Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6: (292 commits)
  [GFS2] Fix endian bug for de_type
  [GFS2] Initialize SELinux extended attributes at inode creation time.
  [GFS2] Move logging code into log.c (mostly)
  [GFS2] Mark nlink cleared so VFS sees it happen
  [GFS2] Two redundant casts removed
  [GFS2] Remove uneeded endian conversion
  [GFS2] Remove duplicate sb reading code
  [GFS2] Mark metadata reads for blktrace
  [GFS2] Remove iflags.h, use FS_
  [GFS2] Fix code style/indent in ops_file.c
  [GFS2] streamline-generic_file_-interfaces-and-filemap gfs fix
  [GFS2] Remove readv/writev methods and use aio_read/aio_write instead (gfs bits)
  [GFS2] inode-diet: Eliminate i_blksize from the inode structure
  [GFS2] inode_diet: Replace inode.u.generic_ip with inode.i_private (gfs)
  [GFS2] Fix typo in last patch
  [GFS2] Fix direct i/o logic in filemap.c
  [GFS2] Fix bug in Makefiles for lock modules
  [GFS2] Remove (extra) fs_subsys declaration
  [GFS2/DLM] Fix trailing whitespace
  [GFS2] Tidy up meta_io code
  ...
diff --git a/CREDITS b/CREDITS
index 2aa8f6d..5329ead 100644
--- a/CREDITS
+++ b/CREDITS
@@ -34,6 +34,7 @@
 D: Basic Interphase 5575 driver with UBR and ABR support.
 S: 75 Donald St, Apt 42
 S: Weymouth, MA 02188
+S: USA
 
 N: Dave Airlie
 E: airlied@linux.ie
@@ -202,6 +203,7 @@
 S: Hewlett-Packard
 S: 3404 E Harmony Rd
 S: Fort Collins, CO 80525
+S: USA
 
 N: Arindam Banerji
 E: axb@cse.nd.edu
@@ -444,6 +446,7 @@
 D: Linux/PA-RISC hacker
 S: 1200 Goldenrod Dr.
 S: Nampa, Idaho 83686
+S: USA
 
 N: Derrick J. Brashear
 E: shadow@dementia.org
@@ -633,6 +636,7 @@
 E: elenstev@mesatop.com
 D: Various build fixes and kernel documentation.
 S: Los Alamos, New Mexico
+S: USA
 
 N: Hamish Coleman
 E: hamish@zot.apana.org.au
@@ -951,6 +955,12 @@
 S: S-114 79 Stockholm
 S: Sweden
 
+N: Pekka Enberg
+E: penberg@cs.helsinki.fi
+W: http://www.cs.helsinki.fi/u/penberg/
+D: Various kernel hacks, fixes, and cleanups.
+S: Finland
+
 N: David Engebretsen
 E: engebret@us.ibm.com
 D: Linux port to 64-bit PowerPC architecture
@@ -2003,6 +2013,7 @@
 D: Busmaster driver for HP 10/100 Mbit Network Adapters
 S: University of Stuttgart, Germany and
 S: Ecole Nationale Superieure des Telecommunications, Paris
+S: France
 
 N: Jamie Lokier
 E: jamie@shareable.org
@@ -2172,6 +2183,7 @@
 S: MS 42
 S: 3404 E. Harmony Road
 S: Fort Collins, CO 80528
+S: USA
 
 N: Torben Mathiasen
 E: torben.mathiasen@compaq.com
@@ -2228,6 +2240,12 @@
 S: Freiburg
 S: Germany
 
+N: Paul E. McKenney
+E: paulmck@us.ibm.com
+W: http://www.rdrop.com/users/paulmck/
+D: RCU and variants
+D: rcutorture module
+
 N: Mike McLagan
 E: mike.mclagan@linux.org
 W: http://www.invlogic.com/~mmclagan
@@ -2969,6 +2987,10 @@
 S: 75013 Paris
 S: France
 
+N: Dipankar Sarma
+E: dipankar@in.ibm.com
+D: RCU
+
 N: Hannu Savolainen
 E: hannu@opensound.com
 D: Maintainer of the sound drivers until 2.1.x days.
@@ -3281,6 +3303,12 @@
 S: MacGregor A.C.T 2615
 S: Australia
 
+N: Josh Triplett
+E: josh@freedesktop.org
+P: 1024D/D0FE7AFB B24A 65C9 1D71 2AC2 DE87  CA26 189B 9946 D0FE 7AFB
+D: rcutorture maintainer
+D: lock annotations, finding and fixing lock bugs
+
 N: Winfried Trümper
 E: winni@xpilot.org
 W: http://www.shop.de/~winni/
@@ -3652,7 +3680,7 @@
 S: USA
 
 N: Michal Wronski
-E: Michal.Wronski@motorola.com
+E: michal.wronski@gmail.com
 D: POSIX message queues fs (with K. Benedyczak)
 S: Krakow
 S: Poland
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
index 63392c9..028614c 100644
--- a/Documentation/DMA-mapping.txt
+++ b/Documentation/DMA-mapping.txt
@@ -107,7 +107,7 @@
 
 	int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
 
-The query for consistent allocations is performed via a a call to
+The query for consistent allocations is performed via a call to
 pci_set_consistent_dma_mask():
 
 	int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask);
@@ -117,7 +117,7 @@
 device supports.  It returns zero if your card can perform DMA
 properly on the machine given the address mask you provided.
 
-If it returns non-zero, your device can not perform DMA properly on
+If it returns non-zero, your device cannot perform DMA properly on
 this platform, and attempting to do so will result in undefined
 behavior.  You must either use a different mask, or not use DMA.
 
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 6d4b1ef..2b5ac60 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -158,6 +158,7 @@
 !Emm/filemap.c
 !Emm/memory.c
 !Emm/vmalloc.c
+!Imm/page_alloc.c
 !Emm/mempool.c
 !Emm/page-writeback.c
 !Emm/truncate.c
@@ -325,8 +326,13 @@
 !Ekernel/irq/manage.c
      </sect1>
 
+     <sect1><title>DMA Channels</title>
+!Ekernel/dma.c
+     </sect1>
+
      <sect1><title>Resources Management</title>
 !Ikernel/resource.c
+!Ekernel/resource.c
      </sect1>
 
      <sect1><title>MTRR Handling</title>
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index 065e8dc..07a6355 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -14,7 +14,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2003-2005</year>
+   <year>2003-2006</year>
    <holder>Jeff Garzik</holder>
   </copyright>
 
@@ -1400,7 +1400,7 @@
 	<listitem>
 	<para>
 	When it's known that HBA is in ready state but ATA/ATAPI
-	device in in unknown state, reset only device.
+	device is in unknown state, reset only device.
 	</para>
 	</listitem>
 
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
index 3608472..143e5ff 100644
--- a/Documentation/DocBook/usb.tmpl
+++ b/Documentation/DocBook/usb.tmpl
@@ -314,8 +314,7 @@
 	<emphasis>usbdevfs</emphasis> although it wasn't solving what
 	<emphasis>devfs</emphasis> was.
 	Every USB device will appear in usbfs, regardless of whether or
-	not it has a kernel driver; but only devices with kernel drivers
-	show up in devfs.
+	not it has a kernel driver.
 	</para>
 
 	<sect1>
@@ -741,7 +740,7 @@
 		<title>Synchronous I/O Support</title>
 
 		<para>Synchronous requests involve the kernel blocking
-		until until the user mode request completes, either by
+		until the user mode request completes, either by
 		finishing successfully or by reporting an error.
 		In most cases this is the simplest way to use usbfs,
 		although as noted above it does prevent performing I/O
diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl
index 008a341..07cd34c 100644
--- a/Documentation/DocBook/writing_usb_driver.tmpl
+++ b/Documentation/DocBook/writing_usb_driver.tmpl
@@ -224,13 +224,8 @@
      Conversely, when the device is removed from the USB bus, the disconnect
      function is called with the device pointer. The driver needs to clean any
      private data that has been allocated at this time and to shut down any
-     pending urbs that are in the USB system. The driver also unregisters
-     itself from the devfs subsystem with the call:
+     pending urbs that are in the USB system.
   </para>
-  <programlisting>
-/* remove our devfs node */
-devfs_unregister(skel->devfs);
-  </programlisting>
   <para>
      Now that the device is plugged into the system and the driver is bound to
      the device, any of the functions in the file_operations structure that
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 7756e09..0e3924e 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -364,6 +364,7 @@
        regspacings=<sp1>,<sp2>,... regsizes=<size1>,<size2>,...
        regshifts=<shift1>,<shift2>,...
        slave_addrs=<addr1>,<addr2>,...
+       force_kipmid=<enable1>,<enable2>,...
 
 Each of these except si_trydefaults is a list, the first item for the
 first interface, second item for the second interface, etc.
@@ -409,7 +410,13 @@
 usually 0x20 and the driver defaults to that, but in case it's not, it
 can be specified when the driver starts up.
 
-When compiled into the kernel, the addresses can be specified on the
+The force_ipmid parameter forcefully enables (if set to 1) or disables
+(if set to 0) the kernel IPMI daemon.  Normally this is auto-detected
+by the driver, but systems with broken interrupts might need an enable,
+or users that don't want the daemon (don't need the performance, don't
+want the CPU hit) can disable it.
+
+When compiled into the kernel, the parameters can be specified on the
 kernel command line as:
 
   ipmi_si.type=<type1>,<type2>...
@@ -419,6 +426,7 @@
        ipmi_si.regsizes=<size1>,<size2>,...
        ipmi_si.regshifts=<shift1>,<shift2>,...
        ipmi_si.slave_addrs=<addr1>,<addr2>,...
+       ipmi_si.force_kipmid=<enable1>,<enable2>,...
 
 It works the same as the module parameters of the same names.
 
@@ -460,12 +468,12 @@
 Setting smb_dbg_probe to 1 will enable debugging of the probing and
 detection process for BMCs on the SMBusses.
 
-Discovering the IPMI compilant BMC on the SMBus can cause devices
+Discovering the IPMI compliant BMC on the SMBus can cause devices
 on the I2C bus to fail. The SMBus driver writes a "Get Device ID" IPMI
 message as a block write to the I2C bus and waits for a response.
 This action can be detrimental to some I2C devices. It is highly recommended
 that the known I2c address be given to the SMBus driver in the smb_addr
-parameter. The default adrress range will not be used when a smb_addr
+parameter. The default address range will not be used when a smb_addr
 parameter is provided.
 
 When compiled into the kernel, the addresses can be specified on the
diff --git a/Documentation/MSI-HOWTO.txt b/Documentation/MSI-HOWTO.txt
index 3ec6c72..c70306a 100644
--- a/Documentation/MSI-HOWTO.txt
+++ b/Documentation/MSI-HOWTO.txt
@@ -267,7 +267,7 @@
 	vector reserved to avoid the case where some MSI-X capable
 	drivers may attempt to claim all available vector resources.
 
-z =	The number of MSI-X capable devices pupulated in the system.
+z =	The number of MSI-X capable devices populated in the system.
 	This policy ensures that maximum (x - y) is distributed
 	evenly among MSI-X capable devices.
 
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index 1d50cf0..f4dffad 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -221,3 +221,41 @@
 	disable irq on a given acquisition of that lock will result in
 	deadlock as soon as the RCU callback happens to interrupt that
 	acquisition's critical section.
+
+13.	SRCU (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu())
+	may only be invoked from process context.  Unlike other forms of
+	RCU, it -is- permissible to block in an SRCU read-side critical
+	section (demarked by srcu_read_lock() and srcu_read_unlock()),
+	hence the "SRCU": "sleepable RCU".  Please note that if you
+	don't need to sleep in read-side critical sections, you should
+	be using RCU rather than SRCU, because RCU is almost always
+	faster and easier to use than is SRCU.
+
+	Also unlike other forms of RCU, explicit initialization
+	and cleanup is required via init_srcu_struct() and
+	cleanup_srcu_struct().	These are passed a "struct srcu_struct"
+	that defines the scope of a given SRCU domain.	Once initialized,
+	the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock()
+	and synchronize_srcu().  A given synchronize_srcu() waits only
+	for SRCU read-side critical sections governed by srcu_read_lock()
+	and srcu_read_unlock() calls that have been passd the same
+	srcu_struct.  This property is what makes sleeping read-side
+	critical sections tolerable -- a given subsystem delays only
+	its own updates, not those of other subsystems using SRCU.
+	Therefore, SRCU is less prone to OOM the system than RCU would
+	be if RCU's read-side critical sections were permitted to
+	sleep.
+
+	The ability to sleep in read-side critical sections does not
+	come for free.	First, corresponding srcu_read_lock() and
+	srcu_read_unlock() calls must be passed the same srcu_struct.
+	Second, grace-period-detection overhead is amortized only
+	over those updates sharing a given srcu_struct, rather than
+	being globally amortized as they are for other forms of RCU.
+	Therefore, SRCU should be used in preference to rw_semaphore
+	only in extremely read-intensive situations, or in situations
+	requiring SRCU's read-side deadlock immunity or low read-side
+	realtime latency.
+
+	Note that, rcu_assign_pointer() and rcu_dereference() relate to
+	SRCU just as they do to other forms of RCU.
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt
index 02e27bf..f84407c 100644
--- a/Documentation/RCU/rcu.txt
+++ b/Documentation/RCU/rcu.txt
@@ -45,7 +45,8 @@
 
 	Search for "rcu_read_lock", "rcu_read_unlock", "call_rcu",
 	"rcu_read_lock_bh", "rcu_read_unlock_bh", "call_rcu_bh",
-	"synchronize_rcu", and "synchronize_net".
+	"srcu_read_lock", "srcu_read_unlock", "synchronize_rcu",
+	"synchronize_net", and "synchronize_srcu".
 
 o	What guidelines should I follow when writing code that uses RCU?
 
diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
index a494859..25a3c3f 100644
--- a/Documentation/RCU/torture.txt
+++ b/Documentation/RCU/torture.txt
@@ -28,6 +28,15 @@
 		To properly exercise RCU implementations with preemptible
 		read-side critical sections.
 
+nfakewriters	This is the number of RCU fake writer threads to run.  Fake
+		writer threads repeatedly use the synchronous "wait for
+		current readers" function of the interface selected by
+		torture_type, with a delay between calls to allow for various
+		different numbers of writers running in parallel.
+		nfakewriters defaults to 4, which provides enough parallelism
+		to trigger special cases caused by multiple writers, such as
+		the synchronize_srcu() early return optimization.
+
 stat_interval	The number of seconds between output of torture
 		statistics (via printk()).  Regardless of the interval,
 		statistics are printed when the module is unloaded.
@@ -44,9 +53,12 @@
 		a kernel that disables the scheduling-clock interrupt to
 		idle CPUs.  Boolean parameter, "1" to test, "0" otherwise.
 
-torture_type	The type of RCU to test: "rcu" for the rcu_read_lock()
-		API, "rcu_bh" for the rcu_read_lock_bh() API, and "srcu"
-		for the "srcu_read_lock()" API.
+torture_type	The type of RCU to test: "rcu" for the rcu_read_lock() API,
+		"rcu_sync" for rcu_read_lock() with synchronous reclamation,
+		"rcu_bh" for the rcu_read_lock_bh() API, "rcu_bh_sync" for
+		rcu_read_lock_bh() with synchronous reclamation, "srcu" for
+		the "srcu_read_lock()" API, and "sched" for the use of
+		preempt_disable() together with synchronize_sched().
 
 verbose		Enable debug printk()s.  Default is disabled.
 
@@ -118,6 +130,21 @@
 	as it is only incremented if a torture structure's counter
 	somehow gets incremented farther than it should.
 
+Different implementations of RCU can provide implementation-specific
+additional information.  For example, SRCU provides the following:
+
+	srcu-torture: rtc: f8cf46a8 ver: 355 tfle: 0 rta: 356 rtaf: 0 rtf: 346 rtmbe: 0
+	srcu-torture: Reader Pipe:  559738 939 0 0 0 0 0 0 0 0 0
+	srcu-torture: Reader Batch:  560434 243 0 0 0 0 0 0 0 0
+	srcu-torture: Free-Block Circulation:  355 354 353 352 351 350 349 348 347 346 0
+	srcu-torture: per-CPU(idx=1): 0(0,1) 1(0,1) 2(0,0) 3(0,1)
+
+The first four lines are similar to those for RCU.  The last line shows
+the per-CPU counter state.  The numbers in parentheses are the values
+of the "old" and "current" counters for the corresponding CPU.  The
+"idx" value maps the "old" and "current" values to the underlying array,
+and is useful for debugging.
+
 
 USAGE
 
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 318df44..e0d6d99 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -582,7 +582,7 @@
 and release a global reader-writer lock.  The synchronize_rcu()
 primitive write-acquires this same lock, then immediately releases
 it.  This means that once synchronize_rcu() exits, all RCU read-side
-critical sections that were in progress before synchonize_rcu() was
+critical sections that were in progress before synchronize_rcu() was
 called are guaranteed to have completed -- there is no way that
 synchronize_rcu() would have been able to write-acquire the lock
 otherwise.
@@ -750,7 +750,7 @@
 
 Either way, the differences are quite small.  Read-side locking moves
 to rcu_read_lock() and rcu_read_unlock, update-side locking moves from
-from a reader-writer lock to a simple spinlock, and a synchronize_rcu()
+a reader-writer lock to a simple spinlock, and a synchronize_rcu()
 precedes the kfree().
 
 However, there is one potential catch: the read-side and update-side
@@ -778,6 +778,8 @@
 	rcu_read_unlock
 	rcu_read_lock_bh
 	rcu_read_unlock_bh
+	srcu_read_lock
+	srcu_read_unlock
 
 RCU pointer/list traversal:
 
@@ -804,6 +806,7 @@
 	synchronize_net
 	synchronize_sched
 	synchronize_rcu
+	synchronize_srcu
 	call_rcu
 	call_rcu_bh
 
diff --git a/Documentation/aoe/todo.txt b/Documentation/aoe/todo.txt
index 7fee1e1..c09dfad 100644
--- a/Documentation/aoe/todo.txt
+++ b/Documentation/aoe/todo.txt
@@ -7,7 +7,7 @@
 deadlock under memory pressure.
 
 Because ATA over Ethernet is not fragmented by the kernel's IP code,
-the destructore member of the struct sk_buff is available to the aoe
+the destructor member of the struct sk_buff is available to the aoe
 driver.  By using a mempool for allocating all but the first few
 sk_buffs, and by registering a destructor, we should be able to
 efficiently allocate sk_buffs without introducing any potential for
diff --git a/Documentation/arm/SA1100/serial_UART b/Documentation/arm/SA1100/serial_UART
index aea2e91..a63966f 100644
--- a/Documentation/arm/SA1100/serial_UART
+++ b/Documentation/arm/SA1100/serial_UART
@@ -24,8 +24,8 @@
 >                   7 = /dev/cusa2                Callout device for ttySA2
 >
 
-If you're not using devfs, you must create those inodes in /dev
-on the root filesystem used by your SA1100-based device:
+You must create those inodes in /dev on the root filesystem used
+by your SA1100-based device:
 
 	mknod ttySA0 c 204 5
 	mknod ttySA1 c 204 6
diff --git a/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt b/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt
index 000e3d7..26422f0 100644
--- a/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt
+++ b/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt
@@ -38,7 +38,7 @@
 ---
 
   The NAND and NOR support has been merged from the linux-mtd project.
-  Any prolbems, see http://www.linux-mtd.infradead.org/ for more
+  Any problems, see http://www.linux-mtd.infradead.org/ for more
   information or up-to-date versions of linux-mtd.
 
 
diff --git a/Documentation/arm/Samsung-S3C24XX/GPIO.txt b/Documentation/arm/Samsung-S3C24XX/GPIO.txt
index 0822764..8caea8c 100644
--- a/Documentation/arm/Samsung-S3C24XX/GPIO.txt
+++ b/Documentation/arm/Samsung-S3C24XX/GPIO.txt
@@ -24,7 +24,7 @@
   header include/asm-arm/arch-s3c2410/hardware.h which can be
   included by #include <asm/arch/hardware.h>
 
-  A useful ammount of documentation can be found in the hardware
+  A useful amount of documentation can be found in the hardware
   header on how the GPIO functions (and others) work.
 
   Whilst a number of these functions do make some checks on what
diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
index 3e46d2a..dda7ecd 100644
--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt
+++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt
@@ -80,7 +80,7 @@
 Adding New Machines
 -------------------
 
-  The archicture has been designed to support as many machines as can
+  The architecture has been designed to support as many machines as can
   be configured for it in one kernel build, and any future additions
   should keep this in mind before altering items outside of their own
   machine files.
diff --git a/Documentation/arm/Samsung-S3C24XX/S3C2412.txt b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
index cb82a7f..295d971 100644
--- a/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
+++ b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
@@ -80,7 +80,7 @@
 Watchdog
 --------
 
-  The watchdog harware is the same as the S3C2410, and is supported by
+  The watchdog hardware is the same as the S3C2410, and is supported by
   the s3c2410_wdt driver.
 
 
diff --git a/Documentation/block/as-iosched.txt b/Documentation/block/as-iosched.txt
index 6f47332..e2a66f8 100644
--- a/Documentation/block/as-iosched.txt
+++ b/Documentation/block/as-iosched.txt
@@ -99,8 +99,8 @@
 at a time during a write batch.  It is this characteristic that can make
 the anticipatory scheduler perform anomalously with controllers supporting
 TCQ, or with hardware striped RAID devices. Setting the antic_expire
-queue paramter (see below) to zero disables this behavior, and the anticipatory
-scheduler behaves essentially like the deadline scheduler.
+queue parameter (see below) to zero disables this behavior, and the 
+anticipatory scheduler behaves essentially like the deadline scheduler.
 
 When read anticipation is enabled (antic_expire is not zero), reads
 are dispatched to the disk controller one at a time.
diff --git a/Documentation/block/barrier.txt b/Documentation/block/barrier.txt
index 0397151..a272c3d 100644
--- a/Documentation/block/barrier.txt
+++ b/Documentation/block/barrier.txt
@@ -25,7 +25,7 @@
 i. For devices which have queue depth greater than 1 (TCQ devices) and
 support ordered tags, block layer can just issue the barrier as an
 ordered request and the lower level driver, controller and drive
-itself are responsible for making sure that the ordering contraint is
+itself are responsible for making sure that the ordering constraint is
 met.  Most modern SCSI controllers/drives should support this.
 
 NOTE: SCSI ordered tag isn't currently used due to limitation in the
@@ -42,7 +42,7 @@
 of ii.  Just keeping issue order suffices.  Ancient SCSI
 controllers/drives and IDE drives are in this category.
 
-2. Forced flushing to physcial medium
+2. Forced flushing to physical medium
 
 Again, if you're not gonna do synchronization with disk drives (dang,
 it sounds even more appealing now!), the reason you use I/O barriers
@@ -56,7 +56,7 @@
 i. No write-back cache.  Keeping requests ordered is enough.
 
 ii. Write-back cache but no flush operation.  There's no way to
-gurantee physical-medium commit order.  This kind of devices can't to
+guarantee physical-medium commit order.  This kind of devices can't to
 I/O barriers.
 
 iii. Write-back cache and flush operation but no FUA (forced unit
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index f989a9e..34bf8f6 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -135,7 +135,7 @@
 		Sets two variables that limit the size of the request.
 
 		- The request queue's max_sectors, which is a soft size in
-		in units of 512 byte sectors, and could be dynamically varied
+		units of 512 byte sectors, and could be dynamically varied
 		by the core kernel.
 
 		- The request queue's max_hw_sectors, which is a hard limit
@@ -783,7 +783,7 @@
 
 	blk_queue_invalidate_tags(request_queue_t *q)
 
-	Clear the internal block tag queue and readd all the pending requests
+	Clear the internal block tag queue and re-add all the pending requests
 	to the request queue. The driver will receive them again on the
 	next request_fn run, just like it did the first time it encountered
 	them.
@@ -890,7 +890,7 @@
 
   Kvec i/o:
 
-  Ben LaHaise's aio code uses a slighly different structure instead
+  Ben LaHaise's aio code uses a slightly different structure instead
   of kiobufs, called a kvec_cb. This contains an array of <page, offset, len>
   tuples (very much like the networking code), together with a callback function
   and data pointer. This is embedded into a brw_cb structure when passed
@@ -988,7 +988,7 @@
 				for a queue.
 
 4.2 Request flows seen by I/O schedulers
-All requests seens by I/O schedulers strictly follow one of the following three
+All requests seen by I/O schedulers strictly follow one of the following three
 flows.
 
  set_req_fn ->
@@ -1203,6 +1203,6 @@
 and Linus' comments - Jan 2001)
 9.2 Discussions about kiobuf and bh design on lkml between sct, linus, alan
 et al - Feb-March 2001 (many of the initial thoughts that led to bio were
-brought up in this discusion thread)
+brought up in this discussion thread)
 9.3 Discussions on mempool on lkml - Dec 2001.
 
diff --git a/Documentation/block/deadline-iosched.txt b/Documentation/block/deadline-iosched.txt
index c918b3a..be08ffd 100644
--- a/Documentation/block/deadline-iosched.txt
+++ b/Documentation/block/deadline-iosched.txt
@@ -23,11 +23,11 @@
 read_expire	(in ms)
 -----------
 
-The goal of the deadline io scheduler is to attempt to guarentee a start
+The goal of the deadline io scheduler is to attempt to guarantee a start
 service time for a request. As we focus mainly on read latencies, this is
 tunable. When a read request first enters the io scheduler, it is assigned
 a deadline that is the current time + the read_expire value in units of
-miliseconds.
+milliseconds.
 
 
 write_expire	(in ms)
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
index 9c629ff..f74affe 100644
--- a/Documentation/cciss.txt
+++ b/Documentation/cciss.txt
@@ -80,7 +80,7 @@
 the SCSI core may not yet be initialized (because the driver is a block 
 driver) and attempting to register it with the SCSI core in such a case 
 would cause a hang.  This is best done via an initialization script 
-(typically in /etc/init.d, but could vary depending on distibution). 
+(typically in /etc/init.d, but could vary depending on distribution). 
 For example:
 
 	for x in /proc/driver/cciss/cciss[0-9]*
@@ -152,7 +152,7 @@
 implements the first two of these actions, aborting the command, and
 resetting the device.  Additionally, most tape drives will not oblige 
 in aborting commands, and sometimes it appears they will not even 
-obey a reset coommand, though in most circumstances they will.  In
+obey a reset command, though in most circumstances they will.  In
 the case that the command cannot be aborted and the device cannot be 
 reset, the device will be set offline.
 
diff --git a/Documentation/computone.txt b/Documentation/computone.txt
index b1cf59b..5e2a0c7 100644
--- a/Documentation/computone.txt
+++ b/Documentation/computone.txt
@@ -199,30 +199,6 @@
 Linux tty naming conventions: ttyF0 - ttyF255 for normal devices, and
 cuf0 - cuf255 for callout devices.
 
-If you are using devfs, existing devices are automatically created within
-the devfs name space.  Normal devices will be tts/F0 - tts/F255 and callout
-devices will be cua/F0 - cua/F255.  With devfs installed, ip2mkdev will
-create symbolic links in /dev from the old conventional names to the newer
-devfs names as follows:
-
-	/dev/ip2ipl[n]	-> /dev/ip2/ipl[n]	n = 0 - 3
-	/dev/ip2stat[n]	-> /dev/ip2/stat[n]	n = 0 - 3
-	/dev/ttyF[n]	-> /dev/tts/F[n]	n = 0 - 255
-	/dev/cuf[n]	-> /dev/cua/F[n]	n = 0 - 255
-
-Only devices for existing ports and boards will be created.
-
-IMPORTANT NOTE:  The naming convention used for devfs by this driver
-was changed from 1.2.12 to 1.2.13.  The old naming convention was to
-use ttf/%d for the tty device and cuf/%d for the cua device.  That
-has been changed to conform to an agreed-upon standard of placing
-all the tty devices under tts.  The device names are now tts/F%d for
-the tty device and cua/F%d for the cua devices.  If you were using
-the older devfs names, you must update for the newer convention.
-
-You do not need to run ip2mkdev if you are using devfs and only want to
-use the devfs native device names.
-
 
 4. USING THE DRIVERS
 
@@ -256,57 +232,15 @@
 use the ip2mkdev script, you must have procfs enabled and the proc file
 system mounted on /proc.
 
-You do not need to run ip2mkdev if you are using devfs and only want to
-use the devfs native device names.
 
-
-6. DEVFS
-
-DEVFS is the DEVice File System available as an add on package for the
-2.2.x kernels and available as a configuration option in 2.3.46 and higher.
-Devfs allows for the automatic creation and management of device names
-under control of the device drivers themselves.  The Devfs namespace is
-hierarchical and reduces the clutter present in the normal flat /dev
-namespace.  Devfs names and conventional device names may be intermixed.
-A userspace daemon, devfsd, exists to allow for automatic creation and
-management of symbolic links from the devfs name space to the conventional
-names.  More details on devfs can be found on the DEVFS home site at
-<http://www.atnf.csiro.au/~rgooch/linux/> or in the file kernel
-documentation files, .../linux/Documentation/filesystems/devfs/README.
-
-If you are using devfs, existing devices are automatically created within
-the devfs name space.  Normal devices will be tts/F0 - tts/F255 and callout
-devices will be cua/F0 - cua/F255.  With devfs installed, ip2mkdev will
-create symbolic links in /dev from the old conventional names to the newer
-devfs names as follows:
-
-	/dev/ip2ipl[n]	-> /dev/ip2/ipl[n]	n = 0 - 3
-	/dev/ip2stat[n]	-> /dev/ip2/stat[n]	n = 0 - 3
-	/dev/ttyF[n]	-> /dev/tts/F[n]	n = 0 - 255
-	/dev/cuf[n]	-> /dev/cua/F[n]	n = 0 - 255
-
-Only devices for existing ports and boards will be created.
-
-IMPORTANT NOTE:  The naming convention used for devfs by this driver
-was changed from 1.2.12 to 1.2.13.  The old naming convention was to
-use ttf/%d for the tty device and cuf/%d for the cua device.  That
-has been changed to conform to an agreed-upon standard of placing
-all the tty devices under tts.  The device names are now tts/F%d for
-the tty device and cua/F%d for the cua devices.  If you were using
-the older devfs names, you must update for the newer convention.
-
-You do not need to run ip2mkdev if you are using devfs and only want to
-use the devfs native device names.
- 
-
-7. NOTES
+6. NOTES
 
 This is a release version of the driver, but it is impossible to test it
 in all configurations of Linux. If there is any anomalous behaviour that 
 does not match the standard serial port's behaviour please let us know.
 
 
-8. ip2mkdev shell script
+7. ip2mkdev shell script
 
 Previously, this script was simply attached here.  It is now attached as a
 shar archive to make it easier to extract the script from the documentation.
diff --git a/Documentation/cpu-freq/cpufreq-stats.txt b/Documentation/cpu-freq/cpufreq-stats.txt
index 6a82948..53d62c1 100644
--- a/Documentation/cpu-freq/cpufreq-stats.txt
+++ b/Documentation/cpu-freq/cpufreq-stats.txt
@@ -1,5 +1,5 @@
 
-     CPU frequency and voltage scaling statictics in the Linux(TM) kernel
+     CPU frequency and voltage scaling statistics in the Linux(TM) kernel
 
 
              L i n u x    c p u f r e q - s t a t s   d r i v e r
@@ -18,8 +18,8 @@
 1. Introduction
 
 cpufreq-stats is a driver that provices CPU frequency statistics for each CPU.
-This statistics is provided in /sysfs as a bunch of read_only interfaces. This
-interface (when configured) will appear in a seperate directory under cpufreq
+These statistics are provided in /sysfs as a bunch of read_only interfaces. This
+interface (when configured) will appear in a separate directory under cpufreq
 in /sysfs (<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/) for each CPU.
 Various statistics will form read_only files under this directory.
 
@@ -53,7 +53,7 @@
 This gives the amount of time spent in each of the frequencies supported by
 this CPU. The cat output will have "<frequency> <time>" pair in each line, which
 will mean this CPU spent <time> usertime units of time at <frequency>. Output
-will have one line for each of the supported freuencies. usertime units here 
+will have one line for each of the supported frequencies. usertime units here 
 is 10mS (similar to other time exported in /proc).
 
 --------------------------------------------------------------------------------
@@ -115,7 +115,7 @@
 
 "CPU frequency translation statistics details" (CONFIG_CPU_FREQ_STAT_DETAILS)
 provides fine grained cpufreq stats by trans_table. The reason for having a
-seperate config option for trans_table is:
+separate config option for trans_table is:
 - trans_table goes against the traditional /sysfs rule of one value per
   interface. It provides a whole bunch of value in a 2 dimensional matrix
   form.
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index f4b8dc4..6a9c55b 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -57,7 +57,7 @@
 
 Basically, it's the following flow graph:
 
-CPU can be set to switch independetly	 |	   CPU can only be set
+CPU can be set to switch independently	 |	   CPU can only be set
       within specific "limits"		 |       to specific frequencies
 
                                  "CPUfreq policy"
@@ -109,7 +109,7 @@
 2.4 Ondemand
 ------------
 
-The CPUfreq govenor "ondemand" sets the CPU depending on the
+The CPUfreq governor "ondemand" sets the CPU depending on the
 current usage. To do this the CPU must have the capability to
 switch the frequency very quickly.  There are a number of sysfs file
 accessible parameters:
@@ -137,11 +137,11 @@
 If set to '1' then the frequency decreases as quickly as it increases,
 if set to '2' it decreases at half the rate of the increase.
 
-ignore_nice_load: this parameter takes a value of '0' or '1', when set
-to '0' (its default) then all processes are counted towards towards the
-'cpu utilisation' value.   When set to '1' then processes that are
+ignore_nice_load: this parameter takes a value of '0' or '1'. When
+set to '0' (its default), all processes are counted towards the
+'cpu utilisation' value.  When set to '1', the processes that are
 run with a 'nice' value will not count (and thus be ignored) in the
-overal usage calculation.  This is useful if you are running a CPU
+overall usage calculation.  This is useful if you are running a CPU
 intensive calculation on your laptop that you do not care how long it
 takes to complete as you can 'nice' it and prevent it from taking part
 in the deciding process of whether to increase your CPU frequency.
diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt
index 2b28e9e..b61cb95 100644
--- a/Documentation/cputopology.txt
+++ b/Documentation/cputopology.txt
@@ -26,7 +26,7 @@
 The type of siblings is cpumask_t.
 
 To be consistent on all architectures, the 4 attributes should have
-deafult values if their values are unavailable. Below is the rule.
+default values if their values are unavailable. Below is the rule.
 1) physical_package_id: If cpu has no physical package id, -1 is the
 default value.
 2) core_id: If cpu doesn't support multi-core, its core id is 0.
diff --git a/Documentation/dell_rbu.txt b/Documentation/dell_rbu.txt
index 941343a..2c0d631 100644
--- a/Documentation/dell_rbu.txt
+++ b/Documentation/dell_rbu.txt
@@ -4,7 +4,7 @@
 
 Scope:
 This document discusses the functionality of the rbu driver only.
-It does not cover the support needed from aplications to enable the BIOS to
+It does not cover the support needed from applications to enable the BIOS to
 update itself with the image downloaded in to the memory.
 
 Overview:
@@ -16,8 +16,8 @@
 Libsmbios can also be used to update BIOS on Dell systems go to
 http://linux.dell.com/libsmbios/ for details.
 
-Dell_RBU driver supports BIOS update using the monilothic image and packetized
-image methods. In case of moniolithic the driver allocates a contiguous chunk
+Dell_RBU driver supports BIOS update using the monolithic image and packetized
+image methods. In case of monolithic the driver allocates a contiguous chunk
 of physical pages having the BIOS image. In case of packetized the app
 using the driver breaks the image in to packets of fixed sizes and the driver
 would place each packet in contiguous physical memory. The driver also
@@ -41,7 +41,7 @@
 These update mechanism depends upon the BIOS currently running on the system.
 Most of the Dell systems support a monolithic update where the BIOS image is
 copied to a single contiguous block of physical memory.
-In case of packet mechanism the single memory can be broken in smaller chuks
+In case of packet mechanism the single memory can be broken in smaller chunks
 of contiguous memory and the BIOS image is scattered in these packets.
 
 By default the driver uses monolithic memory for the update type. This can be
@@ -52,11 +52,11 @@
 In packet update mode the packet size has to be given before any packets can
 be downloaded. It is done as below
 echo XXXX > /sys/devices/platform/dell_rbu/packet_size
-In the packet update mechanism, the user neesd to create a new file having
+In the packet update mechanism, the user needs to create a new file having
 packets of data arranged back to back. It can be done as follows
 The user creates packets header, gets the chunk of the BIOS image and
-placs it next to the packetheader; now, the packetheader + BIOS image chunk
-added to geather should match the specified packet_size. This makes one
+places it next to the packetheader; now, the packetheader + BIOS image chunk
+added together should match the specified packet_size. This makes one
 packet, the user needs to create more such packets out of the entire BIOS
 image file and then arrange all these packets back to back in to one single
 file.
@@ -93,8 +93,8 @@
 NOTE:
 This driver requires a patch for firmware_class.c which has the modified
 request_firmware_nowait function.
-Also after updating the BIOS image an user mdoe application neeeds to execute
-code which message the BIOS update request to the BIOS. So on the next reboot
-the BIOS knows about the new image downloaded and it updates it self.
-Also don't unload the rbu drive if the image has to be updated.
+Also after updating the BIOS image a user mode application needs to execute
+code which sends the BIOS update request to the BIOS. So on the next reboot
+the BIOS knows about the new image downloaded and it updates itself.
+Also don't unload the rbu driver if the image has to be updated.
 
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index addc67b..28c4f79 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -2005,7 +2005,7 @@
 116 char	Advanced Linux Sound Driver (ALSA)
 
 116 block       MicroMemory battery backed RAM adapter (NVRAM)
-                Supports 16 boards, 15 paritions each.
+                Supports 16 boards, 15 partitions each.
                 Requested by neilb at cse.unsw.edu.au.
 
 		 0 = /dev/umem/d0      Whole of first board
@@ -3094,7 +3094,7 @@
 		This major is reserved to assist the expansion to a
 		larger number space.  No device nodes with this major
 		should ever be created on the filesystem.
-		(This is probaly not true anymore, but I'll leave it
+		(This is probably not true anymore, but I'll leave it
 		for now /Torben)
 
 ---LARGE MAJORS!!!!!---
@@ -3205,7 +3205,7 @@
 pseudoterminals (PTYs).
 
 All terminal devices share a common set of capabilities known as line
-diciplines; these include the common terminal line dicipline as well
+disciplines; these include the common terminal line discipline as well
 as SLIP and PPP modes.
 
 All terminal devices are named similarly; this section explains the
@@ -3285,7 +3285,7 @@
 	Pseudoterminals (PTYs)
 
 Pseudoterminals, or PTYs, are used to create login sessions or provide
-other capabilities requiring a TTY line dicipline (including SLIP or
+other capabilities requiring a TTY line discipline (including SLIP or
 PPP capability) to arbitrary data-generation processes.	 Each PTY has
 a master side, named /dev/pty[p-za-e][0-9a-f], and a slave side, named
 /dev/tty[p-za-e][0-9a-f].  The kernel arbitrates the use of PTYs by
diff --git a/Documentation/driver-model/class.txt b/Documentation/driver-model/class.txt
index 2d1d893..548505f 100644
--- a/Documentation/driver-model/class.txt
+++ b/Documentation/driver-model/class.txt
@@ -12,7 +12,7 @@
 
 Each device class defines a set of semantics and a programming interface
 that devices of that class adhere to. Device drivers are the
-implemention of that programming interface for a particular device on
+implementation of that programming interface for a particular device on
 a particular bus. 
 
 Device classes are agnostic with respect to what bus a device resides
diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
index 59806c9..8213216 100644
--- a/Documentation/driver-model/driver.txt
+++ b/Documentation/driver-model/driver.txt
@@ -178,7 +178,7 @@
 
 A driver's probe() may return a negative errno value to indicate that
 the driver did not bind to this device, in which case it should have
-released all reasources it allocated.
+released all resources it allocated.
 
 	int 	(*remove)	(struct device * dev);
 
diff --git a/Documentation/driver-model/overview.txt b/Documentation/driver-model/overview.txt
index 2050c9f..07236ed 100644
--- a/Documentation/driver-model/overview.txt
+++ b/Documentation/driver-model/overview.txt
@@ -57,7 +57,7 @@
 
 The PCI bus layer freely accesses the fields of struct device. It knows about
 the structure of struct pci_dev, and it should know the structure of struct
-device. Individual PCI device drivers that have been converted the the current
+device. Individual PCI device drivers that have been converted to the current
 driver model generally do not and should not touch the fields of struct device,
 unless there is a strong compelling reason to do so.
 
diff --git a/Documentation/dvb/avermedia.txt b/Documentation/dvb/avermedia.txt
index 8bab846..e44c009 100644
--- a/Documentation/dvb/avermedia.txt
+++ b/Documentation/dvb/avermedia.txt
@@ -45,9 +45,9 @@
    by  circuitry on the card and is often presented uncompressed.
    For  a PAL TV signal encoded at a resolution of 768x576 24-bit
    color pixels over 25 frames per second - a fair amount of data
-   is  generated and must be proceesed by the PC before it can be
+   is  generated and must be processed by the PC before it can be
    displayed  on the video monitor screen. Some Analogue TV cards
-   for  PC's  have  onboard  MPEG2  encoders which permit the raw
+   for  PCs  have  onboard  MPEG2  encoders  which permit the raw
    digital  data  stream  to be presented to the PC in an encoded
    and  compressed  form  -  similar  to the form that is used in
    Digital TV.
diff --git a/Documentation/dvb/cards.txt b/Documentation/dvb/cards.txt
index 9e10092..ca58e33 100644
--- a/Documentation/dvb/cards.txt
+++ b/Documentation/dvb/cards.txt
@@ -5,7 +5,7 @@
   frontends (i.e. tuner / demodulator units) used, usually without
   changing the product name, revision number or specs. Some cards
   are also available in versions with different frontends for
-  DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed seperately.
+  DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed separately.
 
   Note 1: There is no guarantee that every frontend driver works
   out of the box with every card, because of different wiring.
diff --git a/Documentation/dvb/ci.txt b/Documentation/dvb/ci.txt
index 95f0e73..531239b 100644
--- a/Documentation/dvb/ci.txt
+++ b/Documentation/dvb/ci.txt
@@ -32,7 +32,7 @@
 	  descrambler to function,
 	  eg: $ ca_zap channels.conf "TMC"
 
-	(d) Hopeflly Enjoy your favourite subscribed channel as you do with
+	(d) Hopefully enjoy your favourite subscribed channel as you do with
 	  a FTA card.
 
 (3) Currently ca_zap, and dst_test, both are meant for demonstration
@@ -65,7 +65,7 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 With the High Level CI approach any new card with almost any random
 architecture can be implemented with this style, the definitions
-insidethe switch statement can be easily adapted for any card, thereby
+inside the switch statement can be easily adapted for any card, thereby
 eliminating the need for any additional ioctls.
 
 The disadvantage is that the driver/hardware has to manage the rest. For
diff --git a/Documentation/dvb/faq.txt b/Documentation/dvb/faq.txt
index a42132d..dbcedf5 100644
--- a/Documentation/dvb/faq.txt
+++ b/Documentation/dvb/faq.txt
@@ -5,7 +5,7 @@
 	It's not a bug, it's a feature. Because the frontends have
 	significant power requirements (and hence get very hot), they
 	are powered down if they are unused (i.e. if the frontend device
-	is closed). The dvb-core.o module paramter "dvb_shutdown_timeout"
+	is closed). The dvb-core.o module parameter "dvb_shutdown_timeout"
 	allow you to change the timeout (default 5 seconds). Setting the
 	timeout to 0 disables the timeout feature.
 
@@ -138,7 +138,7 @@
 
 	- v4l2-common: common functions for Video4Linux-2 drivers
 
-	- v4l1-compat: backward compatiblity layer for Video4Linux-1 legacy
+	- v4l1-compat: backward compatibility layer for Video4Linux-1 legacy
 	  applications
 
 	- dvb-core: DVB core module. This provides you with the
@@ -153,7 +153,7 @@
 	- video-buf: capture helper module for the saa7146_vv driver. This
 	  one is responsible to handle capture buffers.
 
-	- dvb-ttpci: The main driver for AV7110 based, full-featued
+	- dvb-ttpci: The main driver for AV7110 based, full-featured
 	  DVB-S/C/T cards
 
 eof
diff --git a/Documentation/ecryptfs.txt b/Documentation/ecryptfs.txt
new file mode 100644
index 0000000..01d8a08
--- /dev/null
+++ b/Documentation/ecryptfs.txt
@@ -0,0 +1,77 @@
+eCryptfs: A stacked cryptographic filesystem for Linux
+
+eCryptfs is free software. Please see the file COPYING for details.
+For documentation, please see the files in the doc/ subdirectory.  For
+building and installation instructions please see the INSTALL file.
+
+Maintainer: Phillip Hellewell
+Lead developer: Michael A. Halcrow <mhalcrow@us.ibm.com>
+Developers: Michael C. Thompson
+            Kent Yoder
+Web Site: http://ecryptfs.sf.net
+
+This software is currently undergoing development. Make sure to
+maintain a backup copy of any data you write into eCryptfs.
+
+eCryptfs requires the userspace tools downloadable from the
+SourceForge site:
+
+http://sourceforge.net/projects/ecryptfs/
+
+Userspace requirements include:
+ - David Howells' userspace keyring headers and libraries (version
+   1.0 or higher), obtainable from
+   http://people.redhat.com/~dhowells/keyutils/
+ - Libgcrypt
+
+
+NOTES
+
+In the beta/experimental releases of eCryptfs, when you upgrade
+eCryptfs, you should copy the files to an unencrypted location and
+then copy the files back into the new eCryptfs mount to migrate the
+files.
+
+
+MOUNT-WIDE PASSPHRASE
+
+Create a new directory into which eCryptfs will write its encrypted
+files (i.e., /root/crypt).  Then, create the mount point directory
+(i.e., /mnt/crypt).  Now it's time to mount eCryptfs:
+
+mount -t ecryptfs /root/crypt /mnt/crypt
+
+You should be prompted for a passphrase and a salt (the salt may be
+blank).
+
+Try writing a new file:
+
+echo "Hello, World" > /mnt/crypt/hello.txt
+
+The operation will complete.  Notice that there is a new file in
+/root/crypt that is at least 12288 bytes in size (depending on your
+host page size).  This is the encrypted underlying file for what you
+just wrote.  To test reading, from start to finish, you need to clear
+the user session keyring:
+
+keyctl clear @u
+
+Then umount /mnt/crypt and mount again per the instructions given
+above.
+
+cat /mnt/crypt/hello.txt
+
+
+NOTES
+
+eCryptfs version 0.1 should only be mounted on (1) empty directories
+or (2) directories containing files only created by eCryptfs. If you
+mount a directory that has pre-existing files not created by eCryptfs,
+then behavior is undefined. Do not run eCryptfs in higher verbosity
+levels unless you are doing so for the sole purpose of debugging or
+development, since secret values will be written out to the system log
+in that case.
+
+
+Mike Halcrow
+mhalcrow@us.ibm.com
diff --git a/Documentation/eisa.txt b/Documentation/eisa.txt
index 8c8388d..6a099ed 100644
--- a/Documentation/eisa.txt
+++ b/Documentation/eisa.txt
@@ -18,7 +18,7 @@
 
     - The bus code implements most of the generic code. It is shared
     among all the architectures that the EISA code runs on. It
-    implements bus probing (detecting EISA cards avaible on the bus),
+    implements bus probing (detecting EISA cards available on the bus),
     allocates I/O resources, allows fancy naming through sysfs, and
     offers interfaces for driver to register.
 
@@ -84,7 +84,7 @@
 
 id_table	: an array of NULL terminated EISA id strings,
 		  followed by an empty string. Each string can
-		  optionnaly be paired with a driver-dependant value
+		  optionally be paired with a driver-dependant value
 		  (driver_data).
 
 driver		: a generic driver, such as described in
diff --git a/Documentation/exception.txt b/Documentation/exception.txt
index 3cb39ad..2d5aded 100644
--- a/Documentation/exception.txt
+++ b/Documentation/exception.txt
@@ -10,7 +10,7 @@
 function (which has since been replaced by access_ok()).
 
 This function verified that the memory area starting at address 
-addr and of size size was accessible for the operation specified 
+'addr' and of size 'size' was accessible for the operation specified
 in type (read or write). To do this, verify_read had to look up the 
 virtual memory area (vma) that contained the address addr. In the 
 normal case (correctly working program), this test was successful. 
diff --git a/Documentation/fb/fbcon.txt b/Documentation/fb/fbcon.txt
index f373df1..99ea58e 100644
--- a/Documentation/fb/fbcon.txt
+++ b/Documentation/fb/fbcon.txt
@@ -163,7 +163,7 @@
 unloaded if it is still bound to the console layer. (See
 Documentation/console/console.txt for more information).
 
-This is more complicated in the case of the the framebuffer console (fbcon),
+This is more complicated in the case of the framebuffer console (fbcon),
 because fbcon is an intermediate layer between the console and the drivers:
 
 console ---> fbcon ---> fbdev drivers ---> hardware
diff --git a/Documentation/fb/intel810.txt b/Documentation/fb/intel810.txt
index 4f0d6bc..be3e783 100644
--- a/Documentation/fb/intel810.txt
+++ b/Documentation/fb/intel810.txt
@@ -9,8 +9,9 @@
 ================================================================
 
 A. Introduction
+
 	This is a framebuffer driver for various Intel 810/815 compatible
-graphics devices.  These would include:
+	graphics devices.  These include:
 
 	Intel 810
 	Intel 810E
@@ -21,136 +22,136 @@
 
 B.  Features
 
-        - Choice of using Discrete Video Timings, VESA Generalized Timing
+	- Choice of using Discrete Video Timings, VESA Generalized Timing
 	  Formula, or a framebuffer specific database to set the video mode
 
-	- Supports a variable range of horizontal and vertical resolution, and
-	  vertical refresh rates if the VESA Generalized Timing Formula is 
+	- Supports a variable range of horizontal and vertical resolution and
+	  vertical refresh rates if the VESA Generalized Timing Formula is
 	  enabled.
 
-        - Supports color depths of 8, 16, 24 and 32 bits per pixel
+	- Supports color depths of 8, 16, 24 and 32 bits per pixel
 
 	- Supports pseudocolor, directcolor, or truecolor visuals
 
-        - Full and optimized hardware acceleration at 8, 16 and 24 bpp
+	- Full and optimized hardware acceleration at 8, 16 and 24 bpp
 
 	- Robust video state save and restore
 
-        - MTRR support 
+	- MTRR support
 
 	- Utilizes user-entered monitor specifications to automatically
 	  calculate required video mode parameters.
 
-	- Can concurrently run with xfree86 running with native i810 drivers 
+	- Can concurrently run with xfree86 running with native i810 drivers
 
 	- Hardware Cursor Support
  
 	- Supports EDID probing either by DDC/I2C or through the BIOS
 
 C.  List of available options
-	
-   a. "video=i810fb"  
+
+   a. "video=i810fb"
 	enables the i810 driver
 
 	Recommendation: required
- 
-   b. "xres:<value>"  
+
+   b. "xres:<value>"
 	select horizontal resolution in pixels. (This parameter will be
 	ignored if 'mode_option' is specified.  See 'o' below).
 
-	Recommendation: user preference 
+	Recommendation: user preference
 	(default = 640)
 
    c. "yres:<value>"
 	select vertical resolution in scanlines. If Discrete Video Timings
 	is enabled, this will be ignored and computed as 3*xres/4.  (This
 	parameter will be ignored if 'mode_option' is specified.  See 'o'
-	below)  
+	below)
 
 	Recommendation: user preference
 	(default = 480)
-		
-   d. "vyres:<value>" 
+
+   d. "vyres:<value>"
 	select virtual vertical resolution in scanlines. If (0) or none
-	is specified, this will be computed against maximum available memory. 
+	is specified, this will be computed against maximum available memory.
 
 	Recommendation: do not set
 	(default = 480)
 
    e. "vram:<value>"
-	select amount of system RAM in MB to allocate for the video memory 
+	select amount of system RAM in MB to allocate for the video memory
 
 	Recommendation: 1 - 4 MB.
 	(default = 4)
 
-   f. "bpp:<value>"   
-	select desired pixel depth 
+   f. "bpp:<value>"
+	select desired pixel depth
 
 	Recommendation: 8
 	(default = 8)
 
-   g. "hsync1/hsync2:<value>" 
-	select the minimum and maximum Horizontal Sync Frequency of the 
-	monitor in KHz.  If a using a fixed frequency monitor, hsync1 must 
+   g. "hsync1/hsync2:<value>"
+	select the minimum and maximum Horizontal Sync Frequency of the
+	monitor in kHz.  If using a fixed frequency monitor, hsync1 must
 	be equal to hsync2. If EDID probing is successful, these will be
 	ignored and values will be taken from the EDID block.
 
 	Recommendation: check monitor manual for correct values
-	default (29/30)
+	(default = 29/30)
 
-   h. "vsync1/vsync2:<value>" 
+   h. "vsync1/vsync2:<value>"
 	select the minimum and maximum Vertical Sync Frequency of the monitor
-	in Hz. You can also use this option to lock your monitor's refresh 
+	in Hz. You can also use this option to lock your monitor's refresh
 	rate. If EDID probing is successful, these will be ignored and values
 	will be taken from the EDID block.
 
 	Recommendation: check monitor manual for correct values
 	(default = 60/60)
 
-	IMPORTANT:  If you need to clamp your timings, try to give some 
-	leeway for computational errors (over/underflows).  Example: if 
+	IMPORTANT:  If you need to clamp your timings, try to give some
+	leeway for computational errors (over/underflows).  Example: if
 	using vsync1/vsync2 = 60/60, make sure hsync1/hsync2 has at least
 	a 1 unit difference, and vice versa.
 
-   i. "voffset:<value>"	
-        select at what offset in MB of the logical memory to allocate the 
+   i. "voffset:<value>"
+	select at what offset in MB of the logical memory to allocate the
 	framebuffer memory.  The intent is to avoid the memory blocks
 	used by standard graphics applications (XFree86).  The default
-        offset (16 MB for a 64MB aperture, 8 MB for a 32MB aperture) will
-        avoid XFree86's usage and allows up to 7MB/15MB of framebuffer
-        memory.  Depending on your usage, adjust the value up or down, 
-	(0 for maximum usage, 31/63 MB for the least amount).  Note, an 
+	offset (16 MB for a 64 MB aperture, 8 MB for a 32 MB aperture) will
+	avoid XFree86's usage and allows up to 7 MB/15 MB of framebuffer
+	memory.  Depending on your usage, adjust the value up or down
+	(0 for maximum usage, 31/63 MB for the least amount).  Note, an
 	arbitrary setting may conflict with XFree86.
 
 	Recommendation: do not set
 	(default = 8 or 16 MB)
-      
-   j. "accel" 
-	enable text acceleration.  This can be enabled/reenabled anytime 
-	by using 'fbset -accel true/false'. 
+
+   j. "accel"
+	enable text acceleration.  This can be enabled/reenabled anytime
+	by using 'fbset -accel true/false'.
 
 	Recommendation: enable
-	(default = not set) 
+	(default = not set)
 
-   k. "mtrr" 
+   k. "mtrr"
 	enable MTRR.  This allows data transfers to the framebuffer memory
 	to occur in bursts which can significantly increase performance.
-	Not very helpful with the i810/i815 because of 'shared memory'. 
+	Not very helpful with the i810/i815 because of 'shared memory'.
 
 	Recommendation: do not set
-	(default = not set) 
+	(default = not set)
 
    l. "extvga"
 	if specified, secondary/external VGA output will always be enabled.
 	Useful if the BIOS turns off the VGA port when no monitor is attached.
-	The external VGA monitor can then be attached without rebooting. 
+	The external VGA monitor can then be attached without rebooting.
 
 	Recommendation: do not set
 	(default = not set)
-	
-   m. "sync" 
+
+   m. "sync"
 	Forces the hardware engine to do a "sync" or wait for the hardware
-	to finish before starting another instruction. This will produce a 
+	to finish before starting another instruction. This will produce a
 	more stable setup, but will be slower.
 
 	Recommendation: do not set
@@ -162,6 +163,7 @@
 
 	Recommendation: do not set
 	(default = not set)
+
    o. <xres>x<yres>[-<bpp>][@<refresh>]
 	The driver will now accept specification of boot mode option.  If this
 	is specified, the options 'xres' and 'yres' will be ignored. See
@@ -183,8 +185,8 @@
         vsync1:50,vsync2:85,accel,mtrr"
 
 This will initialize the framebuffer to 1024x768 at 8bpp.  The framebuffer
-will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate 
-will be computed based on the hsync1/hsync2 and vsync1/vsync2 values.  
+will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate
+will be computed based on the hsync1/hsync2 and vsync1/vsync2 values.
 
 IMPORTANT:
 You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes
@@ -194,10 +196,10 @@
 block.
 
 E.  Module options
-	
-	The module parameters are essentially similar to the kernel 
-parameters. The main difference is that you need to include a Boolean value 
-(1 for TRUE, and 0 for FALSE) for those options which don't need a value. 
+
+The module parameters are essentially similar to the kernel
+parameters. The main difference is that you need to include a Boolean value
+(1 for TRUE, and 0 for FALSE) for those options which don't need a value.
 
 Example, to enable MTRR, include "mtrr=1".
 
@@ -214,62 +216,62 @@
 	options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \
 	vsync2=85 accel=1 mtrr=1
 
-and just do a 
+and just do a
 
 	modprobe i810fb
 
 
 F.  Setup
 
-	a. Do your usual method of configuring the kernel. 
-	
+	a. Do your usual method of configuring the kernel.
+
 	make menuconfig/xconfig/config
 
-	b. Under "Code Maturity Options", enable "Prompt for experimental/
-	   incomplete code/drivers".
+	b. Under "Code maturity level options" enable "Prompt for development
+	   and/or incomplete code/drivers".
 
  	c. Enable agpgart support for the Intel 810/815 on-board graphics.
-	   This is required.  The option is under "Character Devices"
+	   This is required.  The option is under "Character Devices".
 
 	d. Under "Graphics Support", select "Intel 810/815" either statically
 	   or as a module.  Choose "use VESA Generalized Timing Formula" if
-	   you need to maximize the capability of your display.  To be on the 
-	   safe side, you can leave this unselected.  
-  
+	   you need to maximize the capability of your display.  To be on the
+	   safe side, you can leave this unselected.
+
 	e. If you want support for DDC/I2C probing (Plug and Play Displays),
 	   set 'Enable DDC Support' to 'y'. To make this option appear, set
 	   'use VESA Generalized Timing Formula' to 'y'.
 
-        f. If you want a framebuffer console, enable it under "Console 
-	   Drivers"
+        f. If you want a framebuffer console, enable it under "Console
+	   Drivers".
 
-	g. Compile your kernel. 
-	  	
-	h. Load the driver as described in section D and E.
-	
+	g. Compile your kernel.
+
+	h. Load the driver as described in sections D and E.
+
 	i.  Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver
 	    patch to see the chipset in action (or inaction :-).
 
 G.  Acknowledgment:
-	
-	1.  Geert Uytterhoeven - his excellent howto and the virtual
-                                 framebuffer driver code made this possible.
 
-	2.  Jeff Hartmann for his agpgart code.  
+	1.  Geert Uytterhoeven - his excellent howto and the virtual
+	    framebuffer driver code made this possible.
+
+	2.  Jeff Hartmann for his agpgart code.
 
 	3.  The X developers.  Insights were provided just by reading the
 	    XFree86 source code.
 
 	4.  Intel(c).  For this value-oriented chipset driver and for
-            providing documentation.
+	    providing documentation.
 
 	5. Matt Sottek.  His inputs and ideas  helped in making some
-	optimizations possible.
+	   optimizations possible.
 
 H.  Home Page:
 
 	A more complete, and probably updated information is provided at
-http://i810fb.sourceforge.net.
+	http://i810fb.sourceforge.net.
 
 ###########################
 Tony
diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
index aa0d322..da5ee74 100644
--- a/Documentation/fb/intelfb.txt
+++ b/Documentation/fb/intelfb.txt
@@ -88,12 +88,20 @@
 
 In /etc/lilo.conf, add the line:
 
-append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8"
+append="video=intelfb:mode=800x600-32@75,accel,hwcursor,vram=8"
 
 This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The
 framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor
 will be enabled.
 
+Remarks
+-------
+
+If setting this parameter doesn't work (you stay in a 80x25 text-mode),
+you might need to set the "vga=<mode>" parameter too - see vesafb.txt
+in this directory.
+
+
 D.  Module options
 
 	The module parameters are essentially similar to the kernel
diff --git a/Documentation/fb/sisfb.txt b/Documentation/fb/sisfb.txt
index 3b50c51..2e68e50 100644
--- a/Documentation/fb/sisfb.txt
+++ b/Documentation/fb/sisfb.txt
@@ -72,7 +72,7 @@
 supported options including some explanation.
 
 The desired display mode can be specified using the keyword "mode" with
-a parameter in one of the follwing formats:
+a parameter in one of the following formats:
   - XxYxDepth or
   - XxY-Depth or
   - XxY-Depth@Rate or
diff --git a/Documentation/fb/sstfb.txt b/Documentation/fb/sstfb.txt
index 628d7ff..df27f5b 100644
--- a/Documentation/fb/sstfb.txt
+++ b/Documentation/fb/sstfb.txt
@@ -48,12 +48,12 @@
 
 	Module insertion:
 	# insmod sstfb.o
-	  you should see some strange output frome the board: 
+	  you should see some strange output from the board: 
 	  a big blue square, a green and a red small squares and a vertical
-	  white rectangle. why ? the function's name is self explanatory :
+	  white rectangle. why? the function's name is self-explanatory:
 	  "sstfb_test()"...
 	  (if you don't have a second monitor, you'll have to plug your monitor
-	  directely to the 2D videocard to see what you're typing)
+	  directly to the 2D videocard to see what you're typing)
 	# con2fb /dev/fbx /dev/ttyx
 	  bind a tty to the new frame buffer. if you already have a frame
 	  buffer driver, the voodoo fb will likely be /dev/fb1. if not, 
@@ -72,12 +72,12 @@
 
 Kernel/Modules Options
 
-	You can pass some otions to sstfb module, and via the kernel command
-	line when the driver is compiled in :
+	You can pass some options to the sstfb module, and via the kernel 
+	command line when the driver is compiled in:
 	for module : insmod sstfb.o option1=value1 option2=value2 ...
 	in kernel :  video=sstfb:option1,option2:value2,option3 ...
 	
-	sstfb supports the folowing options :
+	sstfb supports the following options :
 
 Module		Kernel		Description
 
@@ -95,11 +95,11 @@
 
 clipping=1	clipping	Enable or disable clipping.
 clipping=0	noclipping	With clipping enabled, all offscreen
-				reads and writes are disgarded.
+				reads and writes are discarded.
 				Default: enable clipping.
 
 gfxclk=x	gfxclk:x	Force graphic clock frequency (in MHz).
-				Be carefull with this option, it may be
+				Be careful with this option, it may be
 				DANGEROUS.
 				Default: auto 
 					50Mhz for Voodoo 1,
@@ -137,23 +137,23 @@
 	- The driver is 16 bpp only, 24/32 won't work.
 	- The driver is not your_favorite_toy-safe. this includes SMP...
           [Actually from inspection it seems to be safe - Alan]
-	- when using XFree86 FBdev (X over fbdev) you may see strange color
+	- When using XFree86 FBdev (X over fbdev) you may see strange color
 	patterns at the border of your windows (the pixels lose the lowest
-	byte -> basicaly the blue component nd some of the green) . I'm unable
+	byte -> basically the blue component and some of the green). I'm unable
 	to reproduce this with XFree86-3.3, but one of the testers has this
-	problem with XFree86-4. apparently recent Xfree86-4.x solve this
+	problem with XFree86-4. Apparently recent Xfree86-4.x solve this
 	problem.
 	- I didn't really test changing the palette, so you may find some weird
 	things when playing with that.
-	- Sometimes the driver will not recognise the DAC , and the
-        initialisation will fail. this is specificaly true for
-	voodoo 2 boards , but it should be solved in recent versions. please
-	contact me .
-	- the 24/32 is not likely to work anytime soon , knowing that the
-	hardware does ... unusual thigs in 24/32 bpp
-	- When used with anther video board, current limitations of linux
-	console subsystem can cause some troubles, specificaly, you should
-	disable software scrollback , as it can oops badly ...
+	- Sometimes the driver will not recognise the DAC, and the
+        initialisation will fail. This is specifically true for
+	voodoo 2 boards, but it should be solved in recent versions. Please
+	contact me.
+	- The 24/32 is not likely to work anytime soon, knowing that the
+	hardware does ... unusual things in 24/32 bpp.
+	- When used with another video board, current limitations of the linux
+	console subsystem can cause some troubles, specifically, you should
+	disable software scrollback, as it can oops badly ...
 
 Todo
 
@@ -161,7 +161,7 @@
 	- Buy more coffee.
 	- test/port to other arch.
 	- try to add panning using tweeks with front and back buffer .
-	- try to implement accel on voodoo2 , this board can actualy do a 
+	- try to implement accel on voodoo2, this board can actually do a 
 	  lot in 2D even if it was sold as a 3D only board ...
 
 ghoz.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 9364f47..24f3c63 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -29,14 +29,6 @@
 
 ---------------------------
 
-What:	drivers that were depending on OBSOLETE_OSS_DRIVER
-        (config options already removed)
-When:	before 2.6.19
-Why:	OSS drivers with ALSA replacements
-Who:	Adrian Bunk <bunk@stusta.de>
-
----------------------------
-
 What:	raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
 When:	November 2006
 Why:	Deprecated in favour of the new ioctl-based rawiso interface, which is
@@ -122,15 +114,6 @@
 
 ---------------------------
 
-What:	START_ARRAY ioctl for md
-When:	July 2006
-Files:	drivers/md/md.c
-Why:	Not reliable by design - can fail when most needed.
-	Alternatives exist
-Who:	NeilBrown <neilb@suse.de>
-
----------------------------
-
 What:   eepro100 network driver
 When:   January 2007
 Why:    replaced by the e100 driver
@@ -193,7 +176,7 @@
 ---------------------------
 
 What:	USB driver API moves to EXPORT_SYMBOL_GPL
-When:	Febuary 2008
+When:	February 2008
 Files:	include/linux/usb.h, drivers/usb/core/driver.c
 Why:	The USB subsystem has changed a lot over time, and it has been
 	possible to create userspace USB drivers using usbfs/libusb/gadgetfs
@@ -220,42 +203,6 @@
 
 ---------------------------
 
-What:	Support for the Momentum / PMC-Sierra Jaguar ATX evaluation board
-When:	September 2006
-Why:	Does no longer build since quite some time, and was never popular,
-	due to the platform being replaced by successor models.  Apparently
-	no user base left.  It also is one of the last users of
-	WANT_PAGE_VIRTUAL.
-Who:	Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
-What:	Support for the Momentum Ocelot, Ocelot 3, Ocelot C and Ocelot G
-When:	September 2006
-Why:	Some do no longer build and apparently there is no user base left
-	for these platforms.
-Who:	Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
-What:	Support for MIPS Technologies' Altas and SEAD evaluation board
-When:	September 2006
-Why:	Some do no longer build and apparently there is no user base left
-	for these platforms.  Hardware out of production since several years.
-Who:	Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
-What:	Support for the IT8172-based platforms, ITE 8172G and Globespan IVR
-When:	September 2006
-Why:	Code does no longer build since at least 2.6.0,  apparently there is
-	no user base left for these platforms.  Hardware out of production
-	since several years and hardly a trace of the manufacturer left on
-	the net.
-Who:	Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
 What:	Interrupt only SA_* flags
 When:	Januar 2007
 Why:	The interrupt related SA_* flags are replaced by IRQF_* to move them
@@ -325,3 +272,11 @@
 Who:	Jean Delvare <khali@linux-fr.org>
 
 ---------------------------
+
+What:	ftape
+When:	2.6.20
+Why:	Orphaned for ages.  SMP bugs long unfixed.  Few users left
+	in the world.
+Who:	Jeff Garzik <jeff@garzik.org>
+
+---------------------------
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index 16dec61..3c384c0 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -26,8 +26,6 @@
 	- info on the cram filesystem for small storage (ROMs etc).
 dentry-locking.txt
 	- info on the RCU-based dcache locking model.
-devfs/
-	- directory containing devfs documentation.
 directory-locking
 	- info about the locking scheme used for directory operations.
 dlmfs.txt
diff --git a/Documentation/filesystems/befs.txt b/Documentation/filesystems/befs.txt
index 877a7b1..67391a1 100644
--- a/Documentation/filesystems/befs.txt
+++ b/Documentation/filesystems/befs.txt
@@ -7,7 +7,7 @@
 Make sure you understand that this is alpha software.  This means that the
 implementation is neither complete nor well-tested. 
 
-I DISCLAIM ALL RESPONSIBILTY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
+I DISCLAIM ALL RESPONSIBILITY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
 
 LICENSE
 =====
@@ -22,7 +22,7 @@
 details.
 
 Original Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
-His orriginal code can still be found at:
+His original code can still be found at:
 <http://hp.vector.co.jp/authors/VA008030/bfs/>
 Does anyone know of a more current email address for Makoto? He doesn't
 respond to the address given above...
@@ -39,7 +39,7 @@
 ================
 Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". 
 But Unixware Boot Filesystem is called bfs, too. And they are already in
-the kernel. Because of this nameing conflict, on Linux the BeOS
+the kernel. Because of this naming conflict, on Linux the BeOS
 filesystem is called befs.
 
 HOW TO INSTALL
@@ -57,7 +57,7 @@
 figure it out yourself (it shouldn't be hard), or mail the maintainer 
 (Will Dyson <will_dyson@pobox.com>) for help.
 
-step 2.  Configuretion & make kernel
+step 2.  Configuration & make kernel
 
 The linux kernel has many compile-time options. Most of them are beyond the
 scope of this document. I suggest the Kernel-HOWTO document as a good general
diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt
index c4ff96b..c3a7afb 100644
--- a/Documentation/filesystems/configfs/configfs.txt
+++ b/Documentation/filesystems/configfs/configfs.txt
@@ -1,5 +1,5 @@
 
-configfs - Userspace-driven kernel object configuation.
+configfs - Userspace-driven kernel object configuration.
 
 Joel Becker <joel.becker@oracle.com>
 
@@ -254,7 +254,7 @@
 
 Finally, when userspace calls rmdir(2) on the item or group,
 ct_group_ops->drop_item() is called.  As a config_group is also a
-config_item, it is not necessary for a seperate drop_group() method.
+config_item, it is not necessary for a separate drop_group() method.
 The subsystem must config_item_put() the reference that was initialized
 upon item allocation.  If a subsystem has no work to do, it may omit
 the ct_group_ops->drop_item() method, and configfs will call
@@ -406,7 +406,7 @@
 
 Far better would be an explicit action notifying the subsystem that the
 config_item is ready to go.  More importantly, an explicit action allows
-the subsystem to provide feedback as to whether the attibutes are
+the subsystem to provide feedback as to whether the attributes are
 initialized in a way that makes sense.  configfs provides this as
 committable items.
 
@@ -422,7 +422,7 @@
 "pending" directory does allow mkdir(2) and rmdir(2).  An item is
 created in the "pending" directory.  Its attributes can be modified at
 will.  Userspace commits the item by renaming it into the "live"
-directory.  At this point, the subsystem recieves the ->commit_item()
+directory.  At this point, the subsystem receives the ->commit_item()
 callback.  If all required attributes are filled to satisfaction, the
 method returns zero and the item is moved to the "live" directory.
 
diff --git a/Documentation/filesystems/directory-locking b/Documentation/filesystems/directory-locking
index 34380d4..d7099a9 100644
--- a/Documentation/filesystems/directory-locking
+++ b/Documentation/filesystems/directory-locking
@@ -82,7 +82,7 @@
 
 	Consider the object blocking the cross-directory rename.  One
 of its descendents is locked by cross-directory rename (otherwise we
-would again have an infinite set of of contended objects).  But that
+would again have an infinite set of contended objects).  But that
 means that cross-directory rename is taking locks out of order.  Due
 to (2) the order hadn't changed since we had acquired filesystem lock.
 But locking rules for cross-directory rename guarantee that we do not
diff --git a/Documentation/filesystems/dlmfs.txt b/Documentation/filesystems/dlmfs.txt
index 9afab84..c50bbb2 100644
--- a/Documentation/filesystems/dlmfs.txt
+++ b/Documentation/filesystems/dlmfs.txt
@@ -68,7 +68,7 @@
 call. Userspace programs are assumed to handle their own local
 locking.
 
-Two levels of locks are supported - Shared Read, and Exlcusive.
+Two levels of locks are supported - Shared Read, and Exclusive.
 Also supported is a Trylock operation.
 
 For information on the libo2dlm interface, please see o2dlm.h,
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
index 3dd2872..4333e83 100644
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -205,7 +205,7 @@
 
 In ext2, there is a mechanism for reserving a certain number of blocks
 for a particular user (normally the super-user).  This is intended to
-allow for the system to continue functioning even if non-priveleged users
+allow for the system to continue functioning even if non-privileged users
 fill up all the space available to them (this is independent of filesystem
 quotas).  It also keeps the filesystem from filling up entirely which
 helps combat fragmentation.
diff --git a/Documentation/filesystems/files.txt b/Documentation/filesystems/files.txt
index 8c206f4..133e213 100644
--- a/Documentation/filesystems/files.txt
+++ b/Documentation/filesystems/files.txt
@@ -55,7 +55,7 @@
 2. Reading of the fdtable as described above must be protected
    by rcu_read_lock()/rcu_read_unlock().
 
-3. For any update to the the fd table, files->file_lock must
+3. For any update to the fd table, files->file_lock must
    be held.
 
 4. To look up the file structure given an fd, a reader
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
index 638cbd3..35f105b 100644
--- a/Documentation/filesystems/ntfs.txt
+++ b/Documentation/filesystems/ntfs.txt
@@ -13,7 +13,7 @@
 - Using NTFS volume and stripe sets
   - The Device-Mapper driver
   - The Software RAID / MD driver
-  - Limitiations when using the MD driver
+  - Limitations when using the MD driver
 - ChangeLog
 
 
@@ -43,7 +43,7 @@
 at http://linux-ntfs.sourceforge.net/
 
 The web site has a lot of additional information, such as a comprehensive
-FAQ, documentation on the NTFS on-disk format, informaiton on the Linux-NTFS
+FAQ, documentation on the NTFS on-disk format, information on the Linux-NTFS
 userspace utilities, etc.
 
 
@@ -383,14 +383,14 @@
 appropriately (see man 5 raidtab).
 
 Linear volume sets, i.e. linear raid, as well as stripe sets, i.e. raid level
-0, have been tested and work fine (though see section "Limitiations when using
+0, have been tested and work fine (though see section "Limitations when using
 the MD driver with NTFS volumes" especially if you want to use linear raid).
 Even though untested, there is no reason why mirrors, i.e. raid level 1, and
 stripes with parity, i.e. raid level 5, should not work, too.
 
 You have to use the "persistent-superblock 0" option for each raid-disk in the
 NTFS volume/stripe you are configuring in /etc/raidtab as the persistent
-superblock used by the MD driver would damange the NTFS volume.
+superblock used by the MD driver would damage the NTFS volume.
 
 Windows by default uses a stripe chunk size of 64k, so you probably want the
 "chunk-size 64k" option for each raid-disk, too.
@@ -435,7 +435,7 @@
 ntfs volume.
 
 
-Limitiations when using the Software RAID / MD driver
+Limitations when using the Software RAID / MD driver
 -----------------------------------------------------
 
 Using the md driver will not work properly if any of your NTFS partitions have
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 7240ee7..3355e69 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -410,7 +410,7 @@
               this memory, making it slower to access than lowmem.
     LowTotal:
      LowFree: Lowmem is memory which can be used for everything that
-              highmem can be used for, but it is also availble for the
+              highmem can be used for, but it is also available for the
               kernel's use for its own data structures.  Among many
               other things, it is where everything from the Slab is
               allocated.  Bad things happen when you're out of lowmem.
@@ -1255,7 +1255,7 @@
 		address space are refused. Used for a typical system. It
 		ensures a seriously wild allocation fails while allowing
 		overcommit to reduce swap usage.  root is allowed to
-		allocate slighly more memory in this mode. This is the
+		allocate slightly more memory in this mode. This is the
 		default.
 
 1	-	Always overcommit. Appropriate for some scientific
@@ -1588,7 +1588,7 @@
 default is  to  use  the  BSD  compatible interpretation of the urgent pointer
 pointing to the first byte after the urgent data. The RFC793 interpretation is
 to have  it  point  to  the last byte of urgent data. Enabling this option may
-lead to interoperatibility problems. Disabled by default.
+lead to interoperability problems. Disabled by default.
 
 tcp_syncookies
 --------------
@@ -1733,7 +1733,7 @@
 
 These  parameters  are used to limit how many ICMP destination unreachable to 
 send  from  the  host  in question. ICMP destination unreachable messages are 
-sent  when  we can not reach the next hop, while trying to transmit a packet. 
+sent  when  we  cannot reach  the next hop while trying to transmit a packet. 
 It  will also print some error messages to kernel logs if someone is ignoring 
 our   ICMP  redirects.  The  higher  the  error_cost  factor  is,  the  fewer 
 destination  unreachable  and error messages will be let through. Error_burst 
@@ -1857,7 +1857,7 @@
 
 Maximum queue length of the delayed proxy arp timer. (see proxy_delay).
 
-app_solcit
+app_solicit
 ----------
 
 Determines the  number of requests to send to the user level ARP daemon. Use 0
diff --git a/Documentation/filesystems/spufs.txt b/Documentation/filesystems/spufs.txt
index 8edc395..982645a 100644
--- a/Documentation/filesystems/spufs.txt
+++ b/Documentation/filesystems/spufs.txt
@@ -84,7 +84,7 @@
    /ibox
        The  second  SPU  to CPU communication mailbox. This file is similar to
        the first mailbox file, but can be read in blocking I/O mode,  and  the
-       poll  familiy of system calls can be used to wait for it.  The possible
+       poll  family of system calls can be used to wait for it.  The  possible
        operations on an open ibox file are:
 
        read(2)
@@ -105,7 +105,7 @@
 
 
    /wbox
-       The CPU to SPU communation mailbox. It is write-only can can be written
+       The CPU to SPU communation mailbox. It is write-only and can be written
        in  units  of  32  bits. If the mailbox is full, write() will block and
        poll can be used to wait for it becoming  empty  again.   The  possible
        operations  on  an open wbox file are: write(2) If a count smaller than
@@ -359,7 +359,7 @@
        EFAULT npc is not a valid pointer or status is neither NULL nor a valid
               pointer.
 
-       EINTR  A signal occured while spu_run was in progress.  The  npc  value
+       EINTR  A signal occurred while spu_run was in progress.  The npc  value
               has  been updated to the new program counter value if necessary.
 
        EINVAL fd is not a file descriptor returned from spu_create(2).
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
index 89b1d19..4b5ca26 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -238,7 +238,7 @@
 The sysfs directory arrangement exposes the relationship of kernel
 data structures. 
 
-The top level sysfs diretory looks like:
+The top level sysfs directory looks like:
 
 block/
 bus/
diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt
index 1773106..6dd0508 100644
--- a/Documentation/filesystems/tmpfs.txt
+++ b/Documentation/filesystems/tmpfs.txt
@@ -39,7 +39,7 @@
 	tmpfs	/dev/shm	tmpfs	defaults	0 0
 
    Remember to create the directory that you intend to mount tmpfs on
-   if necessary (/dev/shm is automagically created if you use devfs).
+   if necessary.
 
    This mount is _not_ needed for SYSV shared memory. The internal
    mount is used for that. (In the 2.3 kernel versions it was
@@ -63,7 +63,7 @@
 nr_blocks: The same as size, but in blocks of PAGE_CACHE_SIZE.
 nr_inodes: The maximum number of inodes for this instance. The default
            is half of the number of your physical RAM pages, or (on a
-           a machine with highmem) the number of lowmem RAM pages,
+           machine with highmem) the number of lowmem RAM pages,
            whichever is the lower.
 
 These parameters accept a suffix k, m or g for kilo, mega and giga and
diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt
index 2001abb..069cb10 100644
--- a/Documentation/filesystems/vfat.txt
+++ b/Documentation/filesystems/vfat.txt
@@ -35,7 +35,7 @@
 		 you should consider the following option instead.
 
 utf8=<bool>   -- UTF-8 is the filesystem safe version of Unicode that
-		 is used by the console.  It can be be enabled for the
+		 is used by the console.  It can be enabled for the
 		 filesystem with this option. If 'uni_xlate' gets set,
 		 UTF-8 gets disabled.
 
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index cd07c21..7737bfd 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -410,7 +410,7 @@
 
   put_link: called by the VFS to release resources allocated by
   	follow_link().  The cookie returned by follow_link() is passed
-  	to to this method as the last parameter.  It is used by
+  	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
diff --git a/Documentation/fujitsu/frv/mmu-layout.txt b/Documentation/fujitsu/frv/mmu-layout.txt
index 11dcc56..db10250 100644
--- a/Documentation/fujitsu/frv/mmu-layout.txt
+++ b/Documentation/fujitsu/frv/mmu-layout.txt
@@ -233,7 +233,7 @@
      (*) __debug_mmu.iamr[]
      (*) __debug_mmu.damr[]
 
-	 These receive the current IAMR and DAMR contents. These can be viewed with with the _amr
+	 These receive the current IAMR and DAMR contents. These can be viewed with the _amr
 	 GDB macro:
 
 		(gdb) _amr
diff --git a/Documentation/highuid.txt b/Documentation/highuid.txt
index 2c33926..76034d9 100644
--- a/Documentation/highuid.txt
+++ b/Documentation/highuid.txt
@@ -57,7 +57,7 @@
 
   Other filesystems have not been checked yet.
 
-- The ncpfs and smpfs filesystems can not presently use 32-bit UIDs in
+- The ncpfs and smpfs filesystems cannot presently use 32-bit UIDs in
   all ioctl()s. Some new ioctl()s have been added with 32-bit UIDs, but
   more are needed. (as well as new user<->kernel data structures)
 
diff --git a/Documentation/hrtimers.txt b/Documentation/hrtimers.txt
index 7620ff7..ce31f65 100644
--- a/Documentation/hrtimers.txt
+++ b/Documentation/hrtimers.txt
@@ -10,7 +10,7 @@
 features into the existing timer framework, and after testing various
 such high-resolution timer implementations in practice, we came to the
 conclusion that the timer wheel code is fundamentally not suitable for
-such an approach. We initially didnt believe this ('there must be a way
+such an approach. We initially didn't believe this ('there must be a way
 to solve this'), and spent a considerable effort trying to integrate
 things into the timer wheel, but we failed. In hindsight, there are
 several reasons why such integration is hard/impossible:
@@ -27,7 +27,7 @@
   high-res timers.
 
 - the unpredictable [O(N)] overhead of cascading leads to delays which
-  necessiate a more complex handling of high resolution timers, which
+  necessitate a more complex handling of high resolution timers, which
   in turn decreases robustness. Such a design still led to rather large
   timing inaccuracies. Cascading is a fundamental property of the timer
   wheel concept, it cannot be 'designed out' without unevitably
@@ -58,7 +58,7 @@
 The primary users of precision timers are user-space applications that
 utilize nanosleep, posix-timers and itimer interfaces. Also, in-kernel
 users like drivers and subsystems which require precise timed events
-(e.g. multimedia) can benefit from the availability of a seperate
+(e.g. multimedia) can benefit from the availability of a separate
 high-resolution timer subsystem as well.
 
 While this subsystem does not offer high-resolution clock sources just
@@ -68,7 +68,7 @@
 with other potential users for precise timers gives another reason to
 separate the "timeout" and "precise timer" subsystems.
 
-Another potential benefit is that such a seperation allows even more
+Another potential benefit is that such a separation allows even more
 special-purpose optimization of the existing timer wheel for the low
 resolution and low precision use cases - once the precision-sensitive
 APIs are separated from the timer wheel and are migrated over to
@@ -96,8 +96,8 @@
 a separate list is used to give the expiry code fast access to the
 queued timers, without having to walk the rbtree.
 
-(This seperate list is also useful for later when we'll introduce
-high-resolution clocks, where we need seperate pending and expired
+(This separate list is also useful for later when we'll introduce
+high-resolution clocks, where we need separate pending and expired
 queues while keeping the time-order intact.)
 
 Time-ordered enqueueing is not purely for the purposes of
diff --git a/Documentation/ia64/efirtc.txt b/Documentation/ia64/efirtc.txt
index ede2c1e..057e6be 100644
--- a/Documentation/ia64/efirtc.txt
+++ b/Documentation/ia64/efirtc.txt
@@ -26,7 +26,7 @@
 Because we wanted to minimize the impact on existing user-level apps using
 the CMOS clock, we decided to expose an API that was very similar to the one
 used today with the legacy RTC driver (driver/char/rtc.c). However, because 
-EFI provides a simpler services, not all all ioctl() are available. Also
+EFI provides a simpler services, not all ioctl() are available. Also
 new ioctl()s have been introduced for things that EFI provides but not the 
 legacy.
 
diff --git a/Documentation/ia64/fsys.txt b/Documentation/ia64/fsys.txt
index 28da181..59dd689 100644
--- a/Documentation/ia64/fsys.txt
+++ b/Documentation/ia64/fsys.txt
@@ -165,7 +165,7 @@
 * Signal handling
 
 The delivery of (asynchronous) signals must be delayed until fsys-mode
-is exited.  This is acomplished with the help of the lower-privilege
+is exited.  This is accomplished with the help of the lower-privilege
 transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user()
 checks whether the interrupted task was in fsys-mode and, if so, sets
 PSR.lp and returns immediately.  When fsys-mode is exited via the
diff --git a/Documentation/ia64/mca.txt b/Documentation/ia64/mca.txt
index a71cc6a..f097c60 100644
--- a/Documentation/ia64/mca.txt
+++ b/Documentation/ia64/mca.txt
@@ -12,7 +12,7 @@
 ---
 
 The complicated ia64 MCA process.  All of this is mandated by Intel's
-specification for ia64 SAL, error recovery and and unwind, it is not as
+specification for ia64 SAL, error recovery and unwind, it is not as
 if we have a choice here.
 
 * MCA occurs on one cpu, usually due to a double bit memory error.
@@ -94,7 +94,7 @@
 
 INIT is less complicated than MCA.  Pressing the nmi button or using
 the equivalent command on the management console sends INIT to all
-cpus.  SAL picks one one of the cpus as the monarch and the rest are
+cpus.  SAL picks one of the cpus as the monarch and the rest are
 slaves.  All the OS INIT handlers are entered at approximately the same
 time.  The OS monarch prints the state of all tasks and returns, after
 which the slaves return and the system resumes.
diff --git a/Documentation/ia64/serial.txt b/Documentation/ia64/serial.txt
index f51eb4b..040b977 100644
--- a/Documentation/ia64/serial.txt
+++ b/Documentation/ia64/serial.txt
@@ -124,6 +124,13 @@
 
 	- Add entry to /etc/securetty for console tty.
 
+    No ACPI serial devices found in 2.6.17 or later:
+
+	- Turn on CONFIG_PNP and CONFIG_PNPACPI.  Prior to 2.6.17, ACPI
+	  serial devices were discovered by 8250_acpi.  In 2.6.17,
+	  8250_acpi was replaced by the combination of 8250_pnp and
+	  CONFIG_PNPACPI.
+
 
 
 [1] http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index 8b3fd82..71aa403 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -450,7 +450,7 @@
 
 No commands can be written to this file.
 
-EXPERIMENTAL: Embedded controller reigster dump -- /proc/acpi/ibm/ecdump
+EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
 ------------------------------------------------------------------------
 
 This feature is marked EXPERIMENTAL because the implementation
diff --git a/Documentation/ide.txt b/Documentation/ide.txt
index 29866fb..0bf38ba 100644
--- a/Documentation/ide.txt
+++ b/Documentation/ide.txt
@@ -281,7 +281,7 @@
 
  "idex=serialize"	: do not overlap operations on idex. Please note
 			  that you will have to specify this option for
-			  both the respecitve primary and secondary channel
+			  both the respective primary and secondary channel
 			  to take effect.
 
  "idex=four"		: four drives on idex and ide(x^1) share same ports
diff --git a/Documentation/input/amijoy.txt b/Documentation/input/amijoy.txt
index 3b8b2d4..4f0e89d 100644
--- a/Documentation/input/amijoy.txt
+++ b/Documentation/input/amijoy.txt
@@ -79,10 +79,10 @@
 JOY1DAT   Y7  Y6  Y5  Y4  Y3  Y2  Y1  Y0     X7  X6  X5  X4  X3  X2  X1  X0
 
         0=LEFT CONTROLLER PAIR, 1=RIGHT CONTROLLER PAIR.
-        (4 counters total).The bit usage for both left and right
+        (4 counters total). The bit usage for both left and right
         addresses is shown below. Each 6 bit counter (Y7-Y2,X7-X2) is
         clocked by 2 of the signals input from the mouse serial
-        stream. Starting with first bit recived:
+        stream. Starting with first bit received:
 
          +-------------------+-----------------------------------------+
          | Serial | Bit Name | Description                             |
diff --git a/Documentation/input/atarikbd.txt b/Documentation/input/atarikbd.txt
index 8fb896c..1e7e585 100644
--- a/Documentation/input/atarikbd.txt
+++ b/Documentation/input/atarikbd.txt
@@ -10,7 +10,7 @@
 The ikbd processor also maintains a time-of-day clock with one second
 resolution.
 The ikbd has been designed to be general enough that it can be used with a
-ariety of new computer products. Product variations in a number of
+variety of new computer products. Product variations in a number of
 keyswitches, mouse resolution, etc. can be accommodated.
 The ikbd communicates with the main processor over a high speed bi-directional
 serial interface. It can function in a variety of modes to facilitate
@@ -30,7 +30,7 @@
 The special codes 0xF6 through 0xFF are reserved for use as follows:
     0xF6            status report
     0xF7            absolute mouse position record
-    0xF8-0xFB       relative mouse position records(lsbs determind by
+    0xF8-0xFB       relative mouse position records (lsbs determined by
                      mouse button states)
     0xFC            time-of-day
     0xFD            joystick report (both sticks)
@@ -84,7 +84,7 @@
 4.2 Absolute Position reporting
 
 The ikbd can also maintain absolute mouse position. Commands exist for
-reseting the mouse position, setting X/Y scaling, and interrogating the
+resetting the mouse position, setting X/Y scaling, and interrogating the
 current mouse position.
 
 4.3 Mouse Cursor Key Mode
@@ -406,7 +406,7 @@
 9.18 SET JOYSTICK MONITORING
 
     0x17
-    rate                ; time between samples in hundreths of a second
+    rate                ; time between samples in hundredths of a second
     Returns: (in packets of two as long as in mode)
             %000000xy   ; where y is JOYSTICK1 Fire button
                         ; and x is JOYSTICK0 Fire button
@@ -522,7 +522,7 @@
             0x20        ; memory access
             { data }    ; 6 data bytes starting at ADR
 
-This comand permits the host to read from the ikbd controller memory.
+This command permits the host to read from the ikbd controller memory.
 
 9.26 CONTROLLER EXECUTE
 
diff --git a/Documentation/input/cs461x.txt b/Documentation/input/cs461x.txt
index 6181747..afe0d65 100644
--- a/Documentation/input/cs461x.txt
+++ b/Documentation/input/cs461x.txt
@@ -27,7 +27,7 @@
 ISA or PnP ISA cards supported. AFAIK the ns558 have support for Crystal 
 ISA and PnP ISA series.
 
-The driver works witn ALSA drivers simultaneously. For exmple, the xracer
+The driver works with ALSA drivers simultaneously. For example, the xracer
 uses joystick as input device and PCM device as sound output in one time.
 There are no sound or input collisions detected. The source code have
 comments about them; but I've found the joystick can be initialized 
diff --git a/Documentation/input/ff.txt b/Documentation/input/ff.txt
index c7e10ea..085eb15 100644
--- a/Documentation/input/ff.txt
+++ b/Documentation/input/ff.txt
@@ -1,78 +1,48 @@
 Force feedback for Linux.
 By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
+Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
 You may redistribute this file. Please remember to include shape.fig and
 interactive.fig as well.
 ----------------------------------------------------------------------------
 
-0. Introduction
+1. Introduction
 ~~~~~~~~~~~~~~~
 This document describes how to use force feedback devices under Linux. The
 goal is not to support these devices as if they were simple input-only devices
 (as it is already the case), but to really enable the rendering of force
 effects.
-At the moment, only I-Force devices are supported, and not officially. That
-means I had to find out how the protocol works on my own. Of course, the
-information I managed to grasp is far from being complete, and I can not
-guarranty that this driver will work for you.
-This document only describes the force feedback part of the driver for I-Force
-devices. Please read joystick.txt before reading further this document.
+This document only describes the force feedback part of the Linux input
+interface. Please read joystick.txt and input.txt before reading further this
+document.
 
 2. Instructions to the user
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Here are instructions on how to compile and use the driver. In fact, this
-driver is the normal iforce, input and evdev drivers written by Vojtech
-Pavlik, plus additions to support force feedback.
+To enable force feedback, you have to:
+
+1. have your kernel configured with evdev and a driver that supports your
+   device.
+2. make sure evdev module is loaded and /dev/input/event* device files are
+   created.
 
 Before you start, let me WARN you that some devices shake violently during the
 initialisation phase. This happens for example with my "AVB Top Shot Pegasus".
 To stop this annoying behaviour, move you joystick to its limits. Anyway, you
-should keep a hand on your device, in order to avoid it to brake down if
+should keep a hand on your device, in order to avoid it to break down if
 something goes wrong.
 
-At the kernel's compilation:
-	- Enable IForce/Serial
-	- Enable Event interface
-
-Compile the modules, install them.
-
-You also need inputattach.
-
-You then need to insert the modules into the following order:
-% modprobe joydev
-% modprobe serport		# Only for serial
-% modprobe iforce
-% modprobe evdev
-% ./inputattach -ifor $2 &	# Only for serial
-If you are using USB, you don't need the inputattach step.
-
-Please check that you have all the /dev/input entries needed:
-cd /dev
-rm js*
-mkdir input
-mknod input/js0 c 13 0
-mknod input/js1 c 13 1
-mknod input/js2 c 13 2
-mknod input/js3 c 13 3
-ln -s input/js0 js0
-ln -s input/js1 js1
-ln -s input/js2 js2
-ln -s input/js3 js3
-
-mknod input/event0 c 13 64
-mknod input/event1 c 13 65
-mknod input/event2 c 13 66
-mknod input/event3 c 13 67
+If you have a serial iforce device, you need to start inputattach. See
+joystick.txt for details.
 
 2.1 Does it work ?
 ~~~~~~~~~~~~~~~~~~
 There is an utility called fftest that will allow you to test the driver.
 % fftest /dev/input/eventXX
 
-3. Instructions to the developper
+3. Instructions to the developer
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  All interactions are done using the event API. That is, you can use ioctl()
+All interactions are done using the event API. That is, you can use ioctl()
 and write() on /dev/input/eventXX.
-  This information is subject to change.
+This information is subject to change.
 
 3.1 Querying device capabilities
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -86,18 +56,29 @@
 
 Returns the features supported by the device. features is a bitfield with the
 following bits:
-- FF_X		has an X axis (usually joysticks)
-- FF_Y		has an Y axis (usually joysticks)
-- FF_WHEEL	has a wheel (usually sterring wheels)
 - FF_CONSTANT	can render constant force effects
-- FF_PERIODIC	can render periodic effects (sine, triangle, square...)
+- FF_PERIODIC	can render periodic effects with the following waveforms:
+  - FF_SQUARE	  square waveform
+  - FF_TRIANGLE	  triangle waveform
+  - FF_SINE	  sine waveform
+  - FF_SAW_UP	  sawtooth up waveform
+  - FF_SAW_DOWN	  sawtooth down waveform
+  - FF_CUSTOM	  custom waveform
 - FF_RAMP       can render ramp effects
 - FF_SPRING	can simulate the presence of a spring
-- FF_FRICTION	can simulate friction 
+- FF_FRICTION	can simulate friction
 - FF_DAMPER	can simulate damper effects
-- FF_RUMBLE	rumble effects (normally the only effect supported by rumble
-		pads)
+- FF_RUMBLE	rumble effects
 - FF_INERTIA    can simulate inertia
+- FF_GAIN	gain is adjustable
+- FF_AUTOCENTER	autocenter is adjustable
+
+Note: In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All
+      devices that support FF_RUMBLE support FF_PERIODIC (square, triangle,
+      sine) and the other way around.
+
+Note: The exact syntax FF_CUSTOM is undefined for the time being as no driver
+      supports it yet.
 
 
 int ioctl(int fd, EVIOCGEFFECTS, int *n);
@@ -108,7 +89,7 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #include <linux/input.h>
 #include <sys/ioctl.h>
- 
+
 int ioctl(int file_descriptor, int request, struct ff_effect *effect);
 
 "request" must be EVIOCSFF.
@@ -120,6 +101,9 @@
 some operations (removing an effect, controlling the playback).
 This if field must be set to -1 by the user in order to tell the driver to
 allocate a new effect.
+
+Effects are file descriptor specific.
+
 See <linux/input.h> for a description of the ff_effect struct. You should also
 find help in a few sketches, contained in files shape.fig and interactive.fig.
 You need xfig to visualize these files.
@@ -128,8 +112,8 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int ioctl(int fd, EVIOCRMFF, effect.id);
 
-This makes room for new effects in the device's memory. Please note this won't
-stop the effect if it was playing.
+This makes room for new effects in the device's memory. Note that this also
+stops the effect if it was playing.
 
 3.4 Controlling the playback of effects
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -149,22 +133,21 @@
 	play.type = EV_FF;
 	play.code = effect.id;
 	play.value = 3;
-	
+
 	write(fd, (const void*) &play, sizeof(play));
 ...
 	/* Stop an effect */
 	stop.type = EV_FF;
 	stop.code = effect.id;
 	stop.value = 0;
-	
+
 	write(fd, (const void*) &play, sizeof(stop));
 
 3.5 Setting the gain
 ~~~~~~~~~~~~~~~~~~~~
 Not all devices have the same strength. Therefore, users should set a gain
 factor depending on how strong they want effects to be. This setting is
-persistent across access to the driver, so you should not care about it if
-you are writing games, as another utility probably already set this for you.
+persistent across access to the driver.
 
 /* Set the gain of the device
 int gain;		/* between 0 and 100 */
@@ -204,11 +187,14 @@
 the direction of an effect cannot be updated with iforce devices. In this
 case, the driver stops the effect, up-load it, and restart it.
 
+Therefore it is recommended to dynamically change direction while the effect
+is playing only when it is ok to restart the effect with a replay count of 1.
 
 3.8 Information about the status of effects
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Every time the status of an effect is changed, an event is sent. The values
 and meanings of the fields of the event are as follows:
+
 struct input_event {
 /* When the status of the effect changed */
 	struct timeval time;
@@ -225,3 +211,9 @@
 
 FF_STATUS_STOPPED	The effect stopped playing
 FF_STATUS_PLAYING	The effect started to play
+
+NOTE: Status feedback is only supported by iforce driver. If you have
+      a really good reason to use this, please contact
+      linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com
+      so that support for it can be added to the rest of the drivers.
+
diff --git a/Documentation/input/gameport-programming.txt b/Documentation/input/gameport-programming.txt
index 1ba3d32..14e0a8b 100644
--- a/Documentation/input/gameport-programming.txt
+++ b/Documentation/input/gameport-programming.txt
@@ -18,8 +18,8 @@
 gameport generic code will take care of the rest.
 
 If your hardware supports more than one io address, and your driver can
-choose which one program the hardware to, starting from the more exotic
-addresses is preferred, because the likelyhood of clashing with the standard
+choose which one to program the hardware to, starting from the more exotic
+addresses is preferred, because the likelihood of clashing with the standard
 0x201 address is smaller.
 
 Eg. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then
diff --git a/Documentation/input/input.txt b/Documentation/input/input.txt
index 47137e7..ff8cea0 100644
--- a/Documentation/input/input.txt
+++ b/Documentation/input/input.txt
@@ -68,8 +68,8 @@
 
 	crw-r--r--   1 root     root      13,  63 Mar 28 22:45 mice
 
-  This device has to be created, unless you use devfs, in which case it's
-created automatically. The commands to do create it by hand are:
+  This device has to be created.
+  The commands to create it by hand are:
 
 	cd /dev
 	mkdir input
@@ -154,7 +154,7 @@
 
 3.2 Event handlers
 ~~~~~~~~~~~~~~~~~~
-  Event handlers distrubite the events from the devices to userland and
+  Event handlers distribute the events from the devices to userland and
 kernel, as needed.
 
 3.2.1 keybdev
@@ -230,7 +230,7 @@
 API is still evolving, but should be useable now. It's described in
 section 5. 
 
-  This should be the way for GPM and X to get keyboard and mouse mouse
+  This should be the way for GPM and X to get keyboard and mouse
 events. It allows for multihead in X without any specific multihead
 kernel support. The event codes are the same on all architectures and
 are hardware independent.
@@ -279,7 +279,7 @@
 };
 
   'time' is the timestamp, it returns the time at which the event happened.
-Type is for example EV_REL for relative momement, REL_KEY for a keypress or
+Type is for example EV_REL for relative moment, REL_KEY for a keypress or
 release. More types are defined in include/linux/input.h.
 
   'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete
@@ -289,24 +289,3 @@
 EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
 release, 1 for keypress and 2 for autorepeat.
 
-6. Contacts
-~~~~~~~~~~~
-  This effort has its home page at:
-
-	http://www.suse.cz/development/input/
-
-You'll find both the latest HID driver and the complete Input driver
-there as well as information how to access the CVS repository for
-latest revisions of the drivers.
-
-  There is also a mailing list for this:
-
-	majordomo@atrey.karlin.mff.cuni.cz
-
-Send "subscribe linux-input" to subscribe to it.
-
-The input changes are also being worked on as part of the LinuxConsole
-project, see:
-
-	 http://sourceforge.net/projects/linuxconsole/
-
diff --git a/Documentation/input/joystick-parport.txt b/Documentation/input/joystick-parport.txt
index d537c48..ede5f33 100644
--- a/Documentation/input/joystick-parport.txt
+++ b/Documentation/input/joystick-parport.txt
@@ -456,8 +456,8 @@
 	  8  | Sony PSX DDR controller
 	  9  | SNES mouse
 
-  The exact type of the PSX controller type is autoprobed when used so
-hot swapping should work (but is not recomended).
+  The exact type of the PSX controller type is autoprobed when used, so
+hot swapping should work (but is not recommended).
 
   Should you want to use more than one of parallel ports at once, you can use
 gamecon.map2 and gamecon.map3 as additional command line parameters for two
@@ -465,8 +465,8 @@
 
   There are two options specific to PSX driver portion.  gamecon.psx_delay sets
 the command delay when talking to the controllers. The default of 25 should
-work but you can try lowering it for better performace. If your pads don't
-respond try raising it untill they work. Setting the type to 8 allows the
+work but you can try lowering it for better performance. If your pads don't
+respond try raising it until they work. Setting the type to 8 allows the
 driver to be used with Dance Dance Revolution or similar games. Arrow keys are
 registered as key presses instead of X and Y axes.
 
diff --git a/Documentation/input/joystick.txt b/Documentation/input/joystick.txt
index 841c353..389de9b 100644
--- a/Documentation/input/joystick.txt
+++ b/Documentation/input/joystick.txt
@@ -60,7 +60,7 @@
 
 2.2 Device nodes
 ~~~~~~~~~~~~~~~~
-For applications to be able to use the joysticks, in you don't use devfs,
+For applications to be able to use the joysticks,
 you'll have to manually create these nodes in /dev:
 
 cd /dev
diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt
index 0962c5c..0a8c97e 100644
--- a/Documentation/input/yealink.txt
+++ b/Documentation/input/yealink.txt
@@ -87,13 +87,13 @@
 
 
 Format description:
-  From a user space perspective the world is seperated in "digits" and "icons".
+  From a userspace perspective the world is separated into "digits" and "icons".
   A digit can have a character set, an icon can only be ON or OFF.
 
   Format specifier
     '8' :  Generic 7 segment digit with individual addressable segments
 
-    Reduced capabillity 7 segm digit, when segments are hard wired together.
+    Reduced capability 7 segm digit, when segments are hard wired together.
     '1' : 2 segments digit only able to produce a 1.
     'e' : Most significant day of the month digit,
           able to produce at least 1 2 3.
diff --git a/Documentation/ioctl/hdio.txt b/Documentation/ioctl/hdio.txt
index 11c9be4..c19efde 100644
--- a/Documentation/ioctl/hdio.txt
+++ b/Documentation/ioctl/hdio.txt
@@ -203,7 +203,7 @@
 
 	  Source code comments read:
 
-	    This is tightly woven into the driver->do_special can not
+	    This is tightly woven into the driver->do_special cannot
 	    touch.  DON'T do it again until a total personality rewrite
 	    is committed.
 
diff --git a/Documentation/isdn/INTERFACE.fax b/Documentation/isdn/INTERFACE.fax
index 7e57313..9c8c6d9 100644
--- a/Documentation/isdn/INTERFACE.fax
+++ b/Documentation/isdn/INTERFACE.fax
@@ -26,7 +26,7 @@
   If the HL-driver receives ISDN_CMD_FAXCMD, all needed information
   is in this struct set by the LL.
   To signal information to the LL, the HL-driver has to set the 
-  the parameters and use ISDN_STAT_FAXIND.
+  parameters and use ISDN_STAT_FAXIND.
   (Please refer to INTERFACE)
 
 Structure T30_s:
diff --git a/Documentation/isdn/README.hysdn b/Documentation/isdn/README.hysdn
index 56cc59d..eeca11f 100644
--- a/Documentation/isdn/README.hysdn
+++ b/Documentation/isdn/README.hysdn
@@ -1,6 +1,6 @@
 $Id: README.hysdn,v 1.3.6.1 2001/02/10 14:41:19 kai Exp $
 The hysdn driver has been written by
-by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) 
+Werner Cornelius (werner@isdn4linux.de or werner@titro.de)
 for Hypercope GmbH Aachen Germany. Hypercope agreed to publish this driver
 under the GNU General Public License.
 
diff --git a/Documentation/java.txt b/Documentation/java.txt
index e4814c2..c768dc6 100644
--- a/Documentation/java.txt
+++ b/Documentation/java.txt
@@ -22,7 +22,7 @@
    the kernel (CONFIG_BINFMT_MISC) and set it up properly.
    If you choose to compile it as a module, you will have
    to insert it manually with modprobe/insmod, as kmod
-   can not easily be supported with binfmt_misc. 
+   cannot easily be supported with binfmt_misc. 
    Read the file 'binfmt_misc.txt' in this directory to know
    more about the configuration process.
 
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index 003fccc..125093c 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -1,7 +1,7 @@
 Introduction
 ------------
 
-The configuration database is collection of configuration options
+The configuration database is a collection of configuration options
 organized in a tree structure:
 
 	+- Code maturity level options
@@ -110,7 +110,7 @@
   the indentation level, this means it ends at the first line which has
   a smaller indentation than the first line of the help text.
   "---help---" and "help" do not differ in behaviour, "---help---" is
-  used to help visually seperate configuration logic from help within
+  used to help visually separate configuration logic from help within
   the file as an aid to developers.
 
 
@@ -226,7 +226,7 @@
 	"menuconfig" <symbol>
 	<config options>
 
-This is similiar to the simple config entry above, but it also gives a
+This is similar to the simple config entry above, but it also gives a
 hint to front ends, that all suboptions should be displayed as a
 separate list of options.
 
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index e2cbd59..50f4edd 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -390,7 +390,7 @@
 	The kernel may be built with several different versions of
 	$(CC), each supporting a unique set of features and options.
 	kbuild provide basic support to check for valid options for $(CC).
-	$(CC) is useally the gcc compiler, but other alternatives are
+	$(CC) is usually the gcc compiler, but other alternatives are
 	available.
 
     as-option
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt
index 2e7702e..769ee05 100644
--- a/Documentation/kbuild/modules.txt
+++ b/Documentation/kbuild/modules.txt
@@ -43,7 +43,7 @@
 What is covered within this file is mainly information to authors
 of modules. The author of an external module should supply
 a makefile that hides most of the complexity, so one only has to type
-'make' to build the module. A complete example will be present in
+'make' to build the module. A complete example will be presented in
 chapter 4, "Creating a kbuild file for an external module".
 
 
@@ -61,6 +61,7 @@
 		make -C <path-to-kernel> M=`pwd`
 
 	For the running kernel use:
+
 		make -C /lib/modules/`uname -r`/build M=`pwd`
 
 	For the above command to succeed, the kernel must have been
@@ -130,10 +131,10 @@
 
 	To make sure the kernel contains the information required to
 	build external modules the target 'modules_prepare' must be used.
-	'module_prepare' exists solely as a simple way to prepare
+	'modules_prepare' exists solely as a simple way to prepare
 	a kernel source tree for building external modules.
 	Note: modules_prepare will not build Module.symvers even if
-	CONFIG_MODULEVERSIONING is set. Therefore a full kernel build
+	CONFIG_MODVERSIONS is set. Therefore a full kernel build
 	needs to be executed to make module versioning work.
 
 --- 2.5 Building separate files for a module
@@ -450,7 +451,7 @@
 
 Module.symvers contains a list of all exported symbols from a kernel build.
 
---- 7.1 Symbols fron the kernel (vmlinux + modules)
+--- 7.1 Symbols from the kernel (vmlinux + modules)
 
 	During a kernel build, a file named Module.symvers will be generated.
 	Module.symvers contains all exported symbols from the kernel and
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 08bafa8..99f2d4d 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -249,7 +249,7 @@
 is called inside interrupt context or die() is called and panic_on_oops is set,
 the system will boot into the dump-capture kernel.
 
-On powererpc systems when a soft-reset is generated, die() is called by all cpus and the system system will boot into the dump-capture kernel.
+On powererpc systems when a soft-reset is generated, die() is called by all cpus and the system will boot into the dump-capture kernel.
 
 For testing purposes, you can trigger a crash by using "ALT-SysRq-c",
 "echo c > /proc/sysrq-trigger or write a module to force the panic.
diff --git a/Documentation/kernel-docs.txt b/Documentation/kernel-docs.txt
index 99d24f2..b53bccb 100644
--- a/Documentation/kernel-docs.txt
+++ b/Documentation/kernel-docs.txt
@@ -290,17 +290,6 @@
        Description: Very nice 92 pages GPL book on the topic of modules
        programming. Lots of examples.
        
-     * Title: "Device File System (devfs) Overview"
-       Author: Richard Gooch.
-       URL: http://www.atnf.csiro.au/people/rgooch/linux/docs/devfs.html
-       Keywords: filesystem, /dev, devfs, dynamic devices, major/minor
-       allocation, device management.
-       Description: Document describing Richard Gooch's controversial
-       devfs, which allows for dynamic devices, only shows present
-       devices in /dev, gets rid of major/minor numbers allocation
-       problems, and allows for hundreds of identical devices (which some
-       USB systems might demand soon).
-       
      * Title: "I/O Event Handling Under Linux"
        Author: Richard Gooch.
        URL: http://www.atnf.csiro.au/~rgooch/linux/docs/io-events.html
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 137e993..ff571f9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -289,9 +289,6 @@
 
 	autotest	[IA64]
 
-	awe=		[HW,OSS] AWE32/SB32/AWE64 wave table synth
-			Format: <io>,<memsize>,<isapnp>
-
 	aztcd=		[HW,CD] Aztech CD268 CDROM driver
 			Format: <io>,0x79 (?)
 
@@ -355,9 +352,9 @@
 
 	clock=		[BUGS=IA-32, HW] gettimeofday clocksource override.
 			[Deprecated]
-			Forces specified clocksource (if avaliable) to be used
+			Forces specified clocksource (if available) to be used
 			when calculating gettimeofday(). If specified
-			clocksource is not avalible, it defaults to PIT.
+			clocksource is not available, it defaults to PIT.
 			Format: { pit | tsc | cyclone | pmtmr }
 
 	disable_8254_timer
@@ -536,10 +533,6 @@
 			Default value is 0.
 			Value can be changed at runtime via /selinux/enforce.
 
-	es1370=		[HW,OSS]
-			Format: <lineout>[,<micbias>]
-			See also header of sound/oss/es1370.c.
-
 	es1371=		[HW,OSS]
 			Format: <spdif>,[<nomix>,[<amplifier>]]
 			See also header of sound/oss/es1371.c.
@@ -580,9 +573,6 @@
 	gscd=		[HW,CD]
 			Format: <io>
 
-	gus=		[HW,OSS]
-			Format: <io>,<irq>,<dma>,<dma16>
-
 	gvp11=		[HW,SCSI]
 
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
@@ -611,8 +601,8 @@
 	noirqbalance	[IA-32,SMP,KNL] Disable kernel irq balancing
 
 	i8042.direct	[HW] Put keyboard port into non-translated mode
-	i8042.dumbkbd	[HW] Pretend that controlled can only read data from
-			     keyboard and can not control its state
+	i8042.dumbkbd	[HW] Pretend that controller can only read data from
+			     keyboard and cannot control its state
 			     (Don't attempt to blink the leds)
 	i8042.noaux	[HW] Don't check for auxiliary (== mouse) port
 	i8042.nokbd	[HW] Don't check/create keyboard port
@@ -841,12 +831,6 @@
 			(machvec) in a generic kernel.
 			Example: machvec=hpzx1_swiotlb
 
-	mad16=		[HW,OSS] Format:
-			<io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
-
-	maui=		[HW,OSS]
-			Format: <io>,<irq>
-
 	max_loop=	[LOOP] Maximum number of loopback devices that can
 			be mounted
 			Format: <1-256>
@@ -1114,9 +1098,6 @@
 	opl3=		[HW,OSS]
 			Format: <io>
 
-	opl3sa=		[HW,OSS]
-			Format: <io>,<irq>,<dma>,<dma2>,<mpu_io>,<mpu_irq>
-
 	opl3sa2=	[HW,OSS] Format:
 			<io>,<irq>,<dma>,<dma2>,<mss_io>,<mpu_io>,<ymode>,<loopback>[,<isapnp>,<multiple]
 
@@ -1357,10 +1338,6 @@
 	rcu.qlowmark=	[KNL,BOOT] Set threshold of queued
 			RCU callbacks below which batch limiting is re-enabled.
 
-	rcu.rsinterval=	[KNL,BOOT,SMP] Set the number of additional
-			RCU callbacks to queued before forcing reschedule
-			on all cpus.
-
 	rdinit=		[KNL]
 			Format: <full_path>
 			Run specified binary instead of /init from the ramdisk,
@@ -1368,7 +1345,7 @@
 
 	reboot=		[BUGS=IA-32,BUGS=ARM,BUGS=IA-64] Rebooting mode
 			Format: <reboot_mode>[,<reboot_mode2>[,...]]
-			See arch/*/kernel/reboot.c.
+			See arch/*/kernel/reboot.c or arch/*/kernel/process.c			
 
 	reserve=	[KNL,BUGS] Force the kernel to ignore some iomem area
 
@@ -1455,9 +1432,6 @@
 
 	sg_def_reserved_size=	[SCSI]
 
-	sgalaxy=	[HW,OSS]
-			Format: <io>,<irq>,<dma>,<dma2>,<sgbase>
-
 	shapers=	[NET]
 			Maximal number of shapers.
 
@@ -1598,9 +1572,6 @@
 
 	snd-ymfpci=	[HW,ALSA]
 
-	sonicvibes=	[HW,OSS]
-			Format: <reverb>
-
 	sonycd535=	[HW,CD]
 			Format: <io>[,<irq>]
 
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index e373f02..3da586b 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -671,7 +671,7 @@
 
      Note that this setting is inherited across fork/exec.
 
-     [1] The default default is: the thread keyring if there is one, otherwise
+     [1] The default is: the thread keyring if there is one, otherwise
      the process keyring if there is one, otherwise the session keyring if
      there is one, otherwise the user default session keyring.
 
@@ -708,14 +708,14 @@
 
      If the specified key is 0, then any assumed authority will be divested.
 
-     The assumed authorititive key is inherited across fork and exec.
+     The assumed authoritative key is inherited across fork and exec.
 
 
 ===============
 KERNEL SERVICES
 ===============
 
-The kernel services for key managment are fairly simple to deal with. They can
+The kernel services for key management are fairly simple to deal with. They can
 be broken down into two areas: keys and key types.
 
 Dealing with keys is fairly straightforward. Firstly, the kernel service
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index 949f7b5..e448555 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -51,7 +51,7 @@
 almost all complex data types share. kobjects are intended to be
 embedded in larger data structures and replace fields they duplicate. 
 
-1.2 Defintion
+1.2 Definition
 
 struct kobject {
 	char			name[KOBJ_NAME_LEN];
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 2c3b1ea..ba26201 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -151,9 +151,9 @@
 make sure "Loadable module support" (CONFIG_MODULES) and "Module
 unloading" (CONFIG_MODULE_UNLOAD) are set to "y".
 
-You may also want to ensure that CONFIG_KALLSYMS and perhaps even
-CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name()
-is a handy, version-independent way to find a function's address.
+Also make sure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL
+are set to "y", since kallsyms_lookup_name() is used by the in-kernel
+kprobe address resolution code.
 
 If you need to insert a probe in the middle of a function, you may find
 it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
@@ -179,6 +179,27 @@
 or during single-stepping of the probed instruction, Kprobes calls
 kp->fault_handler.  Any or all handlers can be NULL.
 
+NOTE:
+1. With the introduction of the "symbol_name" field to struct kprobe,
+the probepoint address resolution will now be taken care of by the kernel.
+The following will now work:
+
+	kp.symbol_name = "symbol_name";
+
+(64-bit powerpc intricacies such as function descriptors are handled
+transparently)
+
+2. Use the "offset" field of struct kprobe if the offset into the symbol
+to install a probepoint is known. This field is used to calculate the
+probepoint.
+
+3. Specify either the kprobe "symbol_name" OR the "addr". If both are
+specified, kprobe registration will fail with -EINVAL.
+
+4. With CISC architectures (such as i386 and x86_64), the kprobes code
+does not validate if the kprobe.addr is at an instruction boundary.
+Use "offset" with caution.
+
 register_kprobe() returns 0 on success, or a negative errno otherwise.
 
 User's pre-handler (kp->pre_handler):
@@ -225,6 +246,12 @@
 fastcall, or anything else that affects how args are passed, the
 handler's declaration must match.
 
+NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific
+aliasing of jp->entry. In the interest of portability, it is advised
+to use:
+
+	jp->entry = JPROBE_ENTRY(handler);
+
 register_jprobe() returns 0 on success, or a negative errno otherwise.
 
 4.3 register_kretprobe
@@ -251,6 +278,11 @@
 - ret_addr: the return address
 - rp: points to the corresponding kretprobe object
 - task: points to the corresponding task struct
+
+The regs_return_value(regs) macro provides a simple abstraction to
+extract the return value from the appropriate register as defined by
+the architecture's ABI.
+
 The handler's return value is currently ignored.
 
 4.4 unregister_*probe
@@ -369,7 +401,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
 #include <linux/sched.h>
 
 /*For each probe you need to allocate a kprobe structure*/
@@ -403,18 +434,14 @@
 	return 0;
 }
 
-int init_module(void)
+static int __init kprobe_init(void)
 {
 	int ret;
 	kp.pre_handler = handler_pre;
 	kp.post_handler = handler_post;
 	kp.fault_handler = handler_fault;
-	kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork");
-	/* register the kprobe now */
-	if (!kp.addr) {
-		printk("Couldn't find %s to plant kprobe\n", "do_fork");
-		return -1;
-	}
+	kp.symbol_name = "do_fork";
+
 	if ((ret = register_kprobe(&kp) < 0)) {
 		printk("register_kprobe failed, returned %d\n", ret);
 		return -1;
@@ -423,12 +450,14 @@
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit kprobe_exit(void)
 {
 	unregister_kprobe(&kp);
 	printk("kprobe unregistered\n");
 }
 
+module_init(kprobe_init)
+module_exit(kprobe_exit)
 MODULE_LICENSE("GPL");
 ----- cut here -----
 
@@ -463,7 +492,6 @@
 #include <linux/fs.h>
 #include <linux/uio.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
 
 /*
  * Jumper probe for do_fork.
@@ -485,17 +513,13 @@
 }
 
 static struct jprobe my_jprobe = {
-	.entry = (kprobe_opcode_t *) jdo_fork
+	.entry = JPROBE_ENTRY(jdo_fork)
 };
 
-int init_module(void)
+static int __init jprobe_init(void)
 {
 	int ret;
-	my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
-	if (!my_jprobe.kp.addr) {
-		printk("Couldn't find %s to plant jprobe\n", "do_fork");
-		return -1;
-	}
+	my_jprobe.kp.symbol_name = "do_fork";
 
 	if ((ret = register_jprobe(&my_jprobe)) <0) {
 		printk("register_jprobe failed, returned %d\n", ret);
@@ -506,12 +530,14 @@
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit jprobe_exit(void)
 {
 	unregister_jprobe(&my_jprobe);
 	printk("jprobe unregistered\n");
 }
 
+module_init(jprobe_init)
+module_exit(jprobe_exit)
 MODULE_LICENSE("GPL");
 ----- cut here -----
 
@@ -530,16 +556,13 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
 
 static const char *probed_func = "sys_open";
 
 /* Return-probe handler: If the probed function fails, log the return value. */
 static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 {
-	// Substitute the appropriate register name for your architecture --
-	// e.g., regs->rax for x86_64, regs->gpr[3] for ppc64.
-	int retval = (int) regs->eax;
+	int retval = regs_return_value(regs);
 	if (retval < 0) {
 		printk("%s returns %d\n", probed_func, retval);
 	}
@@ -552,15 +575,11 @@
 	.maxactive = 20
 };
 
-int init_module(void)
+static int __init kretprobe_init(void)
 {
 	int ret;
-	my_kretprobe.kp.addr =
-		(kprobe_opcode_t *) kallsyms_lookup_name(probed_func);
-	if (!my_kretprobe.kp.addr) {
-		printk("Couldn't find %s to plant return probe\n", probed_func);
-		return -1;
-	}
+	my_kretprobe.kp.symbol_name = (char *)probed_func;
+
 	if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
 		printk("register_kretprobe failed, returned %d\n", ret);
 		return -1;
@@ -569,7 +588,7 @@
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit kretprobe_exit(void)
 {
 	unregister_kretprobe(&my_kretprobe);
 	printk("kretprobe unregistered\n");
@@ -578,6 +597,8 @@
 		my_kretprobe.nmissed, probed_func);
 }
 
+module_init(kretprobe_init)
+module_exit(kretprobe_exit)
 MODULE_LICENSE("GPL");
 ----- cut here -----
 
@@ -590,3 +611,5 @@
 For additional information on Kprobes, refer to the following URLs:
 http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
 http://www.redhat.com/magazine/005mar05/features/kprobes/
+http://www-users.cs.umn.edu/~boutcher/kprobes/
+http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
diff --git a/Documentation/laptop-mode.txt b/Documentation/laptop-mode.txt
index 5696e87..c487186 100644
--- a/Documentation/laptop-mode.txt
+++ b/Documentation/laptop-mode.txt
@@ -152,7 +152,7 @@
 DO_REMOUNTS:
 
 The control script automatically remounts any mounted journaled filesystems
-with approriate commit interval options. When this option is set to 0, this
+with appropriate commit interval options. When this option is set to 0, this
 feature is disabled.
 
 DO_REMOUNT_NOATIME:
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt
index 55a7e4f..dab123d 100644
--- a/Documentation/lockdep-design.txt
+++ b/Documentation/lockdep-design.txt
@@ -133,7 +133,7 @@
 (defined by the properties of the hierarchy), and the kernel grabs the
 locks in this fixed order on each of the objects.
 
-An example of such an object hieararchy that results in "nested locking"
+An example of such an object hierarchy that results in "nested locking"
 is that of a "whole disk" block-dev object and a "partition" block-dev
 object; the partition is "part of" the whole device and as long as one
 always takes the whole disk lock as a higher lock than the partition
@@ -158,11 +158,11 @@
 In this case the locking is done on a bdev object that is known to be a
 partition.
 
-The validator treats a lock that is taken in such a nested fasion as a
+The validator treats a lock that is taken in such a nested fashion as a
 separate (sub)class for the purposes of validation.
 
 Note: When changing code to use the _nested() primitives, be careful and
-check really thoroughly that the hiearchy is correctly mapped; otherwise
+check really thoroughly that the hierarchy is correctly mapped; otherwise
 you can get false positives or false negatives.
 
 Proof of 100% correctness:
@@ -170,7 +170,7 @@
 
 The validator achieves perfect, mathematical 'closure' (proof of locking
 correctness) in the sense that for every simple, standalone single-task
-locking sequence that occured at least once during the lifetime of the
+locking sequence that occurred at least once during the lifetime of the
 kernel, the validator proves it with a 100% certainty that no
 combination and timing of these locking sequences can cause any class of
 lock related deadlock. [*]
diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
index d5d3f06..1c41db2 100644
--- a/Documentation/m68k/kernel-options.txt
+++ b/Documentation/m68k/kernel-options.txt
@@ -415,7 +415,7 @@
 
   The first 3 parameters of this sub-option should be obvious: <xres>,
 <yres> and <depth> give the dimensions of the screen and the number of
-planes (depth). The depth is is the logarithm to base 2 of the number
+planes (depth). The depth is the logarithm to base 2 of the number
 of colors possible. (Or, the other way round: The number of colors is
 2^depth).
 
diff --git a/Documentation/mca.txt b/Documentation/mca.txt
index 6091335..aabce4a 100644
--- a/Documentation/mca.txt
+++ b/Documentation/mca.txt
@@ -177,7 +177,7 @@
 	with clones that have a different adapter id than the original
 	NE/2.
 
-6) Future Domain MCS-600/700, OEM'd IBM Fast SCSI Aapter/A and
+6) Future Domain MCS-600/700, OEM'd IBM Fast SCSI Adapter/A and
    Reply Sound Blaster/SCSI (SCSI part)
 	Better support for these cards than the driver for ISA.
    Supports multiple cards with IRQ sharing.
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 0668f9d..2202f5d 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -62,7 +62,7 @@
 
 For this reason, md will normally refuse to start such an array.  This
 requires the sysadmin to take action to explicitly start the array
-desipite possible corruption.  This is normally done with
+despite possible corruption.  This is normally done with
    mdadm --assemble --force ....
 
 This option is not really available if the array has the root
@@ -154,11 +154,12 @@
 
 All md devices contain:
   level
-     a text file indicating the 'raid level'.  This may be a standard
-     numerical level prefixed by "RAID-" - e.g. "RAID-5", or some
-     other name such as "linear" or "multipath".
+     a text file indicating the 'raid level'. e.g. raid0, raid1,
+     raid5, linear, multipath, faulty.
      If no raid level has been set yet (array is still being
-     assembled), this file will be empty.
+     assembled), the value will reflect whatever has been written
+     to it, which may be a name like the above, or may be a number
+     such as '0', '5', etc.
 
   raid_disks
      a text file with a simple number indicating the number of devices
@@ -174,7 +175,7 @@
      raid levels that involve striping (1,4,5,6,10). The address space
      of the array is conceptually divided into chunks and consecutive
      chunks are striped onto neighbouring devices.
-     The size should be atleast PAGE_SIZE (4k) and should be a power
+     The size should be at least PAGE_SIZE (4k) and should be a power
      of 2.  This can only be set while assembling an array
 
   component_size
@@ -192,14 +193,6 @@
      1.2 (newer format in varying locations) or "none" indicating that
      the kernel isn't managing metadata at all.
 
-  level
-     The raid 'level' for this array.  The name will often (but not
-     always) be the same as the name of the module that implements the
-     level.  To be auto-loaded the module must have an alias
-        md-$LEVEL  e.g. md-raid5
-     This can be written only while the array is being assembled, not
-     after it is started.
-
   layout
      The "layout" for the array for the particular level.  This is
      simply a number that is interpretted differently by different
@@ -221,8 +214,8 @@
    safe_mode_delay
      When an md array has seen no write requests for a certain period
      of time, it will be marked as 'clean'.  When another write
-     request arrive, the array is marked as 'dirty' before the write
-     commenses.  This is known as 'safe_mode'.
+     request arrives, the array is marked as 'dirty' before the write
+     commences.  This is known as 'safe_mode'.
      The 'certain period' is controlled by this file which stores the
      period as a number of seconds.  The default is 200msec (0.200).
      Writing a value of 0 disables safemode.
@@ -314,8 +307,8 @@
 			 This applies only to raid1 arrays.
 	      spare    - device is working, but not a full member.
 			 This includes spares that are in the process
-			 of being recoverred to
-	This list make grow in future.
+			 of being recovered to
+	This list may grow in future.
 	This can be written to.
 	Writing "faulty"  simulates a failure on the device.
 	Writing "remove" removes the device from the array.
@@ -337,7 +330,7 @@
         This gives the role that the device has in the array.  It will
 	either be 'none' if the device is not active in the array
         (i.e. is a spare or has failed) or an integer less than the
-	'raid_disks' number for the array indicating which possition
+	'raid_disks' number for the array indicating which position
 	it currently fills.  This can only be set while assembling an
 	array.  A device for which this is set is assumed to be working.
 
@@ -360,7 +353,7 @@
 
     rdNN
 
-where 'NN' is the possition in the array, starting from 0.
+where 'NN' is the position in the array, starting from 0.
 So for a 3 drive array there will be rd0, rd1, rd2.
 These are symbolic links to the appropriate 'dev-XXX' entry.
 Thus, for example,
@@ -410,6 +403,15 @@
       than sectors, this my be larger than the number of actual errors
       by a factor of the number of sectors in a page.
 
+   bitmap_set_bits
+      If the array has a write-intent bitmap, then writing to this
+      attribute can set bits in the bitmap, indicating that a resync
+      would need to check the corresponding blocks. Either individual
+      numbers or start-end pairs can be written.  Multiple numbers
+      can be separated by a space.
+      Note that the numbers are 'bit' numbers, not 'block' numbers.
+      They should be scaled by the bitmap_chunksize.
+
 Each active md device may also have attributes specific to the
 personality module that manages it.
 These are specific to the implementation of the module and could
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 46b9b38..994355b 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -670,7 +670,7 @@
 
 
 In the above example, CPU 2 perceives that B is 7, despite the load of *C
-(which would be B) coming after the the LOAD of C.
+(which would be B) coming after the LOAD of C.
 
 If, however, a data dependency barrier were to be placed between the load of C
 and the load of *C (ie: B) on CPU 2:
@@ -1915,7 +1915,7 @@
 access depends on a read, not all do, so it may not be relied on.
 
 Other CPUs may also have split caches, but must coordinate between the various
-cachelets for normal memory accesss.  The semantics of the Alpha removes the
+cachelets for normal memory accesses.  The semantics of the Alpha removes the
 need for coordination in absence of memory barriers.
 
 
diff --git a/Documentation/mono.txt b/Documentation/mono.txt
index 807a0c7..e8e1758 100644
--- a/Documentation/mono.txt
+++ b/Documentation/mono.txt
@@ -26,7 +26,7 @@
    the kernel (CONFIG_BINFMT_MISC) and set it up properly.
    If you choose to compile it as a module, you will have
    to insert it manually with modprobe/insmod, as kmod
-   can not be easily supported with binfmt_misc. 
+   cannot be easily supported with binfmt_misc. 
    Read the file 'binfmt_misc.txt' in this directory to know
    more about the configuration process.
 
diff --git a/Documentation/networking/3c509.txt b/Documentation/networking/3c509.txt
index 867a99f..0643e3b 100644
--- a/Documentation/networking/3c509.txt
+++ b/Documentation/networking/3c509.txt
@@ -126,7 +126,7 @@
 or impossible in normal operation. Possible causes of this error report are:
  
    - a "green" mode enabled that slows the processor down when there is no
-     keyboard activitiy. 
+     keyboard activity. 
 
    - some other device or device driver hogging the bus or disabling interrupts.
      Check /proc/interrupts for excessive interrupt counts. The timer tick
diff --git a/Documentation/networking/NAPI_HOWTO.txt b/Documentation/networking/NAPI_HOWTO.txt
index 54376e8..93af3e8 100644
--- a/Documentation/networking/NAPI_HOWTO.txt
+++ b/Documentation/networking/NAPI_HOWTO.txt
@@ -35,7 +35,7 @@
 packets out of the rx ring. Note from this that the lower the
 load the more we could clean up the rxring
 "Ndone" == is the converse of "Done". Note again, that the higher
-the load the more times we couldnt clean up the rxring.
+the load the more times we couldn't clean up the rxring.
 
 Observe that:
 when the NIC receives 890Kpackets/sec only 17 rx interrupts are generated. 
diff --git a/Documentation/networking/arcnet-hardware.txt b/Documentation/networking/arcnet-hardware.txt
index 30a5f01..731de41 100644
--- a/Documentation/networking/arcnet-hardware.txt
+++ b/Documentation/networking/arcnet-hardware.txt
@@ -139,7 +139,7 @@
 
 5. An active hub to passive hub.
 
-Remember, that you can not connect two passive hubs together.  The power loss
+Remember that you cannot connect two passive hubs together.  The power loss
 implied by such a connection is too high for the net to operate reliably.
 
 An example of a typical ARCnet network:
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index dc942ea..de809e5 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -1023,7 +1023,7 @@
 files located in /sys/class/net/<bond name>/bonding
 
 	The names of these files correspond directly with the command-
-line parameters described elsewhere in in this file, and, with the
+line parameters described elsewhere in this file, and, with the
 exception of arp_ip_target, they accept the same values.  To see the
 current setting, simply cat the appropriate file.
 
diff --git a/Documentation/networking/cs89x0.txt b/Documentation/networking/cs89x0.txt
index 188beb7..6489647 100644
--- a/Documentation/networking/cs89x0.txt
+++ b/Documentation/networking/cs89x0.txt
@@ -227,7 +227,7 @@
 * media=rj45           - specify media type
    or media=bnc
    or media=aui
-   or medai=auto
+   or media=auto
 * duplex=full          - specify forced half/full/autonegotiate duplex
    or duplex=half
    or duplex=auto
@@ -584,7 +584,7 @@
 
     1.) The system does not boot properly (or at all).
 
-    2.) The driver can not communicate with the adapter, reporting an "Adapter
+    2.) The driver cannot communicate with the adapter, reporting an "Adapter
         not found" error message.
 
     3.) You cannot connect to the network or the driver will not load.
@@ -684,7 +684,7 @@
 software-update notification.
 
 Cirrus Logic maintains a web page at http://www.cirrus.com with the
-the latest drivers and technical publications.
+latest drivers and technical publications.
 
 
 6.4 Current maintainer
diff --git a/Documentation/networking/cxgb.txt b/Documentation/networking/cxgb.txt
index 7632463..20a8876 100644
--- a/Documentation/networking/cxgb.txt
+++ b/Documentation/networking/cxgb.txt
@@ -56,7 +56,7 @@
 
       ethtool -C eth0 rx-usecs 100
 
-  You may also provide a timer latency value while disabling adpative-rx:
+  You may also provide a timer latency value while disabling adaptive-rx:
 
       ethtool -C <interface> adaptive-rx off rx-usecs <microseconds>
 
@@ -172,7 +172,7 @@
    smaller window prevents congestion and facilitates better pacing,
    especially if/when MAC level flow control does not work well or when it is
    not supported on the machine. Experimentation may be necessary to attain
-   the correct value. This method is provided as a starting point fot the
+   the correct value. This method is provided as a starting point for the
    correct receive buffer size.
    Setting the min, max, and default receive buffer (RX_WINDOW) size is
    performed in the same manner as single connection.
diff --git a/Documentation/networking/decnet.txt b/Documentation/networking/decnet.txt
index e6c39c5..badb748 100644
--- a/Documentation/networking/decnet.txt
+++ b/Documentation/networking/decnet.txt
@@ -82,7 +82,7 @@
 address of the node in order for it to be autoconfigured (and then appear in
 /proc/net/decnet_dev). There is a utility available at the above
 FTP sites called dn2ethaddr which can compute the correct ethernet
-address to use. The address can be set by ifconfig either before at
+address to use. The address can be set by ifconfig either before or
 at the time the device is brought up. If you are using RedHat you can
 add the line:
 
diff --git a/Documentation/networking/dl2k.txt b/Documentation/networking/dl2k.txt
index d460492..10e8490 100644
--- a/Documentation/networking/dl2k.txt
+++ b/Documentation/networking/dl2k.txt
@@ -173,7 +173,7 @@
 
 Parameter Description
 =====================
-You can install this driver without any addtional parameter. However, if you
+You can install this driver without any additional parameter. However, if you
 are going to have extensive functions then it is necessary to set extra
 parameter. Below is a list of the command line parameters supported by the
 Linux device
@@ -222,7 +222,7 @@
 				  reach timeout of n * 640 nano seconds. 
 				  Set proper rx_coalesce and rx_timeout can 
 				  reduce congestion collapse and overload which
-				  has been a bottlenect for high speed network.
+				  has been a bottleneck for high speed network.
 				  
 				  For example, rx_coalesce=10 rx_timeout=800.
 				  that is, hardware assert only 1 interrupt 
diff --git a/Documentation/networking/dmfe.txt b/Documentation/networking/dmfe.txt
index 0463635..b1b7499 100644
--- a/Documentation/networking/dmfe.txt
+++ b/Documentation/networking/dmfe.txt
@@ -34,7 +34,7 @@
 
 	ifconfig eth0 172.22.3.18
                       ^^^^^^^^^^^
-		     Your IP Adress
+		     Your IP Address
 
 Then you may have to modify the default routing table with command :
 
diff --git a/Documentation/networking/driver.txt b/Documentation/networking/driver.txt
index a9ad58b..4f7da5a 100644
--- a/Documentation/networking/driver.txt
+++ b/Documentation/networking/driver.txt
@@ -37,7 +37,7 @@
 		...
 	}
 
-   And then at the end of your TX reclaimation event handling:
+   And then at the end of your TX reclamation event handling:
 
 	if (netif_queue_stopped(dp->dev) &&
             TX_BUFFS_AVAIL(dp) > (MAX_SKB_FRAGS + 1))
diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt
index 71fe15a..5c0a5cc 100644
--- a/Documentation/networking/e1000.txt
+++ b/Documentation/networking/e1000.txt
@@ -350,7 +350,7 @@
 
   As an example, if you install the e1000 driver for two PRO/1000 adapters
   (eth0 and eth1) and set the speed and duplex to 10full and 100half, add
-  the following to modules.conf or or modprobe.conf:
+  the following to modules.conf or modprobe.conf:
 
        alias eth0 e1000
        alias eth1 e1000
diff --git a/Documentation/networking/fib_trie.txt b/Documentation/networking/fib_trie.txt
index f50d0c6..0723db7 100644
--- a/Documentation/networking/fib_trie.txt
+++ b/Documentation/networking/fib_trie.txt
@@ -79,7 +79,7 @@
 
 resize()
 	Analyzes a tnode and optimizes the child array size by either inflating
-	or shrinking it repeatedly until it fullfills the criteria for optimal
+	or shrinking it repeatedly until it fulfills the criteria for optimal
 	level compression. This part follows the original paper pretty closely
 	and there may be some room for experimentation here.
 
diff --git a/Documentation/networking/gen_stats.txt b/Documentation/networking/gen_stats.txt
index c3297f7..70e6275 100644
--- a/Documentation/networking/gen_stats.txt
+++ b/Documentation/networking/gen_stats.txt
@@ -79,8 +79,8 @@
 
 0) Prepare an estimator attribute. Most likely this would be in user
    space. The value of this TLV should contain a tc_estimator structure.
-   As usual, such a TLV nees to be 32 bit aligned and therefore the
-   length needs to be appropriately set etc. The estimator interval
+   As usual, such a TLV needs to be 32 bit aligned and therefore the
+   length needs to be appropriately set, etc. The estimator interval
    and ewma log need to be converted to the appropriate values.
    tc_estimator.c::tc_setup_estimator() is advisable to be used as the
    conversion routine. It does a few clever things. It takes a time
@@ -103,8 +103,8 @@
    else
        failed
 
-From now on, everytime you dump my_rate_est_stats it will contain
-uptodate info.
+From now on, every time you dump my_rate_est_stats it will contain
+up-to-date info.
 
 Once you are done, call gen_kill_estimator(my_basicstats,
 my_rate_est_stats) Make sure that my_basicstats and my_rate_est_stats
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 935e298..fd3c0c0 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -495,7 +495,7 @@
 
 	Note that if no primary address exists for the interface selected,
 	then the primary address of the first non-loopback interface that
-	has one will be used regarldess of this setting.
+	has one will be used regardless of this setting.
 
 	Default: 0
 
@@ -787,7 +787,7 @@
 			    disabled if accept_ra is disabled.
 
 accept_ra_pinfo - BOOLEAN
-	Learn Prefix Inforamtion in Router Advertisement.
+	Learn Prefix Information in Router Advertisement.
 
 	Functional default: enabled if accept_ra is enabled.
 			    disabled if accept_ra is disabled.
diff --git a/Documentation/networking/netconsole.txt b/Documentation/networking/netconsole.txt
index 53618fb..1caa6c7 100644
--- a/Documentation/networking/netconsole.txt
+++ b/Documentation/networking/netconsole.txt
@@ -52,6 +52,6 @@
 Netconsole was designed to be as instantaneous as possible, to
 enable the logging of even the most critical kernel bugs. It works
 from IRQ contexts as well, and does not enable interrupts while
-sending packets. Due to these unique needs, configuration can not
+sending packets. Due to these unique needs, configuration cannot
 be more automatic, and some fundamental limitations will remain:
 only IP networks, UDP packets and ethernet devices are supported.
diff --git a/Documentation/networking/netif-msg.txt b/Documentation/networking/netif-msg.txt
index 18ad4ce..c967ddb 100644
--- a/Documentation/networking/netif-msg.txt
+++ b/Documentation/networking/netif-msg.txt
@@ -40,7 +40,7 @@
    Per-interface rather than per-driver message level setting.
    More selective control over the type of messages emitted.
 
- The netif_msg recommandation adds these features with only a minor
+ The netif_msg recommendation adds these features with only a minor
  complexity and code size increase.
 
  The recommendation is the following points
diff --git a/Documentation/networking/operstates.txt b/Documentation/networking/operstates.txt
index 4a21d9b..c9074f9 100644
--- a/Documentation/networking/operstates.txt
+++ b/Documentation/networking/operstates.txt
@@ -2,7 +2,7 @@
 1. Introduction
 
 Linux distinguishes between administrative and operational state of an
-interface. Admininstrative state is the result of "ip link set dev
+interface. Administrative state is the result of "ip link set dev
 <dev> up or down" and reflects whether the administrator wants to use
 the device for traffic.
 
diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt
index aaf99d5..12a008a 100644
--- a/Documentation/networking/packet_mmap.txt
+++ b/Documentation/networking/packet_mmap.txt
@@ -66,7 +66,7 @@
 
 [setup]     socket() -------> creation of the capture socket
             setsockopt() ---> allocation of the circular buffer (ring)
-            mmap() ---------> maping of the allocated buffer to the
+            mmap() ---------> mapping of the allocated buffer to the
                               user process
 
 [capture]   poll() ---------> to wait for incoming packets
@@ -93,7 +93,7 @@
 is done by a simple call to close(fd).
 
 Next I will describe PACKET_MMAP settings and it's constraints,
-also the maping of the circular buffer in the user process and 
+also the mapping of the circular buffer in the user process and 
 the use of this buffer.
 
 --------------------------------------------------------------------------------
@@ -153,8 +153,8 @@
 
 A frame can be of any size with the only condition it can fit in a block. A block
 can only hold an integer number of frames, or in other words, a frame cannot 
-be spawn accross two blocks so there are some datails you have to take into 
-account when choosing the frame_size. See "Maping and use of the circular 
+be spawned accross two blocks, so there are some details you have to take into 
+account when choosing the frame_size. See "Mapping and use of the circular 
 buffer (ring)".
 
 
@@ -215,8 +215,8 @@
      block #1
 
 
-kmalloc allocates any number of bytes of phisically contiguous memory from 
-a pool of pre-determined sizes. This pool of memory is mantained by the slab 
+kmalloc allocates any number of bytes of physically contiguous memory from 
+a pool of pre-determined sizes. This pool of memory is maintained by the slab 
 allocator which is at the end the responsible for doing the allocation and 
 hence which imposes the maximum memory that kmalloc can allocate. 
 
@@ -262,7 +262,7 @@
 	<pagesize> = 4096 bytes
 	<max-order> = 11
 
-and a value for <frame size> of 2048 byteas. These parameters will yield
+and a value for <frame size> of 2048 bytes. These parameters will yield
 
 	<block number> = 131072/4 = 32768 blocks
 	<block size> = 4096 << 11 = 8 MiB.
@@ -278,7 +278,7 @@
 All memory allocations are not freed until the socket is closed. The memory 
 allocations are done with GFP_KERNEL priority, this basically means that 
 the allocation can wait and swap other process' memory in order to allocate 
-the nececessary memory, so normally limits can be reached.
+the necessary memory, so normally limits can be reached.
 
  Other constraints
 -------------------
@@ -296,7 +296,7 @@
    - struct tpacket_hdr
    - pad to TPACKET_ALIGNMENT=16
    - struct sockaddr_ll
-   - Gap, chosen so that packet data (Start+tp_net) alignes to 
+   - Gap, chosen so that packet data (Start+tp_net) aligns to 
      TPACKET_ALIGNMENT=16
    - Start+tp_mac: [ Optional MAC header ]
    - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
@@ -311,14 +311,14 @@
    tp_frame_size must be a multiple of TPACKET_ALIGNMENT
    tp_frame_nr   must be exactly frames_per_block*tp_block_nr
 
-Note that tp_block_size should be choosed to be a power of two or there will
+Note that tp_block_size should be chosen to be a power of two or there will
 be a waste of memory.
 
 --------------------------------------------------------------------------------
-+ Maping and use of the circular buffer (ring)
++ Mapping and use of the circular buffer (ring)
 --------------------------------------------------------------------------------
 
-The maping of the buffer in the user process is done with the conventional 
+The mapping of the buffer in the user process is done with the conventional 
 mmap function. Even the circular buffer is compound of several physically
 discontiguous blocks of memory, they are contiguous to the user space, hence
 just one call to mmap is needed:
diff --git a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt
index 18d385c..c8eee23 100644
--- a/Documentation/networking/pktgen.txt
+++ b/Documentation/networking/pktgen.txt
@@ -7,7 +7,7 @@
 
 Enable CONFIG_NET_PKTGEN to compile and build pktgen.o either in kernel
 or as module. Module is preferred. insmod pktgen if needed. Once running
-pktgen creates a thread on each CPU where each thread has affinty it's CPU.
+pktgen creates a thread on each CPU where each thread has affinity to its CPU.
 Monitoring and controlling is done via /proc. Easiest to select a suitable 
 a sample script and configure.
 
@@ -18,7 +18,7 @@
 root       130  0.3  0.0     0    0 ?        SW    2003 509:50 [pktgen/1]
 
 
-For montoring and control pktgen creates:
+For monitoring and control pktgen creates:
 	/proc/net/pktgen/pgctrl
 	/proc/net/pktgen/kpktgend_X
         /proc/net/pktgen/ethX
@@ -32,7 +32,7 @@
 Stopped: eth1 
 Result: OK: max_before_softirq=10000
 
-Most important the devices assigend to thread. Note! A device can only belong 
+Most important the devices assigned to thread. Note! A device can only belong 
 to one thread.
 
 
@@ -147,7 +147,7 @@
 Example scripts
 ===============
 
-A collection of small tutorial scripts for pktgen is in expamples dir.
+A collection of small tutorial scripts for pktgen is in examples dir.
 
 pktgen.conf-1-1                  # 1 CPU 1 dev 
 pktgen.conf-1-2                  # 1 CPU 2 dev
diff --git a/Documentation/networking/s2io.txt b/Documentation/networking/s2io.txt
index bd528ff..4bde53e 100644
--- a/Documentation/networking/s2io.txt
+++ b/Documentation/networking/s2io.txt
@@ -126,7 +126,7 @@
 #setpci -d 17d5:* LATENCY_TIMER=f8
 For detailed description of the PCI registers, please see Xframe User Guide.
 b. Use 2-buffer mode. This results in large performance boost on
-on certain platforms(eg. SGI Altix, IBM xSeries).
+certain platforms(eg. SGI Altix, IBM xSeries).
 c. Ensure Receive Checksum offload is enabled. Use "ethtool -K ethX" command to 
 set/verify this option.
 d. Enable NAPI feature(in kernel configuration Device Drivers ---> Network 
diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
index 7837c53..4e1cc74 100644
--- a/Documentation/networking/sk98lin.txt
+++ b/Documentation/networking/sk98lin.txt
@@ -180,7 +180,7 @@
 1. Insert a line of the form :
    options sk98lin ...
    For "...", the same syntax is required as described for the command
-   line paramaters of modprobe below.
+   line parameters of modprobe below.
 2. To activate the new parameters, either reboot your computer
    or 
    unload and reload the driver.
@@ -320,7 +320,7 @@
 Values:       None, Static, Dynamic
 Default:      None
 
-Interrupt moderation is employed to limit the maxmimum number of interrupts
+Interrupt moderation is employed to limit the maximum number of interrupts
 the driver has to serve. That is, one or more interrupts (which indicate any
 transmit or receive packet to be processed) are queued until the driver 
 processes them. When queued interrupts are to be served, is determined by the
@@ -364,9 +364,9 @@
 Values:       30...40000 (interrupts per second)
 Default:      2000
 
-This parameter is only used, if either static or dynamic interrupt moderation
-is used on a network adapter card. Using this paramter if no moderation is
-applied, will lead to no action performed.
+This parameter is only used if either static or dynamic interrupt moderation
+is used on a network adapter card. Using this parameter if no moderation is
+applied will lead to no action performed.
 
 This parameter determines the length of any interrupt moderation interval. 
 Assuming that static interrupt moderation is to be used, an 'IntsPerSec' 
@@ -484,7 +484,7 @@
 following list:
 
 
-Problem:  The SK-98xx adapter can not be found by the driver.
+Problem:  The SK-98xx adapter cannot be found by the driver.
 Solution: In /proc/pci search for the following entry:
              'Ethernet controller: SysKonnect SK-98xx ...'
           If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has 
@@ -497,12 +497,12 @@
           www.syskonnect.com
           
           Some COMPAQ machines have problems dealing with PCI under Linux.
-          Linux. This problem is described in the 'PCI howto' document
+          This problem is described in the 'PCI howto' document
           (included in some distributions or available from the
           web, e.g. at 'www.linux.org'). 
 
 
-Problem:  Programs such as 'ifconfig' or 'route' can not be found or the 
+Problem:  Programs such as 'ifconfig' or 'route' cannot be found or the 
           error message 'Operation not permitted' is displayed.
 Reason:   You are not logged in as user 'root'.
 Solution: Logout and login as 'root' or change to 'root' via 'su'.
diff --git a/Documentation/networking/skfp.txt b/Documentation/networking/skfp.txt
index 3a419ed..abfddf8 100644
--- a/Documentation/networking/skfp.txt
+++ b/Documentation/networking/skfp.txt
@@ -81,7 +81,7 @@
 
 If you run into problems during installation, check those items:
 
-Problem:  The FDDI adapter can not be found by the driver.
+Problem:  The FDDI adapter cannot be found by the driver.
 Reason:   Look in /proc/pci for the following entry:
              'FDDI network controller: SysKonnect SK-FDDI-PCI ...'
 	  If this entry exists, then the FDDI adapter has been
@@ -99,7 +99,7 @@
 
 Problem:  You want to use your computer as a router between
           multiple IP subnetworks (using multiple adapters), but
-	  you can not reach computers in other subnetworks.
+	  you cannot reach computers in other subnetworks.
 Reason:   Either the router's kernel is not configured for IP
 	  forwarding or there is a problem with the routing table
 	  and gateway configuration in at least one of the
diff --git a/Documentation/networking/slicecom.txt b/Documentation/networking/slicecom.txt
index 59cfd95..2f04c92 100644
--- a/Documentation/networking/slicecom.txt
+++ b/Documentation/networking/slicecom.txt
@@ -89,7 +89,7 @@
 
 -	-	no frame-sync, no signal received, or signal SNAFU.
 -	on	"Everything is OK"
-on	on	Recepion is ok, but the remote end sends Remote Alarm
+on	on	Reception is ok, but the remote end sends Remote Alarm
 on	-	The interface is unconfigured
 
 -----------------------------------------------------------------
@@ -257,12 +257,12 @@
 // No alarms - Everything OK
 //
 // LOS  - Loss Of Signal - No signal sensed on the input
-// AIS  - Alarm Indication Signal - The remot side sends '11111111'-s, 
+// AIS  - Alarm Indication Signal - The remote side sends '11111111'-s, 
 //	it tells, that there's an error condition, or it's not
 //	initialised.
 // AUXP - Auxiliary Pattern Indication - 01010101.. received.
 // LFA  - Loss of Frame Alignment - no frame sync received.
-// RRA  - Receive Remote Alarm - the remote end's OK, but singnals error cond.
+// RRA  - Receive Remote Alarm - the remote end's OK, but signals error cond.
 // LMFA - Loss of CRC4 Multiframe Alignment - no CRC4 multiframe sync.
 // NMF  - No Multiframe alignment Found after 400 msec - no such alarm using
 //	no-crc4 or crc4 framing, see below.
@@ -364,6 +364,6 @@
 
 	# echo >lbireg 0x1d 0x21
 
-		- Swithing the loop off:
+		- Switching the loop off:
 
 	# echo >lbireg 0x1d 0x00
diff --git a/Documentation/networking/smctr.txt b/Documentation/networking/smctr.txt
index 4c866f5..9af25b8 100644
--- a/Documentation/networking/smctr.txt
+++ b/Documentation/networking/smctr.txt
@@ -11,7 +11,7 @@
 in the kernel configuration. A choice for SMC Token Ring adapters will
 appear. This drives supports all SMC ISA/MCA adapters. Choose this
 option. I personally recommend compiling the driver as a module (M), but if you
-you would like to compile it staticly answer Y instead.
+you would like to compile it statically answer Y instead.
 
 This driver supports multiple adapters without the need to load multiple copies
 of the driver. You should be able to load up to 7 adapters without any kernel
diff --git a/Documentation/networking/tcp.txt b/Documentation/networking/tcp.txt
index 0fa3004..0121edc 100644
--- a/Documentation/networking/tcp.txt
+++ b/Documentation/networking/tcp.txt
@@ -62,7 +62,7 @@
 unknown congestion method, then the sysctl attempt will fail.
 
 If you remove a tcp congestion control module, then you will get the next
-available one. Since reno can not be built as a module, and can not be
+available one. Since reno cannot be built as a module, and cannot be
 deleted, it will always be available.
 
 How the new TCP output machine [nyi] works.
diff --git a/Documentation/networking/tms380tr.txt b/Documentation/networking/tms380tr.txt
index 179e527..c169a57 100644
--- a/Documentation/networking/tms380tr.txt
+++ b/Documentation/networking/tms380tr.txt
@@ -24,7 +24,7 @@
 in the kernel configuration. A choice for SysKonnect Token Ring adapters will
 appear. This drives supports all SysKonnect ISA and PCI adapters. Choose this
 option. I personally recommend compiling the driver as a module (M), but if you
-you would like to compile it staticly answer Y instead.
+you would like to compile it statically answer Y instead.
 
 This driver supports multiple adapters without the need to load multiple copies
 of the driver. You should be able to load up to 7 adapters without any kernel
diff --git a/Documentation/networking/vortex.txt b/Documentation/networking/vortex.txt
index 6091e5f..6356d3f 100644
--- a/Documentation/networking/vortex.txt
+++ b/Documentation/networking/vortex.txt
@@ -359,13 +359,13 @@
 
    Eliminate some variables: try different cards, different
    computers, different cables, different ports on the switch/hub,
-   different versions of the kernel or ofthe driver, etc.
+   different versions of the kernel or of the driver, etc.
 
 - OK, it's a driver problem.
 
    You need to generate a report.  Typically this is an email to the
    maintainer and/or linux-net@vger.kernel.org.  The maintainer's
-   email address will be inthe driver source or in the MAINTAINERS file.
+   email address will be in the driver source or in the MAINTAINERS file.
 
 - The contents of your report will vary a lot depending upon the
   problem.  If it's a kernel crash then you should refer to the
diff --git a/Documentation/networking/wan-router.txt b/Documentation/networking/wan-router.txt
index c96897a..0cf6541 100644
--- a/Documentation/networking/wan-router.txt
+++ b/Documentation/networking/wan-router.txt
@@ -148,7 +148,7 @@
 		for async connections.
 
 	o Added the PPPCONFIG utility
-		Used to configure the PPPD dameon for the
+		Used to configure the PPPD daemon for the
 		WANPIPE Async PPP and standard serial port.
 		The wancfg calls the pppconfig to configure
 		the pppd.
@@ -214,7 +214,7 @@
 /usr/local/wanrouter/patches/kdrivers:
 	Sources of the latest WANPIPE device drivers.
 	These are used to UPGRADE the linux kernel to the newest
-	version if the kernel source has already been pathced with
+	version if the kernel source has already been patched with
 	WANPIPE drivers.
 
 /usr/local/wanrouter/samples:
@@ -350,7 +350,7 @@
 				 Available as a patch.                 
 
 2.0.6   Aug 17, 1999		Increased debugging in statup scripts
-				Fixed insallation bugs from 2.0.5
+				Fixed installation bugs from 2.0.5
 				Kernel patch works for both 2.2.10 and 2.2.11 kernels.
 				There is no functional difference between the two packages         
 
@@ -434,11 +434,11 @@
 				  change. 
 	  
 beta1-2.1.5 	Nov 15 2000
-				o Fixed the MulitPort PPP Support for kernels 2.2.16 and above.
+				o Fixed the MultiPort PPP Support for kernels 2.2.16 and above.
 				  2.2.X kernels only
 
 				o Secured the driver UDP debugging calls
-					- All illegal netowrk debugging calls are reported to
+					- All illegal network debugging calls are reported to
 					  the log.
 					- Defined a set of allowed commands, all other denied.
 					
@@ -451,7 +451,7 @@
 
 				o Keyboard Led Monitor/Debugger
 					- A new utilty /usr/sbin/wpkbdmon uses keyboard leds
-					  to convey operatinal statistic information of the 
+					  to convey operational statistic information of the 
 					  Sangoma WANPIPE cards.
 					NUM_LOCK    = Line State  (On=connected,    Off=disconnected)
 					CAPS_LOCK   = Tx data     (On=transmitting, Off=no tx data)
@@ -470,7 +470,7 @@
 				o Fixed the Frame Relay and Chdlc network interfaces so they are
 				  compatible with libpcap libraries.  Meaning, tcpdump, snort,
 				  ethereal, and all other packet sniffers and debuggers work on
-				  all WANPIPE netowrk interfaces.
+				  all WANPIPE network interfaces.
 					- Set the network interface encoding type to ARPHRD_PPP.
 					  This tell the sniffers that data obtained from the
 					  network interface is in pure IP format.
@@ -570,7 +570,7 @@
 
 				Option to COMPILE WANPIPE modules against the currently 
 				running kernel, thus no need for manual kernel and module
-				re-compilatin.
+				re-compilation.
 			
 			o Updates and Bug Fixes to wancfg utility.
 
diff --git a/Documentation/nfsroot.txt b/Documentation/nfsroot.txt
index 3cc953c..719f9a9 100644
--- a/Documentation/nfsroot.txt
+++ b/Documentation/nfsroot.txt
@@ -11,7 +11,7 @@
 In order to use a diskless system, such as an X-terminal or printer server
 for example, it is necessary for the root filesystem to be present on a
 non-disk device. This may be an initramfs (see Documentation/filesystems/
-ramfs-rootfs-initramfs.txt), a ramdisk (see Documenation/initrd.txt) or a
+ramfs-rootfs-initramfs.txt), a ramdisk (see Documentation/initrd.txt) or a
 filesystem mounted via NFS. The following text describes on how to use NFS
 for the root filesystem. For the rest of this text 'client' means the
 diskless system, and 'server' means the NFS server.
diff --git a/Documentation/pci-error-recovery.txt b/Documentation/pci-error-recovery.txt
index 634d3e5..6650af4 100644
--- a/Documentation/pci-error-recovery.txt
+++ b/Documentation/pci-error-recovery.txt
@@ -172,7 +172,7 @@
 >>> a value of 0xff on read, and writes will be dropped. If the device
 >>> driver attempts more than 10K I/O's to a frozen adapter, it will
 >>> assume that the device driver has gone into an infinite loop, and
->>> it will panic the the kernel. There doesn't seem to be any other
+>>> it will panic the kernel. There doesn't seem to be any other
 >>> way of stopping a device driver that insists on spinning on I/O.
 
 STEP 2: MMIO Enabled
diff --git a/Documentation/pi-futex.txt b/Documentation/pi-futex.txt
index 5d61dac..9a5bc86 100644
--- a/Documentation/pi-futex.txt
+++ b/Documentation/pi-futex.txt
@@ -118,4 +118,4 @@
 robust-futex, PI-futex, robust+PI-futex.
 
 More details about priority inheritance can be found in
-Documentation/rtmutex.txt.
+Documentation/rt-mutex.txt.
diff --git a/Documentation/pm.txt b/Documentation/pm.txt
index 79c0f32..da8589a 100644
--- a/Documentation/pm.txt
+++ b/Documentation/pm.txt
@@ -18,10 +18,10 @@
 ACPI driver will override and disable APM, otherwise the APM driver
 will be used.
 
-No sorry, you can not have both ACPI and APM enabled and running at
+No, sorry, you cannot have both ACPI and APM enabled and running at
 once.  Some people with broken ACPI or broken APM implementations
 would like to use both to get a full set of working features, but you
-simply can not mix and match the two.  Only one power management
+simply cannot mix and match the two.  Only one power management
 interface can be in control of the machine at once.  Think about it..
 
 User-space Daemons
@@ -106,7 +106,7 @@
  *
  * Returns: 0 if the request is successful
  *          EINVAL if the request is not supported
- *          EBUSY if the device is now busy and can not handle the request
+ *          EBUSY if the device is now busy and cannot handle the request
  *          ENOMEM if the device was unable to handle the request due to memory
  *          
  * Details: The device request callback will be called before the
diff --git a/Documentation/pnp.txt b/Documentation/pnp.txt
index 9529c9c..9ff966b 100644
--- a/Documentation/pnp.txt
+++ b/Documentation/pnp.txt
@@ -222,7 +222,7 @@
 	.remove		= serial_pnp_remove,
 };
 
-* name and id_table can not be NULL.
+* name and id_table cannot be NULL.
 
 4.) register the driver
 ex:
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt
index 73fc87e..24edf25 100644
--- a/Documentation/power/pci.txt
+++ b/Documentation/power/pci.txt
@@ -326,7 +326,7 @@
 
 This is a typical implementation. Drivers can slightly change the order
 of the operations in the implementation, ignore some operations or add
-more deriver specific operations in it, but drivers should do something like
+more driver specific operations in it, but drivers should do something like
 this on the whole.
 
 5. Resources
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
index 823b2cf..9ea2208 100644
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -156,7 +156,7 @@
 be very carefull).
 
 
-Q: What is the difference between between "platform", "shutdown" and
+Q: What is the difference between "platform", "shutdown" and
 "firmware" in /sys/power/disk?
 
 A:
@@ -175,8 +175,8 @@
 Q: I do not understand why you have such strong objections to idea of
 selective suspend.
 
-A: Do selective suspend during runtime power managment, that's okay. But
-its useless for suspend-to-disk. (And I do not see how you could use
+A: Do selective suspend during runtime power management, that's okay. But
+it's useless for suspend-to-disk. (And I do not see how you could use
 it for suspend-to-ram, I hope you do not want that).
 
 Lets see, so you suggest to
@@ -211,7 +211,7 @@
 For devices like disk it does matter, you do not want to spindown for
 FREEZE.
 
-Q: After resuming, system is paging heavilly, leading to very bad interactivity.
+Q: After resuming, system is paging heavily, leading to very bad interactivity.
 
 A: Try running
 
diff --git a/Documentation/power/tricks.txt b/Documentation/power/tricks.txt
index c6d58d3..3b26bb5 100644
--- a/Documentation/power/tricks.txt
+++ b/Documentation/power/tricks.txt
@@ -9,7 +9,7 @@
 
 * turn off APIC and preempt
 
-* use ext2. At least it has working fsck. [If something seemes to go
+* use ext2. At least it has working fsck. [If something seems to go
   wrong, force fsck when you have a chance]
 
 * turn off modules
diff --git a/Documentation/power/userland-swsusp.txt b/Documentation/power/userland-swsusp.txt
index 9405822..64755e9 100644
--- a/Documentation/power/userland-swsusp.txt
+++ b/Documentation/power/userland-swsusp.txt
@@ -91,7 +91,7 @@
 still frozen when the device is being closed).
 
 Currently it is assumed that the userland utilities reading/writing the
-snapshot image from/to the kernel will use a swap parition, called the resume
+snapshot image from/to the kernel will use a swap partition, called the resume
 partition, as storage space.  However, this is not really required, as they
 can use, for example, a special (blank) suspend partition or a file on a partition
 that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and mounted afterwards.
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt
index d859faa..2b35849 100644
--- a/Documentation/power/video.txt
+++ b/Documentation/power/video.txt
@@ -16,7 +16,7 @@
 that.
 
 We either have to run video BIOS during early resume, or interpret it
-using vbetool later, or maybe nothing is neccessary on particular
+using vbetool later, or maybe nothing is necessary on particular
 system because video state is preserved. Unfortunately different
 methods work on different systems, and no known method suits all of
 them.
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 5c0ba23..27b457c 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -145,7 +145,7 @@
                 in case you are entering the kernel with MMU enabled
                 and a non-1:1 mapping.
 
-                r5 : NULL (as to differenciate with method a)
+                r5 : NULL (as to differentiate with method a)
 
         Note about SMP entry: Either your firmware puts your other
         CPUs in some sleep loop or spin loop in ROM where you can get
@@ -245,7 +245,7 @@
 ---------
 
    The kernel is entered with r3 pointing to an area of memory that is
-   roughtly described in include/asm-powerpc/prom.h by the structure
+   roughly described in include/asm-powerpc/prom.h by the structure
    boot_param_header:
 
 struct boot_param_header {
@@ -335,7 +335,7 @@
      "compact" format for the tree itself that is however not backward
      compatible. You should always generate a structure of the highest
      version defined at the time of your implementation. Currently
-     that is version 16, unless you explicitely aim at being backward
+     that is version 16, unless you explicitly aim at being backward
      compatible.
 
    - last_comp_version
@@ -418,9 +418,9 @@
 format definition (as it is in Open Firmware). Version 0x10 makes it
 optional as it can generate it from the unit name defined below.
 
-There is also a "unit name" that is used to differenciate nodes with
+There is also a "unit name" that is used to differentiate nodes with
 the same name at the same level, it is usually made of the node
-name's, the "@" sign, and a "unit address", which definition is
+names, the "@" sign, and a "unit address", which definition is
 specific to the bus type the node sits on.
 
 The unit name doesn't exist as a property per-se but is included in
@@ -550,11 +550,11 @@
      * [child nodes if any]
      * token OF_DT_END_NODE (that is 0x00000002)
 
-So the node content can be summmarised as a start token, a full path,
-a list of properties, a list of child node and an end token. Every
+So the node content can be summarised as a start token, a full path,
+a list of properties, a list of child nodes, and an end token. Every
 child node is a full node structure itself as defined above.
 
-4) Device tree 'strings" block
+4) Device tree "strings" block
 
 In order to save space, property names, which are generally redundant,
 are stored separately in the "strings" block. This block is simply the
@@ -573,7 +573,7 @@
 the Open Firmware client interface, those properties will be created
 by the trampoline code in the kernel's prom_init() file. For example,
 that's where you'll have to add code to detect your board model and
-set the platform number. However, when using the flatenned device-tree
+set the platform number. However, when using the flattened device-tree
 entry point, there is no prom_init() pass, and thus you have to
 provide those properties yourself.
 
@@ -630,12 +630,11 @@
 prom_parse.c file of the recent kernels for your bus type.
 
 The "reg" property only defines addresses and sizes (if #size-cells
-is
-non-0) within a given bus. In order to translate addresses upward
+is non-0) within a given bus. In order to translate addresses upward
 (that is into parent bus addresses, and possibly into cpu physical
 addresses), all busses must contain a "ranges" property. If the
 "ranges" property is missing at a given level, it's assumed that
-translation isn't possible. The format of the "ranges" proprety for a
+translation isn't possible. The format of the "ranges" property for a
 bus is a list of:
 
 	bus address, parent bus address, size
@@ -689,7 +688,7 @@
 4) Note about node and property names and character set
 -------------------------------------------------------
 
-While open firmware provides more flexibe usage of 8859-1, this
+While open firmware provides more flexible usage of 8859-1, this
 specification enforces more strict rules. Nodes and properties should
 be comprised only of ASCII characters 'a' to 'z', '0' to
 '9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally
@@ -732,12 +731,12 @@
       that typically get driven by the same platform code in the
       kernel, you would use a different "model" property but put a
       value in "compatible". The kernel doesn't directly use that
-      value (see /chosen/linux,platform for how the kernel choses a
+      value (see /chosen/linux,platform for how the kernel chooses a
       platform type) but it is generally useful.
 
   The root node is also generally where you add additional properties
   specific to your board like the serial number if any, that sort of
-  thing. it is recommended that if you add any "custom" property whose
+  thing. It is recommended that if you add any "custom" property whose
   name may clash with standard defined ones, you prefix them with your
   vendor name and a comma.
 
@@ -817,7 +816,7 @@
       your board. It's a list of addresses/sizes concatenated
       together, with the number of cells of each defined by the
       #address-cells and #size-cells of the root node. For example,
-      with both of these properties beeing 2 like in the example given
+      with both of these properties being 2 like in the example given
       earlier, a 970 based machine with 6Gb of RAM could typically
       have a "reg" property here that looks like:
 
@@ -970,7 +969,7 @@
      - "asm": assembly language file. This is a file that can be
        sourced by gas to generate a device-tree "blob". That file can
        then simply be added to your Makefile. Additionally, the
-       assembly file exports some symbols that can be use
+       assembly file exports some symbols that can be used.
 
 
 The syntax of the dtc tool is
@@ -984,10 +983,10 @@
 currently version 3 but that may change in the future to version 16.
 
 Additionally, dtc performs various sanity checks on the tree, like the
-uniqueness of linux,phandle properties, validity of strings, etc...
+uniqueness of linux, phandle properties, validity of strings, etc...
 
 The format of the .dts "source" file is "C" like, supports C and C++
-style commments.
+style comments.
 
 / {
 }
@@ -1069,13 +1068,13 @@
     around. It contains no internal offsets or pointers for this
     purpose.
 
-  - An example of code for iterating nodes & retreiving properties
+  - An example of code for iterating nodes & retrieving properties
     directly from the flattened tree format can be found in the kernel
     file arch/ppc64/kernel/prom.c, look at scan_flat_dt() function,
-    it's usage in early_init_devtree(), and the corresponding various
+    its usage in early_init_devtree(), and the corresponding various
     early_init_dt_scan_*() callbacks. That code can be re-used in a
     GPL bootloader, and as the author of that code, I would be happy
-    do discuss possible free licencing to any vendor who wishes to
+    to discuss possible free licencing to any vendor who wishes to
     integrate all or part of this code into a non-GPL bootloader.
 
 
@@ -1441,6 +1440,258 @@
                descriptor-types-mask = <012b0ebf>;
        };
 
+   h) Board Control and Status (BCSR)
+
+   Required properties:
+
+    - device_type : Should be "board-control"
+    - reg : Offset and length of the register set for the device
+
+    Example:
+
+	bcsr@f8000000 {
+		device_type = "board-control";
+		reg = <f8000000 8000>;
+	};
+
+   i) Freescale QUICC Engine module (QE)
+   This represents qe module that is installed on PowerQUICC II Pro.
+   Hopefully it will merge backward compatibility with CPM/CPM2.
+   Basically, it is a bus of devices, that could act more or less
+   as a complete entity (UCC, USB etc ). All of them should be siblings on
+   the "root" qe node, using the common properties from there.
+   The description below applies to the the qe of MPC8360 and
+   more nodes and properties would be extended in the future.
+
+   i) Root QE device
+
+   Required properties:
+   - device_type : should be "qe";
+   - model : precise model of the QE, Can be "QE", "CPM", or "CPM2"
+   - reg : offset and length of the device registers.
+   - bus-frequency : the clock frequency for QUICC Engine.
+
+   Recommended properties
+   - brg-frequency : the internal clock source frequency for baud-rate
+     generators in Hz.
+
+   Example:
+	qe@e0100000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "qe";
+		model = "QE";
+		ranges = <0 e0100000 00100000>;
+		reg = <e0100000 480>;
+		brg-frequency = <0>;
+		bus-frequency = <179A7B00>;
+	}
+
+
+   ii) SPI (Serial Peripheral Interface)
+
+   Required properties:
+   - device_type : should be "spi".
+   - compatible : should be "fsl_spi".
+   - mode : the spi operation mode, it can be "cpu" or "qe".
+   - reg : Offset and length of the register set for the device
+   - interrupts : <a b> where a is the interrupt number and b is a
+     field that represents an encoding of the sense and level
+     information for the interrupt.  This should be encoded based on
+     the information in section 2) depending on the type of interrupt
+     controller you have.
+   - interrupt-parent : the phandle for the interrupt controller that
+     services interrupts for this device.
+
+   Example:
+	spi@4c0 {
+		device_type = "spi";
+		compatible = "fsl_spi";
+		reg = <4c0 40>;
+		interrupts = <82 0>;
+		interrupt-parent = <700>;
+		mode = "cpu";
+	};
+
+
+   iii) USB (Universal Serial Bus Controller)
+
+   Required properties:
+   - device_type : should be "usb".
+   - compatible : could be "qe_udc" or "fhci-hcd".
+   - mode : the could be "host" or "slave".
+   - reg : Offset and length of the register set for the device
+   - interrupts : <a b> where a is the interrupt number and b is a
+     field that represents an encoding of the sense and level
+     information for the interrupt.  This should be encoded based on
+     the information in section 2) depending on the type of interrupt
+     controller you have.
+   - interrupt-parent : the phandle for the interrupt controller that
+     services interrupts for this device.
+
+   Example(slave):
+	usb@6c0 {
+		device_type = "usb";
+		compatible = "qe_udc";
+		reg = <6c0 40>;
+		interrupts = <8b 0>;
+		interrupt-parent = <700>;
+		mode = "slave";
+	};
+
+
+   iv) UCC (Unified Communications Controllers)
+
+   Required properties:
+   - device_type : should be "network", "hldc", "uart", "transparent"
+    "bisync" or "atm".
+   - compatible : could be "ucc_geth" or "fsl_atm" and so on.
+   - model : should be "UCC".
+   - device-id : the ucc number(1-8), corresponding to UCCx in UM.
+   - reg : Offset and length of the register set for the device
+   - interrupts : <a b> where a is the interrupt number and b is a
+     field that represents an encoding of the sense and level
+     information for the interrupt.  This should be encoded based on
+     the information in section 2) depending on the type of interrupt
+     controller you have.
+   - interrupt-parent : the phandle for the interrupt controller that
+     services interrupts for this device.
+   - pio-handle : The phandle for the Parallel I/O port configuration.
+   - rx-clock : represents the UCC receive clock source.
+     0x00 : clock source is disabled;
+     0x1~0x10 : clock source is BRG1~BRG16 respectively;
+     0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
+   - tx-clock: represents the UCC transmit clock source;
+     0x00 : clock source is disabled;
+     0x1~0x10 : clock source is BRG1~BRG16 respectively;
+     0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
+
+   Required properties for network device_type:
+   - mac-address : list of bytes representing the ethernet address.
+   - phy-handle : The phandle for the PHY connected to this controller.
+
+   Example:
+	ucc@2000 {
+		device_type = "network";
+		compatible = "ucc_geth";
+		model = "UCC";
+		device-id = <1>;
+		reg = <2000 200>;
+		interrupts = <a0 0>;
+		interrupt-parent = <700>;
+		mac-address = [ 00 04 9f 00 23 23 ];
+		rx-clock = "none";
+		tx-clock = "clk9";
+		phy-handle = <212000>;
+		pio-handle = <140001>;
+	};
+
+
+   v) Parallel I/O Ports
+
+   This node configures Parallel I/O ports for CPUs with QE support.
+   The node should reside in the "soc" node of the tree.  For each
+   device that using parallel I/O ports, a child node should be created.
+   See the definition of the Pin configuration nodes below for more
+   information.
+
+   Required properties:
+   - device_type : should be "par_io".
+   - reg : offset to the register set and its length.
+   - num-ports : number of Parallel I/O ports
+
+   Example:
+	par_io@1400 {
+		reg = <1400 100>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		device_type = "par_io";
+		num-ports = <7>;
+		ucc_pin@01 {
+			......
+		};
+
+
+   vi) Pin configuration nodes
+
+   Required properties:
+   - linux,phandle : phandle of this node; likely referenced by a QE
+     device.
+   - pio-map : array of pin configurations.  Each pin is defined by 6
+     integers.  The six numbers are respectively: port, pin, dir,
+     open_drain, assignment, has_irq.
+     - port : port number of the pin; 0-6 represent port A-G in UM.
+     - pin : pin number in the port.
+     - dir : direction of the pin, should encode as follows:
+
+	0 = The pin is disabled
+	1 = The pin is an output
+	2 = The pin is an input
+	3 = The pin is I/O
+
+     - open_drain : indicates the pin is normal or wired-OR:
+
+	0 = The pin is actively driven as an output
+	1 = The pin is an open-drain driver. As an output, the pin is
+	    driven active-low, otherwise it is three-stated.
+
+     - assignment : function number of the pin according to the Pin Assignment
+       tables in User Manual.  Each pin can have up to 4 possible functions in
+       QE and two options for CPM.
+     - has_irq : indicates if the pin is used as source of exteral
+       interrupts.
+
+   Example:
+	ucc_pin@01 {
+		linux,phandle = <140001>;
+		pio-map = <
+		/* port  pin  dir  open_drain  assignment  has_irq */
+			0  3  1  0  1  0 	/* TxD0 */
+			0  4  1  0  1  0 	/* TxD1 */
+			0  5  1  0  1  0 	/* TxD2 */
+			0  6  1  0  1  0 	/* TxD3 */
+			1  6  1  0  3  0 	/* TxD4 */
+			1  7  1  0  1  0 	/* TxD5 */
+			1  9  1  0  2  0 	/* TxD6 */
+			1  a  1  0  2  0 	/* TxD7 */
+			0  9  2  0  1  0 	/* RxD0 */
+			0  a  2  0  1  0 	/* RxD1 */
+			0  b  2  0  1  0 	/* RxD2 */
+			0  c  2  0  1  0 	/* RxD3 */
+			0  d  2  0  1  0 	/* RxD4 */
+			1  1  2  0  2  0 	/* RxD5 */
+			1  0  2  0  2  0 	/* RxD6 */
+			1  4  2  0  2  0 	/* RxD7 */
+			0  7  1  0  1  0 	/* TX_EN */
+			0  8  1  0  1  0 	/* TX_ER */
+			0  f  2  0  1  0 	/* RX_DV */
+			0  10 2  0  1  0 	/* RX_ER */
+			0  0  2  0  1  0 	/* RX_CLK */
+			2  9  1  0  3  0 	/* GTX_CLK - CLK10 */
+			2  8  2  0  1  0>;	/* GTX125 - CLK9 */
+	};
+
+   vii) Multi-User RAM (MURAM)
+
+   Required properties:
+   - device_type : should be "muram".
+   - mode : the could be "host" or "slave".
+   - ranges : Should be defined as specified in 1) to describe the
+      translation of MURAM addresses.
+   - data-only : sub-node which defines the address area under MURAM
+      bus that can be allocated as data/parameter
+
+   Example:
+
+	muram@10000 {
+		device_type = "muram";
+		ranges = <0 00010000 0000c000>;
+
+		data-only@0{
+			reg = <0 c000>;
+		};
+	};
 
    More devices will be defined as this spec matures.
 
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
index 3764dd4..4530d1b 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -90,7 +90,7 @@
 this is the case. If so, then the device driver should put itself
 into a consistent state (given that it won't be able to complete any
 pending work) and start recovery of the card.  Recovery normally
-would consist of reseting the PCI device (holding the PCI #RST
+would consist of resetting the PCI device (holding the PCI #RST
 line high for two seconds), followed by setting up the device
 config space (the base address registers (BAR's), latency timer,
 cache line size, interrupt line, and so on).  This is followed by a
@@ -116,7 +116,7 @@
 so that individual device drivers do not need to be modified to support
 EEH recovery.  This generic mechanism piggy-backs on the PCI hotplug
 infrastructure,  and percolates events up through the userspace/udev
-infrastructure.  Followiing is a detailed description of how this is
+infrastructure.  Following is a detailed description of how this is
 accomplished.
 
 EEH must be enabled in the PHB's very early during the boot process,
diff --git a/Documentation/powerpc/hvcs.txt b/Documentation/powerpc/hvcs.txt
index 1e38166..f93462c 100644
--- a/Documentation/powerpc/hvcs.txt
+++ b/Documentation/powerpc/hvcs.txt
@@ -259,7 +259,7 @@
 
 It should be noted that due to the system hotplug I/O capabilities of a
 system the /dev/hvcs* entry that interacts with a particular vty-server
-adapter is not guarenteed to remain the same across system reboots.  Look
+adapter is not guaranteed to remain the same across system reboots.  Look
 in the Q & A section for more on this issue.
 
 ---------------------------------------------------------------------------
diff --git a/Documentation/prio_tree.txt b/Documentation/prio_tree.txt
index 2fbb0c4..3aa68f9 100644
--- a/Documentation/prio_tree.txt
+++ b/Documentation/prio_tree.txt
@@ -88,7 +88,7 @@
 heap-and-size indexed overflow-sub-trees using prio_tree->index_bits.
 Instead the overflow sub-trees are indexed using full BITS_PER_LONG bits
 of size_index. This may lead to skewed sub-trees because most of the
-higher significant bits of the size_index are likely to be be 0 (zero). In
+higher significant bits of the size_index are likely to be 0 (zero). In
 the example above, all 3 overflow-sub-trees are skewed. This may marginally
 affect the performance. However, processes rarely map many vmas with the
 same start_vm_pgoff but different end_vm_pgoffs. Therefore, we normally
diff --git a/Documentation/rocket.txt b/Documentation/rocket.txt
index a106780..1d85829 100644
--- a/Documentation/rocket.txt
+++ b/Documentation/rocket.txt
@@ -97,7 +97,7 @@
 requires a 68-byte contiguous block of I/O addresses, starting at one
 of the following: 0x100h, 0x140h, 0x180h, 0x200h, 0x240h, 0x280h,
 0x300h, 0x340h, 0x380h.  This I/O address must be reflected in the DIP
-switiches of *all* of the Rocketport cards.
+switches of *all* of the Rocketport cards.
 
 The second, third, and fourth RocketPort cards require a 64-byte
 contiguous block of I/O addresses, starting at one of the following
@@ -107,7 +107,7 @@
 software control.  The DIP switch settings for the I/O address must be
 set to the value of the first Rocketport cards.
 
-In order to destinguish each of the card from the others, each card
+In order to distinguish each of the card from the others, each card
 must have a unique board ID set on the dip switches.  The first
 Rocketport board must be set with the DIP switches corresponding to
 the first board, the second board must be set with the DIP switches
@@ -120,7 +120,7 @@
 RocketPort cards.  Below, you will find a list of commonly used I/O
 address ranges which may be in use by other devices in your system.
 On a Linux system, "cat /proc/ioports" will also be helpful in
-identifying what I/O addresses are being used by devics on your
+identifying what I/O addresses are being used by devices on your
 system.
 
 Remember, the FIRST RocketPort uses 68 I/O addresses.  So, if you set it
diff --git a/Documentation/rpc-cache.txt b/Documentation/rpc-cache.txt
index 5f757c8..8a382be 100644
--- a/Documentation/rpc-cache.txt
+++ b/Documentation/rpc-cache.txt
@@ -24,7 +24,7 @@
    - general cache lookup with correct locking
    - supporting 'NEGATIVE' as well as positive entries
    - allowing an EXPIRED time on cache items, and removing
-     items after they expire, and are no longe in-use.
+     items after they expire, and are no longer in-use.
    - making requests to user-space to fill in cache entries
    - allowing user-space to directly set entries in the cache
    - delaying RPC requests that depend on as-yet incomplete
@@ -53,7 +53,7 @@
 		structure
 	void cache_put(struct kref *)
 		This is called when the last reference to an item is
-		is dropped.  The pointer passed is to the 'ref' field
+		dropped.  The pointer passed is to the 'ref' field
 		in the cache_head.  cache_put should release any
 		references create by 'cache_init' and, if CACHE_VALID
 		is set, any references created by cache_update.
diff --git a/Documentation/s390/3270.txt b/Documentation/s390/3270.txt
index 0a044e6..7a5c73a 100644
--- a/Documentation/s390/3270.txt
+++ b/Documentation/s390/3270.txt
@@ -111,9 +111,7 @@
 	config3270.sh.	Inspect the output script it produces,
 	/tmp/mkdev3270, and then run that script.  This will create the
 	necessary character special device files and make the necessary
-	changes to /etc/inittab.  If you have selected DEVFS, the driver
-	itself creates the device files, and /tmp/mkdev3270 only changes
-	/etc/inittab.
+	changes to /etc/inittab.
 
 	Then notify /sbin/init that /etc/inittab has changed, by issuing
 	the telinit command with the q operand:
diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt
index 844c03f..4dd25ee 100644
--- a/Documentation/s390/Debugging390.txt
+++ b/Documentation/s390/Debugging390.txt
@@ -8,8 +8,8 @@
 Overview of Document:
 =====================
 This document is intended to give an good overview of how to debug 
-Linux for s/390 & z/Architecture it isn't intended as a complete reference & not a
-tutorial on the fundamentals of C & assembly, it dosen't go into
+Linux for s/390 & z/Architecture. It isn't intended as a complete reference & not a
+tutorial on the fundamentals of C & assembly. It doesn't go into
 390 IO in any detail. It is intended to complement the documents in the
 reference section below & any other worthwhile references you get.
 
@@ -88,7 +88,7 @@
 0       0     Reserved ( must be 0 ) otherwise specification exception occurs.
 
 1       1     Program Event Recording 1 PER enabled, 
-	      PER is used to facilititate debugging e.g. single stepping.
+	      PER is used to facilitate debugging e.g. single stepping.
 
 2-4    2-4    Reserved ( must be 0 ). 
 
@@ -163,7 +163,7 @@
                 1         1        64 bit
 
 32             1=31 bit addressing mode 0=24 bit addressing mode (for backward 
-               compatibility ), linux always runs with this bit set to 1
+               compatibility), linux always runs with this bit set to 1
 
 33-64          Instruction address.
       33-63    Reserved must be 0
@@ -188,7 +188,7 @@
 are used by the processor itself for holding such information as exception indications & 
 entry points for exceptions.
 Bytes after 0xc00 hex are used by linux for per processor globals on s/390 & z/Architecture 
-( there is a gap on z/Architecure too currently between 0xc00 & 1000 which linux uses ).
+( there is a gap on z/Architecture too currently between 0xc00 & 1000 which linux uses ).
 The closest thing to this on traditional architectures is the interrupt
 vector table. This is a good thing & does simplify some of the kernel coding
 however it means that we now cannot catch stray NULL pointers in the
@@ -239,7 +239,7 @@
 
 On 390 our limitations & strengths make us slightly different.
 For backward compatibility we are only allowed use 31 bits (2GB)
-of our 32 bit addresses,however, we use entirely separate address 
+of our 32 bit addresses, however, we use entirely separate address 
 spaces for the user & kernel.
 
 This means we can support 2GB of non Extended RAM on s/390, & more
@@ -317,9 +317,9 @@
 defined in linux/include/linux/sched.h
 The S390 on initialisation & resuming of a process on a cpu sets
 the __LC_KERNEL_STACK variable in the spare prefix area for this cpu
-( which we use for per processor globals).
+(which we use for per-processor globals).
 
-The kernel stack pointer is intimately tied with the task stucture for
+The kernel stack pointer is intimately tied with the task structure for
 each processor as follows.
 
                       s/390
@@ -354,7 +354,7 @@
 }
 
 i.e. just anding the current kernel stack pointer with the mask -8192.
-Thankfully because Linux dosen't have support for nested IO interrupts
+Thankfully because Linux doesn't have support for nested IO interrupts
 & our devices have large buffers can survive interrupts being shut for 
 short amounts of time we don't need a separate stack for interrupts.
 
@@ -366,8 +366,8 @@
 Overview:
 ---------
 This is the code that gcc produces at the top & the bottom of
-each function, it usually is fairly consistent & similar from 
-function to function & if you know its layout you can probalby
+each function. It usually is fairly consistent & similar from 
+function to function & if you know its layout you can probably
 make some headway in finding the ultimate cause of a problem
 after a crash without a source level debugger.
 
@@ -394,7 +394,7 @@
 back-chain:
 This is a pointer to the stack pointer before entering a
 framed functions ( see frameless function ) prologue got by 
-deferencing the address of the current stack pointer,
+dereferencing the address of the current stack pointer,
  i.e. got by accessing the 32 bit value at the stack pointers
 current location.
 
@@ -724,7 +724,7 @@
 1) You can double check whether the files you expect to be included are the ones
 that are being included ( e.g. double check that you aren't going to the i386 asm directory ).
 2) Check that macro definitions aren't clashing with typedefs,
-3) Check that definitons aren't being used before they are being included.
+3) Check that definitions aren't being used before they are being included.
 4) Helps put the line emitting the error under the microscope if it contains macros.
 
 For convenience the Linux kernel's makefile will do preprocessing automatically for you
@@ -840,12 +840,11 @@
 
 A source/assembly mixed dump of the kernel can be done with the line
 objdump --source vmlinux > vmlinux.lst
-Also if the file isn't compiled -g this will output as much debugging information
-as it can ( e.g. function names ), however, this is very slow as it spends lots
-of time searching for debugging info, the following self explanitory line should be used 
-instead if the code isn't compiled -g.
+Also, if the file isn't compiled -g, this will output as much debugging information
+as it can (e.g. function names). This is very slow as it spends lots
+of time searching for debugging info. The following self explanatory line should be used 
+instead if the code isn't compiled -g, as it is much faster:
 objdump --disassemble-all --syms vmlinux > vmlinux.lst  
-as it is much faster
 
 As hard drive space is valuble most of us use the following approach.
 1) Look at the emitted psw on the console to find the crash address in the kernel.
@@ -861,7 +860,7 @@
 6) rm /arch/s390/kernel/signal.o
 7) make /arch/s390/kernel/signal.o
 8) watch the gcc command line emitted
-9) type it in again or alernatively cut & paste it on the console adding the -g option.
+9) type it in again or alternatively cut & paste it on the console adding the -g option.
 10) objdump --source arch/s390/kernel/signal.o > signal.lst
 This will output the source & the assembly intermixed, as the snippet below shows
 This will unfortunately output addresses which aren't the same
@@ -913,8 +912,8 @@
 strace ping -c 1 127.0.0.1  
 & then look at the man pages for each of the syscalls below,
 ( In fact this is sometimes easier than looking at some spagetti
-source which conditionally compiles for several architectures )
-Not everything that it throws out needs to make sense immeadiately
+source which conditionally compiles for several architectures ).
+Not everything that it throws out needs to make sense immediately.
 
 Just looking quickly you can see that it is making up a RAW socket
 for the ICMP protocol.
@@ -974,8 +973,9 @@
 
 Example 3
 ---------
-Getting sophistocated
-telnetd crashes on & I don't know why
+Getting sophisticated
+telnetd crashes & I don't know why
+
 Steps
 -----
 1) Replace the following line in /etc/inetd.conf
@@ -1085,8 +1085,7 @@
 -----
 Addresses & values in the VM debugger are always hex never decimal
 Address ranges are of the format <HexValue1>-<HexValue2> or <HexValue1>.<HexValue2> 
-e.g. The address range  0x2000 to 0x3000 can be described described as
-2000-3000 or 2000.1000
+e.g. The address range  0x2000 to 0x3000 can be described as 2000-3000 or 2000.1000
 
 The VM Debugger is case insensitive.
 
@@ -1311,7 +1310,7 @@
 
 An alternative way of finding the STD of a currently running process 
 is to do the following, ( this method is more complex but
-could be quite convient if you aren't updating the kernel much &
+could be quite convenient if you aren't updating the kernel much &
 so your kernel structures will stay constant for a reasonable period of
 time ).
 
@@ -1413,7 +1412,7 @@
 To find out how many cpus you have
 Q CPUS displays all the CPU's available to your virtual machine
 To find the cpu that the current cpu VM debugger commands are being directed at do
-Q CPU to change the current cpu cpu VM debugger commands are being directed at do
+Q CPU to change the current cpu VM debugger commands are being directed at do
 CPU <desired cpu no>
 
 On a SMP guest issue a command to all CPUs try prefixing the command with cpu all.
@@ -1674,8 +1673,8 @@
 concurrently, you check how the IO went on by issuing a TEST SUBCHANNEL at each interrupt,
 from which you receive an Interruption response block (IRB). If you get channel & device end 
 status in the IRB without channel checks etc. your IO probably went okay. If you didn't you
-probably need a doctorto examine the IRB & extended status word etc.
-If an error occurs more sophistocated control units have a facitity known as
+probably need a doctor to examine the IRB & extended status word etc.
+If an error occurs, more sophistocated control units have a facitity known as
 concurrent sense this means that if an error occurs Extended sense information will
 be presented in the Extended status word in the IRB if not you have to issue a
 subsequent SENSE CCW command after the test subchannel. 
@@ -1704,7 +1703,7 @@
 IOP's can use one or more links ( known as channel paths ) to talk to each 
 IO device. It first checks for path availability & chooses an available one,
 then starts ( & sometimes terminates IO ).
-There are two types of channel path ESCON & the Paralell IO interface.
+There are two types of channel path: ESCON & the Parallel IO interface.
 
 IO devices are attached to control units, control units provide the
 logic to interface the channel paths & channel path IO protocols to 
@@ -1743,11 +1742,11 @@
 
 The 390 IO systems come in 2 flavours the current 390 machines support both
 
-The Older 360 & 370 Interface,sometimes called the paralell I/O interface,
+The Older 360 & 370 Interface,sometimes called the Parallel I/O interface,
 sometimes called Bus-and Tag & sometimes Original Equipment Manufacturers
 Interface (OEMI).
 
-This byte wide paralell channel path/bus has parity & data on the "Bus" cable 
+This byte wide Parallel channel path/bus has parity & data on the "Bus" cable 
 & control lines on the "Tag" cable. These can operate in byte multiplex mode for
 sharing between several slow devices or burst mode & monopolize the channel for the
 whole burst. Upto 256 devices can be addressed  on one of these cables. These cables are
@@ -1777,7 +1776,7 @@
 DASD's direct access storage devices ( otherwise known as hard disks ).
 Tape Drives.
 CTC ( Channel to Channel Adapters ),
-ESCON or Paralell Cables used as a very high speed serial link
+ESCON or Parallel Cables used as a very high speed serial link
 between 2 machines. We use 2 cables under linux to do a bi-directional serial link.
 
 
@@ -1803,8 +1802,8 @@
 OSA  7C14 ON OSA   7C14 SUBCHANNEL = 0002
 OSA  7C15 ON OSA   7C15 SUBCHANNEL = 0003
 
-If you have a guest with certain priviliges you may be able to see devices
-which don't belong to you to avoid this do add the option V.
+If you have a guest with certain privileges you may be able to see devices
+which don't belong to you. To avoid this, add the option V.
 e.g.
 Q V OSA
 
@@ -1837,7 +1836,7 @@
 RECEIVE / LOG TXT A1 ( replace
 8)
 filel & press F11 to look at it
-You should see someting like.
+You should see something like:
 
 00020942' SSCH  B2334000    0048813C    CC 0    SCH 0000    DEV 7C08
           CPA 000FFDF0   PARM 00E2C9C4    KEY 0  FPI C0  LPM 80
@@ -1916,7 +1915,7 @@
 --------
 info registers: displays registers other than floating point.
 info all-registers: displays floating points as well.
-disassemble: dissassembles
+disassemble: disassembles
 e.g.
 disassemble without parameters will disassemble the current function
 disassemble $pc $pc+10 
@@ -1935,7 +1934,7 @@
 
 info breakpoints: shows all current breakpoints
 
-info stack: shows stack back trace ( if this dosent work too well, I'll show you the
+info stack: shows stack back trace ( if this doesn't work too well, I'll show you the
 stacktrace by hand below ).
 
 info locals: displays local variables.
@@ -2045,13 +2044,13 @@
 list:
 e.g.
 list lists current function source
-list 1,10 list first 10 lines of curret file.
+list 1,10 list first 10 lines of current file.
 list test.c:1,10
 
 
 directory:
 Adds directories to be searched for source if gdb cannot find the source.
-(note it is a bit sensititive about slashes ) 
+(note it is a bit sensititive about slashes) 
 e.g. To add the root of the filesystem to the searchpath do
 directory //
 
@@ -2123,9 +2122,9 @@
 
 Disassembling instructions without debug info
 ---------------------------------------------
-gdb typically compains if there is a lack of debugging
-symbols in  the disassemble command with 
-"No function contains specified address." to get around
+gdb typically complains if there is a lack of debugging
+symbols in the disassemble command with 
+"No function contains specified address." To get around
 this do 
 x/<number lines to disassemble>xi <address>
 e.g.
@@ -2184,7 +2183,7 @@
 kill -SIGSEGV <gdb's pid>
 or alternatively use killall -SIGSEGV gdb if you have the killall command.
 Now look at the core dump.
-./gdb ./gdb core
+./gdb core
 Displays the following
 GNU gdb 4.18
 Copyright 1998 Free Software Foundation, Inc.
@@ -2316,7 +2315,7 @@
 /proc/1/mem is the current running processes memory which you
 can read & write to like a file.
 strace uses this sometimes as it is a bit faster than the
-rather inefficent ptrace interface for peeking at DATA.
+rather inefficient ptrace interface for peeking at DATA.
 
 
 cat status 
@@ -2446,7 +2445,7 @@
 + RELSTATUS=release
 + MACHTYPE=i586-pc-linux-gnu   
 
-perl -d <scriptname> runs the perlscript in a fully intercative debugger
+perl -d <scriptname> runs the perlscript in a fully interactive debugger
 <like gdb>.
 Type 'h' in the debugger for help.
 
@@ -2477,7 +2476,7 @@
 additional files, Kerntypes which is built using a patch to the 
 linux kernel sources in the linux root directory & the System.map.
 
-Kerntypes is an an objectfile whose sole purpose in life
+Kerntypes is an objectfile whose sole purpose in life
 is to provide stabs debug info to lcrash, to do this
 Kerntypes is built from kerntypes.c which just includes the most commonly
 referenced header files used when debugging, lcrash can then read the
diff --git a/Documentation/s390/cds.txt b/Documentation/s390/cds.txt
index f0be389..d80e573 100644
--- a/Documentation/s390/cds.txt
+++ b/Documentation/s390/cds.txt
@@ -133,7 +133,7 @@
 In order not to introduce a new I/O concept to the common Linux code,
 Linux/390 preserves the IRQ concept and semantically maps the ESA/390
 subchannels to Linux as IRQs. This allows Linux/390 to support up to 64k
-different IRQs, uniquely representig a single device each.
+different IRQs, uniquely representing a single device each.
 
 Up to kernel 2.4, Linux/390 used to provide interfaces via the IRQ (subchannel).
 For internal use of the common I/O layer, these are still there. However, 
@@ -143,7 +143,7 @@
 of those devices is uniquely defined by a so called subchannel by the ESA/390
 channel subsystem. While the subchannel numbers are system generated, each
 subchannel also takes a user defined attribute, the so called device number.
-Both subchannel number and device number can not exceed 65535. During driverfs
+Both subchannel number and device number cannot exceed 65535. During driverfs
 initialisation, the information about control unit type and device types that 
 imply specific I/O commands (channel command words - CCWs) in order to operate
 the device are gathered. Device drivers can retrieve this set of hardware
@@ -177,11 +177,11 @@
 The function is meant to be called with an irq handler in place; that is,
 at earliest during set_online() processing.
 
-While the request is procesed synchronously, the device interrupt
+While the request is processed synchronously, the device interrupt
 handler is called for final ending status. In case of error situations the
 interrupt handler may recover appropriately. The device irq handler can
 recognize the corresponding interrupts by the interruption parameter be
-0x00524443.The ccw_device must not be locked prior to calling read_dev_chars().
+0x00524443. The ccw_device must not be locked prior to calling read_dev_chars().
 
 The function may be called enabled or disabled.
 
@@ -325,7 +325,7 @@
 
 CCW_FLAG_DC        - data chaining
 CCW_FLAG_CC        - command chaining
-CCW_FLAG_SLI       - suppress incorrct length
+CCW_FLAG_SLI       - suppress incorrect length
 CCW_FLAG_SKIP      - skip
 CCW_FLAG_PCI       - PCI
 CCW_FLAG_IDA       - indirect addressing
@@ -348,7 +348,7 @@
           not online.
 
 When the I/O request completes, the CDS first level interrupt handler will
-accumalate the status in a struct irb and then call the device interrupt handler.
+accumulate the status in a struct irb and then call the device interrupt handler.
 The intparm field will contain the value the device driver has associated with a 
 particular I/O request. If a pending device status was recognized, 
 intparm will be set to 0 (zero). This may happen during I/O initiation or delayed
@@ -433,7 +433,7 @@
 
 The device driver is allowed to issue the next ccw_device_start() call from
 within its interrupt handler already. It is not required to schedule a
-bottom-half, unless an non deterministicly long running error recovery procedure
+bottom-half, unless an non deterministically long running error recovery procedure
 or similar needs to be scheduled. During I/O processing the Linux/390 generic
 I/O device driver support has already obtained the IRQ lock, i.e. the handler
 must not try to obtain it again when calling ccw_device_start() or we end in a
diff --git a/Documentation/s390/crypto/crypto-API.txt b/Documentation/s390/crypto/crypto-API.txt
index 78a7762..29dee79 100644
--- a/Documentation/s390/crypto/crypto-API.txt
+++ b/Documentation/s390/crypto/crypto-API.txt
@@ -61,9 +61,9 @@
 		-> when the sha1 algorithm is requested through the crypto API
 		(which has a module autoloader) the z990 module will be loaded.
 
-TBD:	a userspace module probin mechanism
+TBD:	a userspace module probing mechanism
 	something like 'probe sha1 sha1_z990 sha1' in modprobe.conf
-	-> try module sha1_z990, if it fails to load load standard module sha1
+	-> try module sha1_z990, if it fails to load standard module sha1
 	the 'probe' statement is currently not supported in modprobe.conf
 
 
diff --git a/Documentation/s390/driver-model.txt b/Documentation/s390/driver-model.txt
index efb674e..62c0823 100644
--- a/Documentation/s390/driver-model.txt
+++ b/Documentation/s390/driver-model.txt
@@ -157,7 +157,7 @@
 	* In online state, device detached (CIO_GONE) or last path gone
 	  (CIO_NO_PATH). The driver must return !0 to keep the device; for
 	  return code 0, the device will be deleted as usual (also when no
-	  notify function is registerd). If the driver wants to keep the
+	  notify function is registered). If the driver wants to keep the
 	  device, it is moved into disconnected state.
 	* In disconnected state, device operational again (CIO_OPER). The
 	  common I/O layer performs some sanity checks on device number and
@@ -262,7 +262,7 @@
 -----------
 
 The netiucv driver creates an attribute 'connection' under
-bus/iucv/drivers/netiucv. Piping to this attibute creates a new netiucv
+bus/iucv/drivers/netiucv. Piping to this attribute creates a new netiucv
 connection to the specified host.
 
 Netiucv connections show up under devices/iucv/ as "netiucv<ifnum>". The interface
diff --git a/Documentation/s390/monreader.txt b/Documentation/s390/monreader.txt
index d843bb0..beeaa4b 100644
--- a/Documentation/s390/monreader.txt
+++ b/Documentation/s390/monreader.txt
@@ -83,7 +83,7 @@
 
 NOTE:
 -----
-This API provides no interface to control the *MONITOR service, e.g. specifiy
+This API provides no interface to control the *MONITOR service, e.g. specify
 which data should be collected. This can be done by the CP command MONITOR
 (Class E privileged), see "CP Command and Utility Reference".
 
diff --git a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt
index e321a8e..000230c 100644
--- a/Documentation/s390/s390dbf.txt
+++ b/Documentation/s390/s390dbf.txt
@@ -11,7 +11,7 @@
 (e.g. device drivers) can have one separate debug log.
 One purpose of this is to inspect the debug logs after a production system crash
 in order to analyze the reason for the crash.
-If the system still runs but only a subcomponent which uses dbf failes,
+If the system still runs but only a subcomponent which uses dbf fails,
 it is possible to look at the debug logs on a live system via the Linux
 debugfs filesystem.
 The debug feature may also very useful for kernel and driver development.
@@ -65,7 +65,7 @@
 It is also possible to define other views. The content of
 a view can be inspected simply by reading the corresponding debugfs file.
 
-All debug logs have an an actual debug level (range from 0 to 6).
+All debug logs have an actual debug level (range from 0 to 6).
 The default level is 3. Event and Exception functions have a 'level'
 parameter. Only debug entries with a level that is lower or equal
 than the actual level are written to the log. This means, when
@@ -83,8 +83,8 @@
 It is also possible to deactivate the debug feature globally for every
 debug log. You can change the behavior using  2 sysctl parameters in
 /proc/sys/s390dbf:
-There are currently 2 possible triggers, which stop the  debug feature
-globally. The first possbility is to use the "debug_active" sysctl. If
+There are currently 2 possible triggers, which stop the debug feature
+globally. The first possibility is to use the "debug_active" sysctl. If
 set to 1 the debug feature is running. If "debug_active" is set to 0 the
 debug feature is turned off.
 The second trigger which stops the debug feature is an kernel oops.
@@ -468,7 +468,7 @@
 The raw view returns a bytestream as the debug areas are stored in memory.
 
 The sprintf view formats the debug entries in the same way as the sprintf
-function would do. The sprintf event/expection functions write to the
+function would do. The sprintf event/exception functions write to the
 debug entry a pointer to the format string (size = sizeof(long)) 
 and for each vararg a long value. So e.g. for a debug entry with a format 
 string plus two varargs one would need to allocate a (3 * sizeof(long)) 
@@ -556,7 +556,7 @@
 the view (e.g. like with 'echo "0" > /sys/kernel/debug/s390dbf/dasd/level).
 
 For header_proc there can be used the default function
-debug_dflt_header_fn() which is defined in in debug.h.
+debug_dflt_header_fn() which is defined in debug.h.
 and which produces the same header output as the predefined views.
 E.g:
 00 00964419409:440761 2 - 00 88023ec
diff --git a/Documentation/sched-coding.txt b/Documentation/sched-coding.txt
index 2b75ef67..cbd8db7 100644
--- a/Documentation/sched-coding.txt
+++ b/Documentation/sched-coding.txt
@@ -15,7 +15,7 @@
 void load_balance(runqueue_t *this_rq, int idle)
 	Attempts to pull tasks from one cpu to another to balance cpu usage,
 	if needed.  This method is called explicitly if the runqueues are
-	inbalanced or periodically by the timer tick.  Prior to calling,
+	imbalanced or periodically by the timer tick.  Prior to calling,
 	the current runqueue must be locked and interrupts disabled.
 
 void schedule()
diff --git a/Documentation/sched-design.txt b/Documentation/sched-design.txt
index 9d04e7b..1605bf0 100644
--- a/Documentation/sched-design.txt
+++ b/Documentation/sched-design.txt
@@ -93,9 +93,9 @@
 Design
 ======
 
-the core of the new scheduler are the following mechanizms:
+The core of the new scheduler contains the following mechanisms:
 
- - *two*, priority-ordered 'priority arrays' per CPU. There is an 'active'
+ - *two* priority-ordered 'priority arrays' per CPU. There is an 'active'
    array and an 'expired' array. The active array contains all tasks that
    are affine to this CPU and have timeslices left. The expired array
    contains all tasks which have used up their timeslices - but this array
diff --git a/Documentation/scsi/ChangeLog.1992-1997 b/Documentation/scsi/ChangeLog.1992-1997
index dc88ee2..6faad7e 100644
--- a/Documentation/scsi/ChangeLog.1992-1997
+++ b/Documentation/scsi/ChangeLog.1992-1997
@@ -1214,7 +1214,7 @@
 
 	* sr.c(sr_open): Do not allow opens with write access.
 
-Mon Jul 18 09:51:22 1994 1994  Eric Youngdale  (eric@esp22)
+Mon Jul 18 09:51:22 1994  Eric Youngdale  (eric@esp22)
 
 	* Linux 1.1.31 released.
 
diff --git a/Documentation/scsi/NinjaSCSI.txt b/Documentation/scsi/NinjaSCSI.txt
index 041780f..3229b64 100644
--- a/Documentation/scsi/NinjaSCSI.txt
+++ b/Documentation/scsi/NinjaSCSI.txt
@@ -24,7 +24,7 @@
     You can also use "cardctl" program (this program is in pcmcia-cs source
     code) to get more info.
 
-# cat /var/log/messgaes
+# cat /var/log/messages
 ...
 Jan  2 03:45:06 lindberg cardmgr[78]: unsupported card in socket 1
 Jan  2 03:45:06 lindberg cardmgr[78]:   product info: "WBT", "NinjaSCSI-3", "R1.0"
@@ -36,18 +36,18 @@
   product info: "IO DATA", "CBSC16       ", "1"
 
 
-[2] Get Linux kernel source, and extract it to /usr/src.
-    Because NinjaSCSI driver requiers some SCSI header files in Linux kernel
-    source.
-    I recomend rebuilding your kernel. This eliminate some versioning problem.
+[2] Get the Linux kernel source, and extract it to /usr/src.
+    Because the NinjaSCSI driver requires some SCSI header files in Linux 
+    kernel source, I recommend rebuilding your kernel; this eliminates 
+    some versioning problems.
 $ cd /usr/src
 $ tar -zxvf linux-x.x.x.tar.gz
 $ cd linux
 $ make config
 ...
 
-[3] If you use this driver with Kernel 2.2, Unpack pcmcia-cs in some directory
-    and make & install. This driver requies pcmcia-cs header file.
+[3] If you use this driver with Kernel 2.2, unpack pcmcia-cs in some directory
+    and make & install. This driver requires the pcmcia-cs header file.
 $ cd /usr/src
 $ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz
 ...
@@ -59,10 +59,10 @@
 ...
 $ make
 
-[5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
+[5] Copy nsp_cs.ko to suitable place, like /lib/modules/<Kernel version>/pcmcia/ .
 
 [6] Add these lines to /etc/pcmcia/config .
-    If you yse pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
+    If you use pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
     So, you don't need to edit file. Just copy to /etc/pcmcia/ .
 
 -------------------------------------
diff --git a/Documentation/scsi/aacraid.txt b/Documentation/scsi/aacraid.txt
index ee03678..3367130 100644
--- a/Documentation/scsi/aacraid.txt
+++ b/Documentation/scsi/aacraid.txt
@@ -4,7 +4,7 @@
 -------------------------
 The aacraid driver adds support for Adaptec (http://www.adaptec.com)
 RAID controllers. This is a major rewrite from the original
-Adaptec supplied driver. It has signficantly cleaned up both the code
+Adaptec supplied driver. It has significantly cleaned up both the code
 and the running binary size (the module is less than half the size of
 the original).
 
diff --git a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt
index 382b439..904d49e 100644
--- a/Documentation/scsi/aic79xx.txt
+++ b/Documentation/scsi/aic79xx.txt
@@ -81,7 +81,7 @@
           an SDTR with an offset of 0 to be sure the target
           knows we are async.  This works around a firmware defect
           in the Quantum Atlas 10K.
-        - Implement controller susupend and resume.
+        - Implement controller suspend and resume.
         - Clear PCI error state during driver attach so that we
           don't disable memory mapped I/O due to a stray write
           by some other driver probe that occurred before we
@@ -94,7 +94,7 @@
         - Add support for scsi_report_device_reset() found in
           2.5.X kernels.
         - Add 7901B support.
-        - Simplify handling of the packtized lun Rev A workaround.
+        - Simplify handling of the packetized lun Rev A workaround.
         - Correct and simplify handling of the ignore wide residue
           message.  The previous code would fail to report a residual
           if the transaction data length was even and we received
diff --git a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt
index 3481fcd..9b894f1 100644
--- a/Documentation/scsi/aic7xxx.txt
+++ b/Documentation/scsi/aic7xxx.txt
@@ -160,7 +160,7 @@
 
    6.2.34 (May 5th, 2003)
         - Fix locking regression instroduced in 6.2.29 that
-          could cuase a lock order reversal between the io_request_lock
+          could cause a lock order reversal between the io_request_lock
           and our per-softc lock.  This was only possible on RH9,
           SuSE, and kernel.org 2.4.X kernels.
 
diff --git a/Documentation/scsi/aic7xxx_old.txt b/Documentation/scsi/aic7xxx_old.txt
index 79e5ac6..c92f447 100644
--- a/Documentation/scsi/aic7xxx_old.txt
+++ b/Documentation/scsi/aic7xxx_old.txt
@@ -102,7 +102,7 @@
     The hardware RAID devices sold by Adaptec are *NOT* supported by this
     driver (and will people please stop emailing me about them, they are
     a totally separate beast from the bare SCSI controllers and this driver
-    can not be retrofitted in any sane manner to support the hardware RAID
+    cannot be retrofitted in any sane manner to support the hardware RAID
     features on those cards - Doug Ledford).
     
 
@@ -241,7 +241,7 @@
         that instead of dumping the register contents on the card, this
 	option dumps the contents of the sequencer program RAM.  This gives
 	the ability to verify that the instructions downloaded to the
-	card's sequencer are indeed what they are suppossed to be.  Again,
+	card's sequencer are indeed what they are supposed to be.  Again,
 	unless you have documentation to tell you how to interpret these
 	numbers, then it is totally useless.
 	
@@ -317,7 +317,7 @@
 	initial DEVCONFIG values for each of your aic7xxx controllers as
 	they are listed, and also record what the machine is detecting as
 	the proper termination on your controllers.  NOTE: the order in
-	which the initial DEVCONFIG values are printed out is not gauranteed
+	which the initial DEVCONFIG values are printed out is not guaranteed
 	to be the same order as the SCSI controllers are registered.  The
 	above option and this option both work on the order of the SCSI
 	controllers as they are registered, so make sure you match the right
diff --git a/Documentation/scsi/dc395x.txt b/Documentation/scsi/dc395x.txt
index ae3b79a..88219f9 100644
--- a/Documentation/scsi/dc395x.txt
+++ b/Documentation/scsi/dc395x.txt
@@ -20,7 +20,7 @@
 ----------
 The driver uses the settings from the EEPROM set in the SCSI BIOS 
 setup. If there is no EEPROM, the driver uses default values.
-Both can be overriden by command line parameters (module or kernel
+Both can be overridden by command line parameters (module or kernel
 parameters).
 
 The following parameters are available:
diff --git a/Documentation/scsi/dpti.txt b/Documentation/scsi/dpti.txt
index 6e45e70..f36dc0e 100644
--- a/Documentation/scsi/dpti.txt
+++ b/Documentation/scsi/dpti.txt
@@ -48,7 +48,7 @@
  *      Implemented suggestions from Alan Cox
  *      Added calculation of resid for sg layer
  *      Better error handling
- *         Added checking underflow condtions 
+ *         Added checking underflow conditions 
  *         Added DATAPROTECT checking
  *         Changed error return codes
  *         Fixed pointer bug in bus reset routine
diff --git a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt
index d16ce5b..35f6b8e 100644
--- a/Documentation/scsi/ibmmca.txt
+++ b/Documentation/scsi/ibmmca.txt
@@ -229,7 +229,7 @@
 
    In a second step of the driver development, the following improvement has
    been applied: The first approach limited the number of devices to 7, far
-   fewer than the 15 that it could usem then it just maped ldn -> 
+   fewer than the 15 that it could use, then it just mapped ldn -> 
    (ldn/8,ldn%8) for pun,lun.  We ended up with a real mishmash of puns
    and luns, but it all seemed to work.
 
@@ -254,12 +254,12 @@
    device to be existant, but it has no ldn assigned, it gets a ldn out of 7 
    to 14. The numbers are assigned in cyclic order. Therefore it takes 8 
    dynamical reassignments on the SCSI-devices, until a certain device 
-   loses its ldn again. This assures, that dynamical remapping is avoided 
+   loses its ldn again. This assures that dynamical remapping is avoided 
    during intense I/O between up to 15 SCSI-devices (means pun,lun 
-   combinations). A further advantage of this method is, that people who
+   combinations). A further advantage of this method is that people who
    build their kernel without probing on all luns will get what they expect,
    because the driver just won't assign everything with lun>0 when 
-   multpile lun probing is inactive.
+   multiple lun probing is inactive.
  
    2.4 SCSI-Device Order
    ---------------------
@@ -309,9 +309,9 @@
    2.6 Abort & Reset Commands
    --------------------------
    These are implemented with busy waiting for interrupt to arrive.
-   ibmmca_reset() and ibmmca_abort() do not work sufficently well
-   up to now and need still a lot of development work. But, this seems
-   to be even a problem with other SCSI-low level drivers, too. However,
+   ibmmca_reset() and ibmmca_abort() do not work sufficiently well
+   up to now and need still a lot of development work. This seems
+   to be a problem with other low-level SCSI drivers too, however
    this should be no excuse.
 
    2.7 Disk Geometry
@@ -684,8 +684,8 @@
       not like sending commands to non-existing SCSI-devices and will react
       with a command error as a sign of protest. While this error is not
       present on IBM SCSI Adapter w/cache, it appears on IBM Integrated SCSI
-      Adapters. Therefore, I implemented a workarround to forgive those 
-      adapters their protests, but it is marked up in the statisctis, so
+      Adapters. Therefore, I implemented a workaround to forgive those 
+      adapters their protests, but it is marked up in the statistics, so
       after a successful boot, you can see in /proc/scsi/ibmmca/<host_number>
       how often the command errors have been forgiven to the SCSI-subsystem.
       If the number is bigger than 0, you have a SCSI subsystem of older
@@ -778,15 +778,15 @@
 	 not accept this, as they stick quite near to ANSI-SCSI and report
 	 a COMMAND_ERROR message which causes the driver to panic. The main
 	 problem was located around the INQUIRY command. Now, for all the
-	 mentioned commands, the buffersize, sent to the adapter is at 
+	 mentioned commands, the buffersize sent to the adapter is at 
 	 maximum 255 which seems to be a quite reasonable solution. 
-	 TEST_UNIT_READY gets a buffersize of 0 to make sure, that no 
+	 TEST_UNIT_READY gets a buffersize of 0 to make sure that no 
 	 data is transferred in order to avoid any possible command failure.
-      2) On unsuccessful TEST_UNIT_READY, the midlevel-driver has to send
-         a REQUEST_SENSE in order to see, where the problem is located. This
+      2) On unsuccessful TEST_UNIT_READY, the mid-level driver has to send
+         a REQUEST_SENSE in order to see where the problem is located. This
 	 REQUEST_SENSE may have various length in its answer-buffer. IBM
-	 SCSI-subsystems report a command failure, if the returned buffersize
-	 is different from the sent buffersize, but this can be supressed by
+	 SCSI-subsystems report a command failure if the returned buffersize
+	 is different from the sent buffersize, but this can be suppressed by
 	 a special bit, which is now done and problems seem to be solved.
    2) Code adaption to all kernel-releases. Now, the 3.2 code compiles on 
       2.0.x, 2.1.x, 2.2.x and 2.3.x kernel releases without any code-changes.
@@ -1086,7 +1086,7 @@
    
      Q: "Reset SCSI-devices at boottime" halts the system at boottime, why?
      A: This is only tested with the IBM SCSI Adapter w/cache. It is not
-        yet prooved to run on other adapters, however you may be lucky.
+        yet proven to run on other adapters, however you may be lucky.
 	In version 3.1d this has been hugely improved and should work better,
 	now. Normally you really won't need to activate this flag in the
 	kernel configuration, as all post 1989 SCSI-devices should accept
@@ -1104,7 +1104,7 @@
 	The parameter 'normal' sets the new industry standard, starting
 	from pun 0, scanning up to pun 6. This allows you to change your 
 	opinion still after having already compiled the kernel.
-     Q: Why I cannot find the IBM MCA SCSI support in the config menue?
+     Q: Why can't I find IBM MCA SCSI support in the config menu?
      A: You have to activate MCA bus support, first.
      Q: Where can I find the latest info about this driver?
      A: See the file MAINTAINERS for the current WWW-address, which offers
@@ -1156,7 +1156,7 @@
         Guide) what has to be done for reset, we still share the bad shape of
 	the reset functions with all other low level SCSI-drivers. 
 	Astonishingly, reset works in most cases quite ok, but the harddisks
-	won't run in synchonous mode anymore after a reset, until you reboot.
+	won't run in synchronous mode anymore after a reset, until you reboot.
      Q: Why does my XXX w/Cache adapter not use read-prefetch?
      A: Ok, that is not completely possible. If a cache is present, the 
         adapter tries to use it internally. Explicitly, one can use the cache
diff --git a/Documentation/scsi/megaraid.txt b/Documentation/scsi/megaraid.txt
index ff864c0..3c7cea5 100644
--- a/Documentation/scsi/megaraid.txt
+++ b/Documentation/scsi/megaraid.txt
@@ -4,11 +4,11 @@
 Overview:
 --------
 
-Different classes of controllers from LSI Logic, accept and respond to the
+Different classes of controllers from LSI Logic accept and respond to the
 user applications in a similar way. They understand the same firmware control
 commands. Furthermore, the applications also can treat different classes of
 the controllers uniformly. Hence it is logical to have a single module that
-interefaces with the applications on one side and all the low level drivers
+interfaces with the applications on one side and all the low level drivers
 on the other.
 
 The advantages, though obvious, are listed for completeness:
diff --git a/Documentation/scsi/ncr53c8xx.txt b/Documentation/scsi/ncr53c8xx.txt
index 822d2ac..58ad8db 100644
--- a/Documentation/scsi/ncr53c8xx.txt
+++ b/Documentation/scsi/ncr53c8xx.txt
@@ -70,7 +70,7 @@
 15. SCSI problem troubleshooting
       15.1 Problem tracking
       15.2 Understanding hardware error reports
-16. Synchonous transfer negotiation tables
+16. Synchronous transfer negotiation tables
       16.1 Synchronous timings for 53C875 and 53C860 Ultra-SCSI controllers
       16.2 Synchronous timings for fast SCSI-2 53C8XX controllers
 17. Serial NVRAM support (by Richard Waltham)
@@ -96,10 +96,10 @@
 It is now available as a bundle of 2 drivers:
 
 - ncr53c8xx generic driver that supports all the SYM53C8XX family including 
-  the ealiest 810 rev. 1, the latest 896 (2 channel LVD SCSI controller) and
+  the earliest 810 rev. 1, the latest 896 (2 channel LVD SCSI controller) and
   the new 895A (1 channel LVD SCSI controller).
 - sym53c8xx enhanced driver (a.k.a. 896 drivers) that drops support of oldest 
-  chips in order to gain advantage of new features, as LOAD/STORE intructions 
+  chips in order to gain advantage of new features, as LOAD/STORE instructions 
   available since the 810A and hardware phase mismatch available with the 
   896 and the 895A.
 
@@ -207,7 +207,7 @@
 SCRIPTS (avoids the phase mismatch interrupt that stops the SCSI processor 
 until the C code has saved the context of the transfer).
 Implementing this without using LOAD/STORE instructions would be painfull 
-and I did'nt even want to try it.
+and I didn't even want to try it.
 
 The 896 chip supports 64 bit PCI transactions and addressing, while the 
 895A supports 32 bit PCI transactions and 64 bit addressing.
@@ -631,8 +631,8 @@
 
 A boot setup command for the ncr53c8xx (sym53c8xx) driver begins with the 
 driver name "ncr53c8xx="(sym53c8xx). The kernel syntax parser then expects 
-an optionnal list of integers separated with comma followed by an optional 
-list of  comma-separated strings. Example of boot setup command under lilo 
+an optional list of integers separated with comma followed by an optional 
+list of comma-separated strings. Example of boot setup command under lilo 
 prompt:
 
 lilo: linux root=/dev/hda2 ncr53c8xx=tags:4,sync:10,debug:0x200
@@ -778,7 +778,7 @@
   Some scsi boards use a 875 (ultra wide) and only supply narrow connectors.
   If you have connected a wide device with a 50 pins to 68 pins cable 
   converter, any accepted wide negotiation will break further data transfers.
-  In such a case, using "wide:0" in the bootup command will be helpfull. 
+  In such a case, using "wide:0" in the bootup command will be helpful. 
 
 10.2.14 Differential mode
         diff:0	never set up diff mode
@@ -899,7 +899,7 @@
     ncr53c8xx=safe:y,mpar:y
     ncr53c8xx=safe:y
 
-My personnal system works flawlessly with the following equivalent setup:
+My personal system works flawlessly with the following equivalent setup:
 
    ncr53c8xx=mpar:y,spar:y,disc:y,specf:1,fsn:n,ultra:2,fsn:n,revprob:n,verb:1\
              tags:32,sync:12,debug:0,burst:7,led:1,wide:1,settle:2,diff:0,irqm:0
@@ -1151,7 +1151,7 @@
 
 New driver versions are made available separately in order to allow testing 
 changes and new features prior to including them into the linux kernel 
-distribution. The following URL provides informations on latest avalaible 
+distribution. The following URL provides information on latest available 
 patches: 
 
       ftp://ftp.tux.org/pub/people/gerard-roudier/README
@@ -1382,7 +1382,7 @@
 You are not required to decode and understand them, unless you want to help 
 maintain the driver code.
 
-16. Synchonous transfer negotiation tables
+16. Synchronous transfer negotiation tables
 
 Tables below have been created by calling the routine the driver uses
 for synchronisation negotiation timing calculation and chip setting.
diff --git a/Documentation/scsi/osst.txt b/Documentation/scsi/osst.txt
index ce574e7..f536907 100644
--- a/Documentation/scsi/osst.txt
+++ b/Documentation/scsi/osst.txt
@@ -56,8 +56,7 @@
 
 Now, your osst driver is inside the kernel or available as a module,
 depending on your choice during kernel config. You may still need to create
-the device nodes by calling the Makedevs.sh script (see below) manually,
-unless you use a devfs kernel, where this won't be needed.
+the device nodes by calling the Makedevs.sh script (see below) manually.
 
 To load your module, you may use the command 
 modprobe osst
diff --git a/Documentation/scsi/ppa.txt b/Documentation/scsi/ppa.txt
index 5d9223b..067ac39 100644
--- a/Documentation/scsi/ppa.txt
+++ b/Documentation/scsi/ppa.txt
@@ -3,7 +3,7 @@
 General Iomega ZIP drive page for Linux:
 http://www.torque.net/~campbell/
 
-Driver achive for old drivers:
+Driver archive for old drivers:
 http://www.torque.net/~campbell/ppa/
 
 Linux Parport page (parallel port)
diff --git a/Documentation/scsi/scsi-changer.txt b/Documentation/scsi/scsi-changer.txt
index c132687..d74bbd2 100644
--- a/Documentation/scsi/scsi-changer.txt
+++ b/Documentation/scsi/scsi-changer.txt
@@ -31,7 +31,7 @@
   media transport - this one shuffles around the media, i.e. the
                     transport arm.  Also known as "picker".
   storage         - a slot which can hold a media.
-  import/export   - the same as above, but is accessable from outside,
+  import/export   - the same as above, but is accessible from outside,
                     i.e. there the operator (you !) can use this to
                     fill in and remove media from the changer.
 		    Sometimes named "mailslot".
diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
index ce767b9..b964eef 100644
--- a/Documentation/scsi/scsi_eh.txt
+++ b/Documentation/scsi/scsi_eh.txt
@@ -160,7 +160,7 @@
  - Fine-grained EH callbacks
 	LLDD can implement fine-grained EH callbacks and let SCSI
 	midlayer drive error handling and call appropriate callbacks.
-	This will be dicussed further in [2-1].
+	This will be discussed further in [2-1].
 
  - eh_strategy_handler() callback
 	This is one big callback which should perform whole error
@@ -194,7 +194,7 @@
 again.
 
  To achieve these goals, EH performs recovery actions with increasing
-severity.  Some actions are performed by issueing SCSI commands and
+severity.  Some actions are performed by issuing SCSI commands and
 others are performed by invoking one of the following fine-grained
 hostt EH callbacks.  Callbacks may be omitted and omitted ones are
 considered to fail always.
diff --git a/Documentation/scsi/st.txt b/Documentation/scsi/st.txt
index 20e30cf..5ff65b1 100644
--- a/Documentation/scsi/st.txt
+++ b/Documentation/scsi/st.txt
@@ -249,7 +249,7 @@
 
 If the driver is compiled into the kernel, the same parameters can be
 also set using, e.g., the LILO command line. The preferred syntax is
-is to use the same keyword used when loading as module but prepended
+to use the same keyword used when loading as module but prepended
 with 'st.'. For instance, to set the maximum number of scatter/gather
 segments, the parameter 'st.max_sg_segs=xx' should be used (xx is the
 number of scatter/gather segments).
@@ -369,7 +369,7 @@
 		the device dependent address. It is recommended to set
 		this flag unless there are tapes using the device
 		dependent (from the old times) (global)
-	     MT_ST_SYSV sets the SYSV sematics (mode)
+	     MT_ST_SYSV sets the SYSV semantics (mode)
 	     MT_ST_NOWAIT enables immediate mode (i.e., don't wait for
 	        the command to finish) for some commands (e.g., rewind)
 	     MT_ST_DEBUGGING debugging (global; debugging must be
diff --git a/Documentation/scsi/sym53c8xx_2.txt b/Documentation/scsi/sym53c8xx_2.txt
index 7f516cd..26c8a08 100644
--- a/Documentation/scsi/sym53c8xx_2.txt
+++ b/Documentation/scsi/sym53c8xx_2.txt
@@ -67,7 +67,7 @@
 Other drivers files are intended not to depend on the Operating System 
 on which the driver is used.
 
-The history of this driver can be summerized as follows:
+The history of this driver can be summarized as follows:
 
 1993: ncr driver written for 386bsd and FreeBSD by:
           Wolfgang Stanglmeier        <wolf@cologne.de>
@@ -684,7 +684,7 @@
           Contains the setting of timing values for both asynchronous and 
           synchronous data transfers. 
 Field I : SCNTL4 Scsi Control Register 4
-          Only meaninful for 53C1010 Ultra3 controllers.
+          Only meaningful for 53C1010 Ultra3 controllers.
 
 Understanding Fields J, K, L and dumps requires to have good knowledge of 
 SCSI standards, chip cores functionnals and internal driver data structures.
diff --git a/Documentation/scsi/tmscsim.txt b/Documentation/scsi/tmscsim.txt
index df7a02b..8b2168a 100644
--- a/Documentation/scsi/tmscsim.txt
+++ b/Documentation/scsi/tmscsim.txt
@@ -27,7 +27,7 @@
 scsi = SCSI driver, m = AMD (?) as opposed to w for the DC390W/U/F
 (NCR53c8X5, X=2/7) driver. Yes, there was also a driver for the latter,
 tmscsiw, which supported DC390W/U/F adapters. It's not maintained any more,
-as the ncr53c8xx is perfectly supporting these adpaters since some time.
+as the ncr53c8xx is perfectly supporting these adapters since some time.
 
 The driver first appeared in April 1996, exclusively supported the DC390 
 and has been enhanced since then in various steps. In May 1998 support for 
@@ -381,7 +381,7 @@
   replaced by the dev index of your scanner). You may try to reset your SCSI
   bus afterwards (echo "RESET" >/proc/scsi/tmscsim/?).
   The problem seems to be solved as of 2.0d18, thanks to Andreas Rick.
-* If there is a valid partition table, the driver will use it for determing
+* If there is a valid partition table, the driver will use it for determining
   the mapping. If there's none, a reasonable mapping (Symbios-like) will be
   assumed. Other operating systems may not like this mapping, though
   it's consistent with the BIOS' behaviour. Old DC390 drivers ignored the
diff --git a/Documentation/sh/kgdb.txt b/Documentation/sh/kgdb.txt
index 5b04f7f..05b4ba8 100644
--- a/Documentation/sh/kgdb.txt
+++ b/Documentation/sh/kgdb.txt
@@ -69,7 +69,7 @@
 
   kgdb=halt
 
-Boot the TARGET machinem, which will appear to hang. 
+Boot the TARGET machine, which will appear to hang. 
 
 On your DEVELOPMENT machine, cd to the source directory and run the gdb
 program.  (This is likely to be a cross GDB which runs on your host but
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index e6b57dd..138673a 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -57,11 +57,6 @@
 		- Default: 1
 		- For auto-loading more than one card, specify this
 		  option together with snd-card-X aliases.
-    device_mode
-		- permission mask for dynamic sound device filesystem
-		- This is available only when DEVFS is enabled
-		- Default: 0666
-		- E.g.: device_mode=0660
 
   
   Module snd-pcm-oss
@@ -1268,8 +1263,8 @@
 
     Note: on some notebooks the buffer address cannot be detected
     automatically, or causes hang-up during initialization.
-    In such a case, specify the buffer top address explicity via
-    buffer_top option.
+    In such a case, specify the buffer top address explicitly via
+    the buffer_top option.
     For example,
       Sony F250: buffer_top=0x25a800
       Sony F270: buffer_top=0x272800
@@ -1887,7 +1882,7 @@
 # OSS/Free portion
 alias sound-slot-0 snd-interwave
 alias sound-slot-1 snd-ens1371
------ /etc/moprobe.conf
+----- /etc/modprobe.conf
 
 In this example, the interwave card is always loaded as the first card
 (index 0) and ens1371 as the second (index 1).
@@ -1915,21 +1910,6 @@
 options of snd-pcm-oss module.
 
 
-DEVFS support
-=============
-
-The ALSA driver fully supports the devfs extension.
-You should add lines below to your devfsd.conf file:
-
-LOOKUP snd MODLOAD ACTION snd
-REGISTER ^sound/.* PERMISSIONS root.audio 660
-REGISTER ^snd/.* PERMISSIONS root.audio 660
-
-Warning: These lines assume that you have the audio group in your system.
-         Otherwise replace audio word with another group name (root for
-         example).
-
-
 Proc interfaces (/proc/asound)
 ==============================
 
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt
index b535c2a..e40cce8 100644
--- a/Documentation/sound/alsa/Audiophile-Usb.txt
+++ b/Documentation/sound/alsa/Audiophile-Usb.txt
@@ -126,7 +126,7 @@
    - Alsa driver default mode
    - maintains backward compatibility with setups that do not use this 
      parameter by not introducing any change
-   - results sometimes in corrupted sound as decribed earlier
+   - results sometimes in corrupted sound as described earlier
  * device_setup=0x01
    - 16bits 48kHz mode with Di disabled
    - Ai,Ao,Do can be used at the same time
diff --git a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt
index 1872e24..4b2b153 100644
--- a/Documentation/sound/alsa/CMIPCI.txt
+++ b/Documentation/sound/alsa/CMIPCI.txt
@@ -16,11 +16,11 @@
 card#0) for front and 4/6ch playbacks, while the second PCM device
 (hw:0,1) is assigned to the second DAC for rear playback.
 
-There are slight difference between two DACs.
+There are slight differences between the two DACs:
 
 - The first DAC supports U8 and S16LE formats, while the second DAC
   supports only S16LE.
-- The seconde DAC supports only two channel stereo.
+- The second DAC supports only two channel stereo.
 
 Please note that the CM8x38 DAC doesn't support continuous playback
 rate but only fixed rates: 5512, 8000, 11025, 16000, 22050, 32000,
@@ -76,7 +76,7 @@
 
 	% aplay -Dsurround51 sixchannels.wav
 
-For programmin the 4/6 channel playback, you need to specify the PCM
+For programming the 4/6 channel playback, you need to specify the PCM
 channels as you like and set the format S16LE.  For example, for playback
 with 4 channels,
 
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 4807ef7..077fbe2 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -5486,7 +5486,7 @@
   <chapter id="power-management">
     <title>Power Management</title>
     <para>
-      If the chip is supposed to work with with suspend/resume
+      If the chip is supposed to work with suspend/resume
       functions, you need to add the power-management codes to the
       driver. The additional codes for the power-management should be
       <function>ifdef</function>'ed with
diff --git a/Documentation/sound/alsa/MIXART.txt b/Documentation/sound/alsa/MIXART.txt
index 5cb9706..ef42c44 100644
--- a/Documentation/sound/alsa/MIXART.txt
+++ b/Documentation/sound/alsa/MIXART.txt
@@ -31,7 +31,7 @@
 Formats
 -------
 U8, S16_LE, S16_BE, S24_3LE, S24_3BE, FLOAT_LE, FLOAT_BE
-Sample rates : 8000 - 48000 Hz continously
+Sample rates : 8000 - 48000 Hz continuously
 
 Playback
 --------
@@ -39,7 +39,7 @@
 substreams performing hardware mixing. This could be changed to a
 maximum of 24 substreams if wished.
 Mono files will be played on the left and right channel. Each channel
-can be muted for each stream to use 8 analog/digital outputs seperately.
+can be muted for each stream to use 8 analog/digital outputs separately.
 
 Capture
 -------
@@ -97,4 +97,4 @@
 =========
 
 Copyright (c) 2003 Digigram SA <alsa@digigram.com>
-Distributalbe under GPL.
+Distributable under GPL.
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt
index 1fe4884..f738b29 100644
--- a/Documentation/sound/alsa/Procfile.txt
+++ b/Documentation/sound/alsa/Procfile.txt
@@ -71,7 +71,7 @@
 name and the received/transmitted bytes through the MIDI device.
 
 When the card is equipped with AC97 codecs, there are codec97#*
-subdirectories (desribed later).
+subdirectories (described later).
 
 When the OSS mixer emulation is enabled (and the module is loaded),
 oss_mixer file appears here, too.  This shows the current mapping of
@@ -161,12 +161,12 @@
 	Lists the currently available ALSA sequencer drivers.
 
 seq/clients
-	Shows the list of currently available sequencer clinets and
+	Shows the list of currently available sequencer clients and
 	ports.  The connection status and the running status are shown
 	in this file, too.
 
 seq/queues
-	Lists the currently allocated/running sequener queues.
+	Lists the currently allocated/running sequencer queues.
 
 seq/timer
 	Lists the currently allocated/running sequencer timers.
@@ -182,10 +182,10 @@
 mode.  This will give you the kernel messages when and where xrun
 happened.
 
-If it's really a bug, report it with the following information
+If it's really a bug, report it with the following information:
 
   - the name of the driver/card, show in /proc/asound/cards
-  - the reigster dump, if available (e.g. card*/cmipci)
+  - the register dump, if available (e.g. card*/cmipci)
 
 when it's a PCM problem,
 
diff --git a/Documentation/sound/oss/AWE32 b/Documentation/sound/oss/AWE32
deleted file mode 100644
index cb179bf..0000000
--- a/Documentation/sound/oss/AWE32
+++ /dev/null
@@ -1,76 +0,0 @@
-	Installing and using Creative AWE midi sound under Linux.
-
-This documentation is devoted to the Creative Sound Blaster AWE32, AWE64 and 
-SB32.
-
-1) Make sure you have an ORIGINAL Creative SB32, AWE32 or AWE64 card. This
-   is important, because the driver works only with real Creative cards.
-
-2) The first thing you need to do is re-compile your kernel with support for
-   your sound card. Run your favourite tool to configure the kernel and when
-   you get to the "Sound" menu you should enable support for the following:
-
-   Sound card support,
-   OSS sound modules,
-   100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support,
-   AWE32 synth
-
-   If your card is "Plug and Play" you will also need to enable these two
-   options, found under the "Plug and Play configuration" menu:
-
-   Plug and Play support
-   ISA Plug and Play support
-
-   Now compile and install the kernel in normal fashion. If you don't know
-   how to do this you can find instructions for this in the README file
-   located in the root directory of the kernel source.
-
-3) Before you can start playing midi files you will have to load a sound
-   bank file. The utility needed for doing this is called "sfxload", and it
-   is one of the utilities found in a package called "awesfx". If this
-   package is not available in your distribution you can download the AWE
-   snapshot from Creative Labs Open Source website:
-
-   http://www.opensource.creative.com/snapshot.html
-
-   Once you have unpacked the AWE snapshot you will see a "awesfx"
-   directory. Follow the instructions in awesfx/docs/INSTALL to install the
-   utilities in this package. After doing this, sfxload should be installed
-   as:
-
-   /usr/local/bin/sfxload
-
-   To enable AWE general midi synthesis you should also get the sound bank
-   file for general midi from:
-
-   http://members.xoom.com/yar/synthgm.sbk.gz
-
-   Copy it to a directory of your choice, and unpack it there.
-
-4) Edit /etc/modprobe.conf, and insert the following lines at the end of the
-   file:
-
-  alias sound-slot-0 sb
-  alias sound-service-0-1 awe_wave
-  install awe_wave /sbin/modprobe --first-time -i awe_wave && /usr/local/bin/sfxload PATH_TO_SOUND_BANK_FILE
-
-  You will of course have to change "PATH_TO_SOUND_BANK_FILE" to the full
-  path of of the sound bank file. That will enable the Sound Blaster and AWE
-  wave synthesis. To play midi files you should get one of these programs if
-  you don't already have them:
-
-  Playmidi:			http://playmidi.openprojects.net
-
-  AWEMidi Player (drvmidi)  	Included in the previously mentioned AWE
-  				snapshot.
-
-  You will probably have to pass the "-e" switch to playmidi to have it use
-  your midi device. drvmidi should work without switches.
-
-  If something goes wrong please e-mail me. All comments and suggestions are
-  welcome.
-
-		    Yaroslav Rosomakho (alons55@dialup.ptt.ru)
-			    http://www.yar.opennet.ru
-
-Last Updated: Feb 3 2001
diff --git a/Documentation/sound/oss/CMI8338 b/Documentation/sound/oss/CMI8338
deleted file mode 100644
index 387d058..0000000
--- a/Documentation/sound/oss/CMI8338
+++ /dev/null
@@ -1,85 +0,0 @@
-Audio driver for CM8338/CM8738 chips by Chen-Li Tien
-
-
-HARDWARE SUPPORTED
-================================================================================
-C-Media CMI8338
-C-Media CMI8738
-On-board C-Media chips
-
-
-STEPS TO BUILD DRIVER
-================================================================================
-
-  1. Backup the Config.in and Makefile in the sound driver directory
-     (/usr/src/linux/driver/sound).
-     The Configure.help provide help when you config driver in step
-     4, please backup the original one (/usr/src/linux/Document) and
-     copy this file.
-     The cmpci is document for the driver in detail, please copy it
-     to /usr/src/linux/Document/sound so you can refer it. Backup if
-     there is already one.
-
-  2. Extract the tar file by 'tar xvzf cmpci-xx.tar.gz' in the above
-     directory.
-
-  3. Change directory to /usr/src/linux
-
-  4. Config cm8338 driver by 'make menuconfig', 'make config' or
-     'make xconfig' command.
-
-  5. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI
-     driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested.
-     For driver option, please refer 'DRIVER PARAMETER'
-
-  6. Compile the kernel if necessary.
-
-  7. Compile the modules by 'make modules'.
-
-  8. Install the modules by 'make modules_install'
-
-
-INSTALL DRIVER
-================================================================================
-
-  1. Before first time to run the driver, create module dependency by
-     'depmod -a'
-
-  2. To install the driver manually, enter 'modprobe cmpci'.
-
-  3. Driver installation for various distributions:
-
-    a. Slackware 4.0
-       Add the 'modprobe cmpci' command in your /etc/rc.d/rc.modules
-       file.so you can start the driver automatically each time booting.
-
-    b. Caldera OpenLinux 2.2
-       Use LISA to load the cmpci module.
-
-    c. RedHat 6.0 and S.u.S.E. 6.1
-       Add following command in /etc/conf.modules:
-
-       alias sound cmpci
-
-	also visit http://www.cmedia.com.tw for installation instruction.
-
-DRIVER PARAMETER
-================================================================================
-
-  Some functions for the cm8738 can be configured in Kernel Configuration
-  or modules parameters. Set these parameters to 1 to enable.
-
-  mpuio:	I/O ports base for MPU-401, 0 if disabled.
-  fmio:		I/O ports base for OPL-3, 0 if disabled.
-  spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
-		CD-ROM or DVD-ROM.
-  spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
-                directly.
-  speakers:     Number of speakers used.
-  use_line_as_rear:Enable this if you want to use line-in as
-                rear-out.
-  use_line_as_bass:Enable this if you want to use line-in as
-                bass-out.
-  joystick:	Enable joystick. You will need to install Linux joystick
-		driver.
-
diff --git a/Documentation/sound/oss/INSTALL.awe b/Documentation/sound/oss/INSTALL.awe
deleted file mode 100644
index 310f42c..0000000
--- a/Documentation/sound/oss/INSTALL.awe
+++ /dev/null
@@ -1,134 +0,0 @@
-================================================================
-	INSTALLATION OF AWE32 SOUND DRIVER FOR LINUX
-	Takashi Iwai	<iwai@ww.uni-erlangen.de>
-================================================================
-
-----------------------------------------------------------------
-* Attention to SB-PnP Card Users
-
-If you're using PnP cards, the initialization of PnP is required
-before loading this driver.  You have now three options:
-  1. Use isapnptools.
-  2. Use in-kernel isapnp support.
-  3. Initialize PnP on DOS/Windows, then boot linux by loadlin.
-In this document, only the case 1 case is treated.
-
-----------------------------------------------------------------
-* Installation on Red Hat 5.0 Sound Driver
-
-Please use install-rh.sh under RedHat5.0 directory.
-DO NOT USE install.sh below.
-See INSTALL.RH for more details.
-
-----------------------------------------------------------------
-* Installation/Update by Shell Script
-
-  1. Become root
-
-	% su
-
-  2. If you have never configured the kernel tree yet, run make config
-    once (to make dependencies and symlinks).
-
-	# cd /usr/src/linux
-	# make xconfig
-    
-  3. Run install.sh script
-
-	# sh ./install.sh
-
-  4. Configure your kernel
-
-	(for Linux 2.[01].x user)
-	# cd /usr/src/linux
-	# make xconfig (or make menuconfig)
-
-	(for Linux 1.2.x user)
-	# cd /usr/src/linux
-	# make config
-
-    Answer YES to both "lowlevel drivers" and "AWE32 wave synth" items 
-    in Sound menu.  ("lowlevel drivers" will appear only in 2.x
-    kernel.)
-
-  5. Make your kernel (and modules), and install them as usual.
-
-	5a. make kernel image
-		# make zImage
-
-	5b. make modules and install them
-		# make modules && make modules_install
-
-	5c. If you're using lilo, copy the kernel image and run lilo.
-	    Otherwise, copy the kernel image to suitable directory or
-	    media for your system.
-
-  6. Reboot the kernel if necessary.
-	- If you updated only the modules, you don't have to reboot
-	  the system.  Just remove the old sound modules here.
-		in 
-		# rmmod sound.o		(linux-2.0 or OSS/Free)
-		# rmmod awe_wave.o	(linux-2.1)
-
-  7. If your AWE card is a PnP and not initialized yet, you'll have to
-    do it by isapnp tools.  Otherwise, skip to 8.
-
-	This section described only a brief explanation.  For more
-	details, please see the AWE64-Mini-HOWTO or isapnp tools FAQ.
-
-	7a. If you have no isapnp.conf file, generate it by pnpdump.
-	    Otherwise, skip to 7d.
-		# pnpdump > /etc/isapnp.conf
-
-	7b. Edit isapnp.conf file.  Comment out the appropriate
-	    lines containing desirable I/O ports, DMA and IRQs.
-	    Don't forget to enable (ACT Y) line.
-
-	7c. Add two i/o ports (0xA20 and 0xE20) in WaveTable part.
-	    ex)
-		(CONFIGURE CTL0048/58128 (LD 2
-		#     ANSI string -->WaveTable<--
-		  (IO 0 (BASE 0x0620))
-		  (IO 1 (BASE 0x0A20))
-		  (IO 2 (BASE 0x0E20))
-		  (ACT Y)
-		))
-
-	7d. Load the config file.
-	    CAUTION: This will reset all PnP cards!
-
-		# isapnp /etc/isapnp.conf
-
-  8. Load the sound module (if you configured it as a module):
-
-	for 2.0 kernel or OSS/Free monolithic module:
-
-		# modprobe sound.o
-
-	for 2.1 kernel:
-
-		# modprobe sound
-		# insmod uart401
-		# insmod sb io=0x220 irq=5 dma=1 dma16=5 mpu_io=0x330
-		(These values depend on your settings.)
-		# insmod awe_wave
-		(Be sure to load awe_wave after sb!)
-
-		See Documentation/sound/oss/AWE32 for
-		more details.
-
-  9. (only for obsolete systems) If you don't have /dev/sequencer
-     device file, make it according to Readme.linux file on
-     /usr/src/linux/drivers/sound. (Run a shell script included in
-     that file). <-- This file no longer exists in the recent kernels!
-
-  10. OK, load your own soundfont file, and enjoy MIDI!
-
-	% sfxload synthgm.sbk
-	% drvmidi foo.mid
-
-  11. For more advanced use (eg. dynamic loading, virtual bank and
-      etc.), please read the awedrv FAQ or the instructions in awesfx
-      and awemidi packages.
-
-Good luck!
diff --git a/Documentation/sound/oss/MAD16 b/Documentation/sound/oss/MAD16
deleted file mode 100644
index 865dbd8..0000000
--- a/Documentation/sound/oss/MAD16
+++ /dev/null
@@ -1,56 +0,0 @@
-(This recipe has been edited to update the configuration symbols,
- and change over to modprobe.conf for 2.6)
-
-From: Shaw Carruthers <shaw@shawc.demon.co.uk>
-
-I have been using mad16 sound for some time now with no problems, current
-kernel 2.1.89
-
-lsmod shows:
-
-mad16                   5176   0 
-sb                     22044   0  [mad16]
-uart401                 5576   0  [mad16 sb]
-ad1848                 14176   1  [mad16]
-sound                  61928   0  [mad16 sb uart401 ad1848]
-
-.config has:
-
-CONFIG_SOUND=m
-CONFIG_SOUND_ADLIB=m
-CONFIG_SOUND_MAD16=m
-CONFIG_SOUND_YM3812=m
-
-modprobe.conf has:
-
-alias char-major-14-* mad16
-options sb mad16=1
-options mad16 io=0x530 irq=7 dma=0 dma16=1  && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0
-
-
-To get the built in mixer to work this needs to be:
-
-options adlib_card io=0x388     # FM synthesizer
-options sb mad16=1
-options mad16 io=0x530 irq=7 dma=0 dma16=1 mpu_io=816 mpu_irq=5 && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0
-
-The addition of the "mpu_io=816 mpu_irq=5" to the mad16 options line is
-
-------------------------------------------------------------------------
-The mad16 module in addition supports the following options:
-
-option:			meaning:			default:
-joystick=0,1 		disabled, enabled 		disabled
-cdtype=0x00,0x02,0x04,	disabled, Sony CDU31A,		disabled
-       0x06,0x08,0x0a   Mitsumi, Panasonic,
-			Secondary IDE, Primary IDE 
-cdport=0x340,0x320,					0x340
-       0x330,0x360
-cdirq=0,3,5,7,9,10,11 	disabled, IRQ3, ... 		disabled
-cddma=0,5,6,7 		disabled, DMA5, ... 		DMA5 for Mitsumi or IDE
-cddma=0,1,2,3 		disabled, DMA1, ... 		DMA3 for Sony or Panasonic
-opl4=0,1 		OPL3, OPL4 			OPL3	
-
-for more details see linux/drivers/sound/mad16.c
-
-Rui Sousa
diff --git a/Documentation/sound/oss/Maestro b/Documentation/sound/oss/Maestro
deleted file mode 100644
index 4a80eb3..0000000
--- a/Documentation/sound/oss/Maestro
+++ /dev/null
@@ -1,123 +0,0 @@
-	An OSS/Lite Driver for the ESS Maestro family of sound cards
-
-			Zach Brown, December 1999
-
-Driver Status and Availability
-------------------------------
-
-The most recent version of this driver will hopefully always be available at
-	http://www.zabbo.net/maestro/
-
-I will try and maintain the most recent stable version of the driver
-in both the stable and development kernel lines.
-
-ESS Maestro Chip Family
------------------------
-
-There are 3 main variants of the ESS Maestro PCI sound chip.  The first
-is the Maestro 1.  It was originally produced by Platform Tech as the
-'AGOGO'.  It can be recognized by Platform Tech's PCI ID 0x1285 with
-0x0100 as the device ID.  It was put on some sound boards and a few laptops.  
-ESS bought the design and cleaned it up as the Maestro 2.  This starts
-their marking with the ESS vendor ID 0x125D and the 'year' device IDs.
-The Maestro 2 claims 0x1968 while the Maestro 2e has 0x1978.
-
-The various families of Maestro are mostly identical as far as this 
-driver is concerned.  It doesn't touch the DSP parts that differ (though
-it could for FM synthesis).
-
-Driver OSS Behavior
---------------------
-
-This OSS driver exports /dev/mixer and /dev/dsp to applications, which
-mostly adhere to the OSS spec.   This driver doesn't register itself
-with /dev/sndstat, so don't expect information to appear there.
-
-The /dev/dsp device exported behaves almost as expected.  Playback is
-supported in all the various lovely formats.  8/16bit stereo/mono from
-8khz to 48khz, and mmap()ing for playback behaves.  Capture/recording
-is limited due to oddities with the Maestro hardware.  One can only
-record in 16bit stereo.  For recording the maestro uses non interleaved
-stereo buffers so that mmap()ing the incoming data does not result in
-a ring buffer of LRLR data.  mmap()ing of the read buffers is therefore
-disallowed until this can be cleaned up.
-
-/dev/mixer is an interface to the AC'97 codec on the Maestro.  It is
-worth noting that there are a variety of AC'97s that can be wired to
-the Maestro.  Which is used is entirely up to the hardware implementor.
-This should only be visible to the user by the presence, or lack, of
-'Bass' and 'Treble' sliders in the mixer.  Not all AC'97s have them.
-
-The driver doesn't support MIDI or FM playback at the moment.  Typically
-the Maestro is wired to an MPU MIDI chip, but some hardware implementations
-don't.  We need to assemble a white list of hardware implementations that
-have MIDI wired properly before we can claim to support it safely.
-
-Compiling and Installing
-------------------------
-
-With the drivers inclusion into the kernel, compiling and installing
-is the same as most OSS/Lite modular sound drivers.  Compilation
-of the driver is enabled through the CONFIG_SOUND_MAESTRO variable
-in the config system.  
-
-It may be modular or statically linked.  If it is modular it should be
-installed with the rest of the modules for the kernel on the system.
-Typically this will be in /lib/modules/ somewhere.  'alias sound maestro'
-should also be added to your module configs (typically /etc/conf.modules)
-if you're using modular OSS/Lite sound and want to default to using a
-maestro chip.
-
-As this is a PCI device, the module does not need to be informed of
-any IO or IRQ resources it should use, it devines these from the
-system.  Sometimes, on sucky PCs, the BIOS fails to allocated resources
-for the maestro.  This will result in a message like:
-	maestro: PCI subsystem reports IRQ 0, this might not be correct.
-from the kernel.  Should this happen the sound chip most likely will
-not operate correctly.  To solve this one has to dig through their BIOS
-(typically entered by hitting a hot key at boot time) and figure out
-what magic needs to happen so that the BIOS will reward the maestro with
-an IRQ.  This operation is incredibly system specific, so you're on your
-own.  Sometimes the magic lies in 'PNP Capable Operating System' settings.
-
-There are very few options to the driver.  One is 'debug' which will 
-tell the driver to print minimal debugging information as it runs.  This
-can be collected with 'dmesg' or through the klogd daemon.
-
-The other, more interesting option, is 'dsps_order'.  Typically at
-install time the driver will only register one available /dev/dsp device
-for its use.  The 'dsps_order' module parameter allows for more devices
-to be allocated, as a power of two.  Up to 4 devices can be registered
-( dsps_order=2 ).  These devices act as fully distinct units and use
-separate channels in the maestro.
-
-Power Management
-----------------
-
-As of version 0.14, this driver has a minimal understanding of PCI
-Power Management.  If it finds a valid power management capability
-on the PCI device it will attempt to use the power management
-functions of the maestro.  It will only do this on Maestro 2Es and
-only on machines that are known to function well.  You can
-force the use of power management by setting the 'use_pm' module
-option to 1, or can disable it entirely by setting it to 0.
-
-When using power management, the driver does a few things
-differently.  It will keep the chip in a lower power mode
-when the module is inserted but /dev/dsp is not open.  This
-allows the mixer to function but turns off the clocks
-on other parts of the chip.  When /dev/dsp is opened the chip
-is brought into full power mode, and brought back down
-when it is closed.  It also powers down the chip entirely
-when the module is removed or the machine is shutdown.  This
-can have nonobvious consequences.  CD audio may not work
-after a power managing driver is removed.  Also, software that
-doesn't understand power management may not be able to talk
-to the powered down chip until the machine goes through a hard
-reboot to bring it back.
-
-.. more details ..
-------------------
-
-drivers/sound/maestro.c contains comments that hopefully explain
-the maestro implementation.
diff --git a/Documentation/sound/oss/Maestro3 b/Documentation/sound/oss/Maestro3
deleted file mode 100644
index a113718..0000000
--- a/Documentation/sound/oss/Maestro3
+++ /dev/null
@@ -1,92 +0,0 @@
-	An OSS/Lite Driver for the ESS Maestro3 family of sound chips
-
-			Zach Brown, January 2001
-
-Driver Status and Availability
-------------------------------
-
-The most recent version of this driver will hopefully always be available at
-	http://www.zabbo.net/maestro3/
-
-I will try and maintain the most recent stable version of the driver
-in both the stable and development kernel lines.
-
-Historically I've sucked pretty hard at actually doing that, however.
-
-ESS Maestro3 Chip Family
------------------------
-
-The 'Maestro3' is much like the Maestro2 chip.  The noted improvement
-is the removal of the silicon in the '2' that did PCM mixing.  All that
-work is now done through a custom DSP called the ASSP, the Asynchronus
-Specific Signal Processor.
-
-The 'Allegro' is a baby version of the Maestro3.  I'm not entirely clear
-on the extent of the differences, but the driver supports them both :)
-
-The 'Allegro' shows up as PCI ID 0x1988 and the Maestro3 as 0x1998,
-both under ESS's vendor ID of 0x125D.  The Maestro3 can also show up as
-0x199a when hardware strapping is used.
-
-The chip can also act as a multi function device.  The modem IDs follow
-the audio multimedia device IDs.  (so the modem part of an Allegro shows
-up as 0x1989)
-
-Driver OSS Behavior
---------------------
-
-This OSS driver exports /dev/mixer and /dev/dsp to applications, which
-mostly adhere to the OSS spec.   This driver doesn't register itself
-with /dev/sndstat, so don't expect information to appear there.
-
-The /dev/dsp device exported behaves as expected.  Playback is
-supported in all the various lovely formats.  8/16bit stereo/mono from
-8khz to 48khz, with both read()/write(), and mmap().
-
-/dev/mixer is an interface to the AC'97 codec on the Maestro3.  It is
-worth noting that there are a variety of AC'97s that can be wired to
-the Maestro3.  Which is used is entirely up to the hardware implementor.
-This should only be visible to the user by the presence, or lack, of
-'Bass' and 'Treble' sliders in the mixer.  Not all AC'97s have them.
-The Allegro has an onchip AC'97.
-
-The driver doesn't support MIDI or FM playback at the moment.
-
-Compiling and Installing
-------------------------
-
-With the drivers inclusion into the kernel, compiling and installing
-is the same as most OSS/Lite modular sound drivers.  Compilation
-of the driver is enabled through the CONFIG_SOUND_MAESTRO3 variable
-in the config system.  
-
-It may be modular or statically linked.  If it is modular it should be
-installed with the rest of the modules for the kernel on the system.
-Typically this will be in /lib/modules/ somewhere.  'alias sound-slot-0
-maestro3' should also be added to your module configs (typically
-/etc/modprobe.conf) if you're using modular OSS/Lite sound and want to
-default to using a maestro3 chip.
-
-There are very few options to the driver.  One is 'debug' which will 
-tell the driver to print minimal debugging information as it runs.  This
-can be collected with 'dmesg' or through the klogd daemon.
-
-One is 'external_amp', which tells the driver to attempt to enable
-an external amplifier.  This defaults to '1', you can tell the driver
-not to bother enabling such an amplifier by setting it to '0'.
-
-And the last is 'gpio_pin', which tells the driver which GPIO pin number
-the external amp uses (0-15), The Allegro uses 8 by default, all others 1.
-If everything loads correctly and seems to be working but you get no sound, 
-try tweaking this value. 
-
-Systems known to need a different value
-        Panasonic ToughBook CF-72: gpio_pin=13 
-
-Power Management
-----------------
-
-This driver has a minimal understanding of PCI Power Management.  It will
-try and power down the chip when the system is suspended, and power
-it up with it is resumed.  It will also try and power down the chip
-when the machine is shut down.
diff --git a/Documentation/sound/oss/NEWS b/Documentation/sound/oss/NEWS
deleted file mode 100644
index a81e0ef..0000000
--- a/Documentation/sound/oss/NEWS
+++ /dev/null
@@ -1,42 +0,0 @@
-Linux 2.4 Sound Changes
-2000-September-25
-Christoph Hellwig, <hch@infradead.org>
-
-
-
-=== isapnp support
-
-The Linux 2.4 Kernel does have reliable in-kernel isapnp support.
-Some drivers (sb.o, ad1816.o awe_wave.o) do now support automatically
-detecting and configuring isapnp devices.
-If you have a not yet supported isapnp soundcard, mail me the content
-of '/proc/isapnp' on your system and some information about your card
-and its driver(s) so I can try to get isapnp working for it.
-
-
-
-=== soundcard resources on kernel commandline
-
-Before Linux 2.4 you had to specify the resources for sounddrivers
-statically linked into the kernel at compile time
-(in make config/menuconfig/xconfig). In Linux 2.4 the resources are
-now specified at the boot-time kernel commandline (e.g. the lilo
-'append=' line or everything that's after the kernel name in grub).
-Read the Configure.help entry for your card for the parameters.
-
-
-=== softoss is gone
-
-In Linux 2.4 the softoss in-kernel software synthesizer is no more aviable.
-Use a user space software synthesizer like timidity instead.
-
-
-
-=== /dev/sndstat and /proc/sound are gone
-
-In older Linux versions those files exported some information about the
-OSS/Free configuration to userspace. In Linux 2.3 they were removed because
-they did not support the growing number of pci soundcards and there were
-some general problems with this interface.
-
-
diff --git a/Documentation/sound/oss/OPL3-SA b/Documentation/sound/oss/OPL3-SA
deleted file mode 100644
index 66a9183..0000000
--- a/Documentation/sound/oss/OPL3-SA
+++ /dev/null
@@ -1,52 +0,0 @@
-OPL3-SA1 sound driver (opl3sa.o)
-
----
-Note: This howto only describes how to setup the OPL3-SA1 chip; this info
-does not apply to the SA2, SA3, or SA4. 
----
-
-The Yamaha OPL3-SA1 sound chip is usually found built into motherboards, and
-it's a decent little chip offering a WSS mode, a SB Pro emulation mode, MPU401
-and OPL3 FM Synth capabilities.
-
-You can enable inclusion of the driver via CONFIG_SOUND_OPL3SA1=m, or
-CONFIG_SOUND_OPL3SA1=y through 'make config/xconfig/menuconfig'.
-
-You'll need to know all of the relevant info (irq, dma, and io port) for the
-chip's WSS mode, since that is the mode the kernel sound driver uses, and of
-course you'll also need to know about where the MPU401 and OPL3 ports and
-IRQs are if you want to use those.
-
-Here's the skinny on how to load it as a module:
-
-	modprobe opl3sa io=0x530 irq=11 dma=0 dma2=1 mpu_io=0x330 mpu_irq=5
-
-Module options in detail:
-
-	io:	This is the WSS's port base.
-	irq:	This is the WSS's IRQ.
-	dma:	This is the WSS's DMA line. In my BIOS setup screen this was
-		listed as "WSS Play DMA"
-	dma2:	This is the WSS's secondary DMA line. My BIOS calls it the
-		"WSS capture DMA"
-	
-	mpu_io:	This is the MPU401's port base.
-	mpu_irq: This is the MPU401's IRQ.
-
-If you'd like to use the OPL3 FM Synthesizer, make sure you enable
-CONFIG_SOUND_YM3812 (in 'make config'). That'll build the opl3.o module.
-
-Then a simple 'insmod opl3 io=0x388', and you now have FM Synth.
-
-You can also use the SoftOSS software synthesizer instead of the builtin OPL3.
-Here's how:
-
-Say 'y' or 'm' to "SoftOSS software wave table engine" in make config.
-
-If you said yes, the software synth is available once you boot your new
-kernel.
-
-If you chose to build it as a module, just insmod the resulting softoss2.o
-
-Questions? Comments?
-<stiker@northlink.com>
diff --git a/Documentation/sound/oss/README.awe b/Documentation/sound/oss/README.awe
deleted file mode 100644
index 80054cd..0000000
--- a/Documentation/sound/oss/README.awe
+++ /dev/null
@@ -1,218 +0,0 @@
-================================================================
-	AWE32 Sound Driver for Linux / FreeBSD
-		version 0.4.3; Nov. 1, 1998
-
-	Takashi Iwai <iwai@ww.uni-erlangen.de>
-================================================================
-
-* GENERAL NOTES
-
-This is a sound driver extension for SoundBlaster AWE32 and other
-compatible cards (AWE32-PnP, SB32, SB32-PnP, AWE64 & etc) to enable
-the wave synth operations.  The driver is provided for Linux 1.2.x
-and 2.[012].x kernels, as well as FreeBSD, on Intel x86 and DEC
-Alpha systems.
-
-This driver was written by Takashi Iwai <iwai@ww.uni-erlangen.de>,
-and provided "as is".  The original source (awedrv-0.4.3.tar.gz) and
-binary packages are available on the following URL:
-	http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/
-Note that since the author is apart from this web site, the update is
-not frequent now.
-
-
-* NOTE TO LINUX USERS
-
-To enable this driver on linux-2.[01].x kernels, you need turn on 
-"AWE32 synth" options in sound menu when configure your linux kernel
-and modules.  The precise installation procedure is described in the
-AWE64-Mini-HOWTO and linux-kernel/Documetation/sound/AWE32.
-
-If you're using PnP cards, the card must be initialized before loading
-the sound driver.  There're several options to do this:
-    - Initialize the card via ISA PnP tools, and load the sound module.
-    - Initialize the card on DOS, and load linux by loadlin.exe
-    - Use PnP kernel driver (for Linux-2.x.x)
-The detailed instruction for the solution using isapnp tools is found
-in many documents like above.  A brief instruction is also included in
-the installation document of this package.
-For PnP driver project, please refer to the following URL:
-	http://www-jcr.lmh.ox.ac.uk/~pnp/
-
-
-* USING THE DRIVER
-
-The awedrv has several different playing modes to realize easy channel 
-allocation for MIDI songs.  To hear the exact sound quality, you need
-to obtain the extended sequencer program, drvmidi or playmidi-2.5.
-
-For playing MIDI files, you *MUST* load the soundfont file on the
-driver previously by sfxload utility.  Otherwise you'll here no sounds 
-at all!  All the utilities and driver source packages are found in the
-above URL.  The sfxload program is included in the package
-awesfx-0.4.3.tgz.  Binary packages are available there, too.  See the
-instruction in each package for installation.
-
-Loading a soundfont file is very simple.  Just execute the command
-
-	% sfxload synthgm.sbk
-
-Then, sfxload transfers the file "synthgm.sbk" to the driver.
-Both SF1 and SF2 formats are accepted.
-
-Now you can hear midi musics by a midi player.
-
-	% drvmidi foo.mid
-
-If you run MIDI player after MOD player, you need to load soundfont
-files again, since MOD player programs clear the previous loaded
-samples by their own data.
-
-If you have only 512kb on the sound card, I recommend to use dynamic
-sample loading via -L option of drvmidi.  2MB GM/GS soundfont file is
-available in most midi files.
-
-	% sfxload synthgm
-	% drvmidi -L 2mbgmgs foo.mid
-
-This makes a big difference (believe me)!  For more details, please
-refer to the FAQ list which is available on the URL above.
-
-The current chorus, reverb and equalizer status can be changed by
-aweset utility program (included in awesfx package).  Note that
-some awedrv-native programs (like drvmidi and xmp) will change the
-current settings by themselves.  The aweset program is effective
-only for other programs like playmidi.
-
-Enjoy.
-
-
-* COMPILE FLAGS
-
-Compile conditions are defined in awe_config.h.
-
-[Compatibility Conditions]
-The following flags are defined automatically when using installation
-shell script.
-
-- AWE_MODULE_SUPPORT
-    indicates your Linux kernel supports module for each sound card
-    (in recent 2.1 or 2.2 kernels and unofficial patched 2.0 kernels
-    as distributed in the RH5.0 package).
-    This flag is automatically set when you're using 2.1.x kernels.
-    You can pass the base address and memory size via the following
-    module options,
-	io = base I/O port address (eg. 0x620)
-	memsize = DRAM size in kilobytes (eg. 512)
-    As default, AWE driver probes these values automatically.
-
-
-[Hardware Conditions]
-You DON'T have to define the following two values.
-Define them only when the driver couldn't detect the card properly.
-
-- AWE_DEFAULT_BASE_ADDR		(default: not defined)
-    specifies the base port address of your AWE32 card.
-    0 means to autodetect the address.
-
-- AWE_DEFAULT_MEM_SIZE		(default: not defined)
-    specifies the memory size of your AWE32 card in kilobytes.
-    -1 means to autodetect its size.
-    
-
-[Sample Table Size]
-From ver.0.4.0, sample tables are allocated dynamically (except
-Linux-1.2.x system), so you need NOT to touch these parameters.
-Linux-1.2.x users may need to increase these values to appropriate size 
-if the sound card is equipped with more DRAM.
-
-- AWE_MAX_SF_LISTS, AWE_MAX_SAMPLES, AWE_MAX_INFOS
-
-
-[Other Conditions]
-
-- AWE_ALWAYS_INIT_FM		(default: not defined)
-    indicates the AWE driver always initialize FM passthrough even
-    without DRAM on board.  Emu8000 chip has a restriction for playing
-    samples on DRAM that at least two channels must be occupied as
-    passthrough channels. 
-
-- AWE_DEBUG_ON			(default: defined)
-    turns on debugging messages if defined.
-
-- AWE_HAS_GUS_COMPATIBILITY	(default: defined)
-    Enables GUS compatibility mode if defined, reading GUS patches and 
-    GUS control commands.  Define this option to use GMOD or other
-    GUS module players.
-
-- CONFIG_AWE32_MIDIEMU		(default: defined)
-    Adds a MIDI emulation device by Emu8000 wavetable.  The emulation
-    device can be accessed as an external MIDI, and sends the MIDI
-    control codes directly.  XG and GS sysex/NRPN are accepted.
-    No MIDI input is supported.
-
-- CONFIG_AWE32_MIXER		(default: not defined)
-    Adds a mixer device for AWE32 bass/treble equalizer control.
-    You can access this device using /dev/mixer?? (usually mixer01).
-
-- AWE_USE_NEW_VOLUME_CALC	(default: defined)
-    Use the new method to calculate the volume change as compatible
-    with DOS/Win drivers.  This option can be toggled via aweset
-    program, or drvmidi player.
-
-- AWE_CHECK_VTARGET		(default: defined)
-    Check the current volume target value when searching for an
-    empty channel to allocate a new voice.  This is experimentally
-    implemented in this version.  (probably, this option doesn't
-    affect the sound quality severely...)
-
-- AWE_ALLOW_SAMPLE_SHARING	(default: defined)
-   Allow sample sharing for differently loaded patches.
-   This function is available only together with awesfx-0.4.3p3.
-   Note that this is still an experimental option.
-
-- DEF_FM_CHORUS_DEPTH		(default: 0x10)
-    The default strength to be sent to the chorus effect engine.
-    From 0 to 0xff.  Larger numbers may often cause weird sounds.
-
-- DEF_FM_REVERB_DEPTH		(default: 0x10)
-    The default strength to be sent to the reverb effect engine.
-    From 0 to 0xff.  Larger numbers may often cause weird sounds.
-
-
-* ACKNOWLEDGMENTS
-
-Thanks to Witold Jachimczyk (witek@xfactor.wpi.edu) for much advice
-on programming of AWE32.  Much code is brought from his AWE32-native 
-MOD player, ALMP.
-The port of awedrv to FreeBSD is done by Randall Hopper
-(rhh@ct.picker.com).
-The new volume calculation routine was derived from Mark Weaver's
-ADIP compatible routines.
-I also thank linux-awe-ml members for their efforts
-to reboot their system many times :-)
-
-
-* TODO'S
-
-- Complete DOS/Win compatibility
-- DSP-like output
-
-
-* COPYRIGHT
-
-Copyright (C) 1996-1998 Takashi Iwai
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/Documentation/sound/oss/Wavefront b/Documentation/sound/oss/Wavefront
deleted file mode 100644
index 16f57ea..0000000
--- a/Documentation/sound/oss/Wavefront
+++ /dev/null
@@ -1,339 +0,0 @@
-	     An OSS/Free Driver for WaveFront soundcards
-	       (Turtle Beach Maui, Tropez, Tropez Plus)
-
-		     Paul Barton-Davis, July 1998
-
-			  VERSION 0.2.5
-
-Driver Status
--------------
-
-Requires: Kernel 2.1.106 or later (the driver is included with kernels
-2.1.109 and above)
-	  
-As of 7/22/1998, this driver is currently in *BETA* state. This means
-that it compiles and runs, and that I use it on my system (Linux
-2.1.106) with some reasonably demanding applications and uses.  I
-believe the code is approaching an initial "finished" state that
-provides bug-free support for the Tropez Plus.
-
-Please note that to date, the driver has ONLY been tested on a Tropez
-Plus. I would very much like to hear (and help out) people with Tropez
-and Maui cards, since I think the driver can support those cards as
-well. 
-
-Finally, the driver has not been tested (or even compiled) as a static
-(non-modular) part of the kernel. Alan Cox's good work in modularizing
-OSS/Free for Linux makes this rather unnecessary.
-
-Some Questions
---------------
-
-**********************************************************************
-0) What does this driver do that the maui driver did not ?
-**********************************************************************
-
-* can fully initialize a WaveFront card from cold boot - no DOS 
-          utilities needed
-* working patch/sample/program loading and unloading (the maui
-      driver didn't document how to make this work, and assumed
-      user-level preparation of the patch data for writing
-      to the board. ick.)
-* full user-level access to all WaveFront commands
-* for the Tropez Plus, (primitive) control of the YSS225 FX processor
-* Virtual MIDI mode supported - 2 MIDI devices accessible via the
-          WaveFront's MPU401/UART emulation. One
-	  accesses the WaveFront synth, the other accesses the
-	  external MIDI connector. Full MIDI read/write semantics
-	  for both devices.
-* OSS-compliant /dev/sequencer interface for the WaveFront synth,
-	  including native and GUS-format patch downloading.
-* semi-intelligent patch management (prototypical at this point)
-
-**********************************************************************
-1) What to do about MIDI interfaces ?
-**********************************************************************
-
-The Tropez Plus (and perhaps other WF cards) can in theory support up
-to 2 physical MIDI interfaces. One of these is connected to the
-ICS2115 chip (the WaveFront synth itself) and is controlled by
-MPU/UART-401 emulation code running as part of the WaveFront OS.  The
-other is controlled by the CS4232 chip present on the board. However,
-physical access to the CS4232 connector is difficult, and it is
-unlikely (though not impossible) that you will want to use it.
-
-An older version of this driver introduced an additional kernel config
-variable which controlled whether or not the CS4232 MIDI interface was
-configured. Because of Alan Cox's work on modularizing the sound
-drivers, and now backporting them to 2.0.34 kernels, there seems to be
-little reason to support "static" configuration variables, and so this
-has been abandoned in favor of *only* module parameters. Specifying
-"mpuio" and "mpuirq" for the cs4232 parameter will result in the
-CS4232 MIDI interface being configured; leaving them unspecified will
-leave it unconfigured (and thus unusable).
-
-BTW, I have heard from one Tropez+ user that the CS4232 interface is
-more reliable than the ICS2115 one. I have had no problems with the
-latter, and I don't have the right cable to test the former one
-out. Reports welcome.
-
-**********************************************************************
-2) Why does line XXX of the code look like this .... ?
-**********************************************************************
-
-Either because it's not finished yet, or because you're a better coder
-than I am, or because you don't understand some aspect of how the card
-or the code works. 
-
-I absolutely welcome comments, criticisms and suggestions about the
-design and implementation of the driver. 
-
-**********************************************************************
-3) What files are included ?
-**********************************************************************
-
-   drivers/sound/README.wavefront       -- this file
-
-   drivers/sound/wavefront.patch	-- patches for the 2.1.106 sound drivers
-					   needed to make the rest of this work
-				           DO NOT USE IF YOU'VE APPLIED THEM 
-					   BEFORE, OR HAVE 2.1.109 OR ABOVE
-
-   drivers/sound/wavfront.c             -- the driver
-   drivers/sound/ys225.h                -- data declarations for FX config
-   drivers/sound/ys225.c                -- data definitions for FX config
-   drivers/sound/wf_midi.c              -- the "uart401" driver 
-   				              to support virtual MIDI mode.
-   include/wavefront.h                  -- the header file
-   Documentation/sound/oss/Tropez+          -- short docs on configuration
-
-**********************************************************************
-4) How do I compile/install/use it ?
-**********************************************************************
-
-PART ONE: install the source code into your sound driver directory
-
-  cd <top-of-your-2.1.106-code-base-e.g.-/usr/src/linux>
-  tar -zxvf <where-you-put/wavefront.tar.gz>
-
-PART TWO: apply the patches
-
-     DO THIS ONLY IF YOU HAVE A KERNEL VERSION BELOW 2.1.109
-     AND HAVE NOT ALREADY INSTALLED THE PATCH(ES).
-
-  cd drivers/sound
-  patch < wavefront.patch
-
-PART THREE: configure your kernel
-
-  cd <top of your kernel tree>
-  make xconfig (or whichever config option you use)
-
-         - choose YES for Sound Support	      
-         - choose MODULE (M) for OSS Sound Modules
-         - choose MODULE(M) to YM3812/OPL3 support
-	 - choose MODULE(M) for WaveFront support
-	 - choose MODULE(M) for CS4232 support
-
-	 - choose "N" for everything else (unless you have other
-	      soundcards you want support for)
-
-
-   make boot
-   .
-   .
-   .
-   <whatever you normally do for a kernel install>
-   make modules
-   .
-   .
-   .
-   make modules_install
-
-Here's my autoconf.h SOUND section:
-
-/*
- * Sound
- */
-#define CONFIG_SOUND 1
-#undef  CONFIG_SOUND_OSS
-#define CONFIG_SOUND_OSS_MODULE 1
-#undef  CONFIG_SOUND_PAS
-#undef  CONFIG_SOUND_SB
-#undef  CONFIG_SOUND_ADLIB
-#undef  CONFIG_SOUND_GUS
-#undef  CONFIG_SOUND_MPU401
-#undef  CONFIG_SOUND_PSS
-#undef  CONFIG_SOUND_MSS
-#undef  CONFIG_SOUND_SSCAPE
-#undef  CONFIG_SOUND_TRIX
-#undef  CONFIG_SOUND_MAD16
-#undef  CONFIG_SOUND_WAVEFRONT
-#define CONFIG_SOUND_WAVEFRONT_MODULE 1
-#undef  CONFIG_SOUND_CS4232
-#define CONFIG_SOUND_CS4232_MODULE 1
-#undef  CONFIG_SOUND_MAUI
-#undef  CONFIG_SOUND_SGALAXY
-#undef  CONFIG_SOUND_OPL3SA1
-#undef  CONFIG_SOUND_SOFTOSS
-#undef  CONFIG_SOUND_YM3812
-#define CONFIG_SOUND_YM3812_MODULE 1
-#undef  CONFIG_SOUND_VMIDI
-#undef  CONFIG_SOUND_UART6850
-/*
- * Additional low level sound drivers
- */
-#undef  CONFIG_LOWLEVEL_SOUND
-
-************************************************************
-6) How do I configure my card ?
-************************************************************
-
-You need to edit /etc/modprobe.conf. Here's mine (edited to show the
-relevant details):
-
-  # Sound system
-  alias char-major-14-* wavefront
-  alias synth0 wavefront
-  alias mixer0 cs4232
-  alias audio0 cs4232
-  install wavefront /sbin/modprobe cs4232 && /sbin/modprobe -i wavefront && /sbin/modprobe opl3
-  options wavefront io=0x200 irq=9
-  options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
-  options opl3 io=0x388
-
-Things to note: 
-
-       the wavefront options "io" and "irq" ***MUST*** match the "synthio"
-       and "synthirq" cs4232 options.
-
-       you can do without the opl3 module if you don't
-       want to use the OPL/[34] FM synth on the soundcard
-
-       the opl3 io parameter is conventionally not adjustable.
-       In theory, any not-in-use IO port address would work, but
-       just use 0x388 and stick with the crowd.
-
-**********************************************************************
-7) What about firmware ?
-**********************************************************************
-
-Turtle Beach have not given me permission to distribute their firmware
-for the ICS2115. However, if you have a WaveFront card, then you
-almost certainly have the firmware, and if not, its freely available
-on their website, at:
-
-   http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus 
-
-The file is called WFOS2001.MOT (for the Tropez+).
-
-This driver, however, doesn't use the pure firmware as distributed,
-but instead relies on a somewhat processed form of it. You can
-generate this very easily. Following an idea from Andrew Veliath's
-Pinnacle driver, the following flex program will generate the
-processed version:
-
----- cut here -------------------------
-%option main
-%%
-^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext);
-<<EOF>> { fputc ('\0', stdout); return; }
-\n {} 
-.  {}
----- cut here -------------------------
-
-To use it, put the above in file (say, ws.l) compile it like this:
-
-      shell> flex -ows.c ws.l
-      shell> cc -o ws ws.c
-      
-and then use it like this:
-
-    ws < my-copy-of-the-oswf.mot-file > /etc/sound/wavefront.os
-
-If you put it somewhere else, you'll always have to use the wf_ospath
-module parameter (see below) or alter the source code.
-
-**********************************************************************
-7) How do I get it working ?
-**********************************************************************
-
-Optionally, you can reboot with the "new" kernel (even though the only
-changes have really been made to a module).
-
-Then, as root do:
-
-     modprobe wavefront
-
-You should get something like this in /var/log/messages:
-
-    WaveFront: firmware 1.20 already loaded.
-
-or 
-
-    WaveFront: no response to firmware probe, assume raw.
-
-then:
-
-    WaveFront: waiting for memory configuration ...
-    WaveFront: hardware version 1.64
-    WaveFront: available DRAM 8191k
-    WaveFront: 332 samples used (266 real, 13 aliases, 53 multi), 180 empty
-    WaveFront: 128 programs slots in use
-    WaveFront: 256 patch slots filled, 142 in use
-
-The whole process takes about 16 seconds, the longest waits being
-after reporting the hardware version (during the firmware download),
-and after reporting program status (during patch status inquiry).  Its
-shorter (about 10 secs) if the firmware is already loaded (i.e. only
-warm reboots since the last firmware load).
-
-The "available DRAM" line will vary depending on how much added RAM
-your card has. Mine has 8MB.
-
-To check basically functionality, use play(1) or splay(1) to send a
-.WAV or other audio file through the audio portion. Then use playmidi
-to play a General MIDI file. Try the "-D 0" to hear the
-difference between sending MIDI to the WaveFront and using the OPL/3,
-which is the default (I think ...). If you have an external synth(s)
-hooked to the soundcard, you can use "-e" to route to the
-external synth(s) (in theory, -D 1 should work as well, but I think
-there is a bug in playmidi which prevents this from doing what it
-should). 
-
-**********************************************************************
-8) What are the module parameters ?
-**********************************************************************
-
-Its best to read wavefront.c for this, but here is a summary:
-
-integers: 
-	  wf_raw  - if set, ignore apparent presence of firmware
-		    loaded onto the ICS2115, reset the whole
-		    board, and initialize it from scratch. (default = 0)
-
-          fx_raw  - if set, always initialize the YSS225 processor
-		    on the Tropez plus. (default = 1)
-
-          < The next 4 are basically for kernel hackers to allow
-	    tweaking the driver for testing purposes. >		    
-
-          wait_usecs        -  loop timer used when waiting for
-			       status conditions on the board. 
-			       The default is 150.
-
-          debug_default    - debugging flags. See sound/wavefront.h
-			     for WF_DEBUG_* values. Default is zero.
-			     Setting this allows you to debug the
-			     driver during module installation.
-strings:
-	  ospath - path to get to the pre-processed OS firmware.
-		    (default: /etc/sound/wavefront.os)
-
-**********************************************************************
-9) Who should I contact if I have problems?
-**********************************************************************
-
-Just me: Paul Barton-Davis <pbd@op.net>
-
-
diff --git a/Documentation/sound/oss/es1370 b/Documentation/sound/oss/es1370
deleted file mode 100644
index 7b38b1a..0000000
--- a/Documentation/sound/oss/es1370
+++ /dev/null
@@ -1,70 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-This soundcard does not have any hardware MIDI synthesizer;
-MIDI synthesis has to be done in software. To allow this
-the driver/soundcard supports two PCM (/dev/dsp) interfaces.
-The second one goes to the mixer "synth" setting and supports
-only a limited set of sampling rates (44100, 22050, 11025, 5512).
-By setting lineout to 1 on the driver command line
-(eg. insmod es1370 lineout=1) it is even possible on some
-cards to convert the LINEIN jack into a second LINEOUT jack, thus
-making it possible to output four independent audio channels!
-
-There is a freely available software package that allows
-MIDI file playback on this soundcard called Timidity.
-See http://www.cgs.fi/~tt/timidity/.
-
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/sound/oss/rme96xx b/Documentation/sound/oss/rme96xx
deleted file mode 100644
index 87d7b7b..0000000
--- a/Documentation/sound/oss/rme96xx
+++ /dev/null
@@ -1,767 +0,0 @@
-Beta release of the rme96xx (driver for RME 96XX cards like the 
-"Hammerfall" and the "Hammerfall light") 
-
-Important: The driver module has to be installed on a freshly rebooted system, 
-otherwise the driver might not be able to acquire its buffers.
-
-features:
-
- - OSS programming interface (i.e. runs with standard OSS soundsoftware) 
- - OSS/Multichannel interface (OSS multichannel is done by just aquiring
-   more than 2 channels). The driver does not use more than one device 
-   ( yet .. this feature may be implemented later ) 
- - more than one RME card supported
-
-The driver uses a specific multichannel interface, which I will document
-when the driver gets stable. (take a look at the defines in rme96xx.h,
-which adds blocked multichannel formats i.e instead of 
-lrlrlrlr --> llllrrrr  etc.
-
-Use the "rmectrl" programm to look at the status of the card .. 
-or use xrmectrl, a GUI interface for the ctrl program.
-
-What you can do with the rmectrl program is to set the stereo device for
-OSS emulation (e.g. if you use SPDIF out).
-
-You do:
-
-./ctrl offset 24 24
-
-which makes the stereo device use channels 25 and 26.
-
-Guenter Geiger <geiger@epy.co.at>
-
-copy the first part of the attached source code into rmectrl.c
-and the  second part into xrmectrl (or get the program from
-http://gige.xdv.org/pages/soft/pages/rme)
-
-to compile: gcc -o rmectrl rmectrl.c
------------------------------- snip ------------------------------------
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <linux/soundcard.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "rme96xx.h"
-
-/*
-  remctrl.c
-  (C) 2000 Guenter Geiger <geiger@debian.org>
-  HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-*/
-
-/* # define DEVICE_NAME "/dev/mixer" */
-# define DEVICE_NAME "/dev/mixer1"
-
-
-void usage(void)
-{
-     fprintf(stderr,"usage: rmectrl [/dev/mixer<n>] [command [options]]\n\n");
-     fprintf(stderr,"where command is one of:\n");
-     fprintf(stderr,"  help                       show this help\n");
-     fprintf(stderr,"  status                     show status bits\n");
-     fprintf(stderr,"  control                    show control bits\n");
-     fprintf(stderr,"  mix                        show mixer/offset status\n");
-     fprintf(stderr,"  master <n>                 set sync master\n");
-     fprintf(stderr,"  pro <n>                    set spdif out pro\n");
-     fprintf(stderr,"  emphasis <n>               set spdif out emphasis\n");
-     fprintf(stderr,"  dolby <n>                  set spdif out no audio\n");
-     fprintf(stderr,"  optout <n>                 set spdif out optical\n");
-     fprintf(stderr,"  wordclock <n>              set sync wordclock\n");
-     fprintf(stderr,"  spdifin <n>                set spdif in (0=optical,1=coax,2=intern)\n");
-     fprintf(stderr,"  syncref <n>                set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n");
-     fprintf(stderr,"  adat1cd <n>                set ADAT1 on internal CD\n");
-     fprintf(stderr,"  offset <devnr> <in> <out>  set dev (0..3) offset (0..25)\n");
-     exit(-1);
-}
-
-
-int main(int argc, char* argv[])
-{
-     int cards;
-     int ret;
-     int i;
-     double ft;
-     int fd, fdwr;
-     int param,orig;
-     rme_status_t stat;
-     rme_ctrl_t ctrl;
-     char *device;
-     int argidx;
-
-     if (argc < 2)
-	  usage();
-
-     if (*argv[1]=='/') {
-	  device = argv[1];
-	  argidx = 2;
-     }
-     else {
-	  device = DEVICE_NAME;
-	  argidx = 1;
-     }
-
-     fprintf(stdout,"mixer device %s\n",device);
-     if ((fd = open(device,O_RDONLY)) < 0) {
-	  fprintf(stdout,"opening device failed\n");
-	  exit(-1);
-     }
-
-     if ((fdwr = open(device,O_WRONLY)) < 0) {
-	  fprintf(stdout,"opening device failed\n");
-	  exit(-1);
-     }
-
-     if (argc < argidx+1)
-	  usage();
-
-     if (!strcmp(argv[argidx],"help"))
-        usage();
-     if (!strcmp(argv[argidx],"-h"))
-        usage();
-     if (!strcmp(argv[argidx],"--help"))
-        usage();
-
-     if (!strcmp(argv[argidx],"status")) {
-	  ioctl(fd,SOUND_MIXER_PRIVATE2,&stat);
-	  fprintf(stdout,"stat.irq %d\n",stat.irq);
-	  fprintf(stdout,"stat.lockmask %d\n",stat.lockmask);
-	  fprintf(stdout,"stat.sr48 %d\n",stat.sr48);
-	  fprintf(stdout,"stat.wclock %d\n",stat.wclock);
-	  fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint);
-	  fprintf(stdout,"stat.syncmask %d\n",stat.syncmask);
-	  fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed);
-	  fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy);
-	  fprintf(stdout,"stat.tc_out %d\n",stat.tc_out);
-	  fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate);
-	  fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error);
-	  fprintf(stdout,"stat.bufid %d\n",stat.bufid);
-	  fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"control")) {
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  fprintf(stdout,"ctrl.start %d\n",ctrl.start);
-	  fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency);
-	  fprintf(stdout,"ctrl.master %d\n",ctrl.master);
-	  fprintf(stdout,"ctrl.ie %d\n",ctrl.ie);
-	  fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48);
-	  fprintf(stdout,"ctrl.spare %d\n",ctrl.spare);
-	  fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed);
-	  fprintf(stdout,"ctrl.pro %d\n",ctrl.pro);
-	  fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis);
-	  fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby);
-	  fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out);
-	  fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock);
-	  fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in);
-	  fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref);
-	  fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset);
-	  fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select);
-	  fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock);
-	  fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write);
-	  fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"mix")) {
-	  rme_mixer mix;
-	  int i;
-
-	  for (i=0; i<4; i++) {
-	       mix.devnr = i;
-	       ioctl(fd,SOUND_MIXER_PRIVATE1,&mix);
-	       if (mix.devnr == i) {
-		    fprintf(stdout,"devnr %d\n",mix.devnr);
-		    fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset);
-		    fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset);
-	       }
-	  }
-	  exit (0);
-     }
-
-/* the control flags */
-
-     if (argc < argidx+2)
-	  usage();
-
-     if (!strcmp(argv[argidx],"master")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("master = %d\n",val);
-	  ctrl.master = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"pro")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("pro = %d\n",val);
-	  ctrl.pro = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"emphasis")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("emphasis = %d\n",val);
-	  ctrl.emphasis = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"dolby")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("dolby = %d\n",val);
-	  ctrl.dolby = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"optout")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("optout = %d\n",val);
-	  ctrl.opt_out = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"wordclock")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("wordclock = %d\n",val);
-	  ctrl.wordclock = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"spdifin")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("spdifin = %d\n",val);
-	  ctrl.spdif_in = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"syncref")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("syncref = %d\n",val);
-	  ctrl.sync_ref = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"adat1cd")) {
-	  int val = atoi(argv[argidx+1]);
-	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-	  printf("adat1cd = %d\n",val);
-	  ctrl.adat1_cd = val;
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-	  exit (0);
-     }
-
-/* setting offset */
-
-     if (argc < argidx+4)
-	  usage();
-
-     if (!strcmp(argv[argidx],"offset")) {
-	  rme_mixer mix;
-
-	  mix.devnr = atoi(argv[argidx+1]);
-
-	  mix.i_offset = atoi(argv[argidx+2]);
-	  mix.o_offset = atoi(argv[argidx+3]);
-	  ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix);
-	  fprintf(stdout,"devnr %d\n",mix.devnr);
-	  fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset);
-	  fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset);
-	  exit (0);
-     }
-
-     usage();
-     exit (0); /* to avoid warning */
-}
-
-
----------------------------- <snip> --------------------------------
-#!/usr/bin/wish
-
-# xrmectrl
-# (C) 2000 Guenter Geiger <geiger@debian.org>
-# HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-
-#set defaults "-relief ridged"
-set CTRLPROG "./rmectrl"
-if {$argc} {
-    set CTRLPROG "$CTRLPROG $argv"
-}
-puts "CTRLPROG $CTRLPROG"
-
-frame .butts
-button .butts.exit -text "Exit" -command "exit" -relief ridge
-#button .butts.state -text "State" -command "get_all"
-
-pack .butts.exit -side left
-pack .butts -side bottom
-
-
-#
-# STATUS
-#
-
-frame .status
-
-# Sampling Rate
-
-frame .status.sr
-label .status.sr.text -text "Sampling Rate" -justify left
-radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times
-radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times
-radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times
-radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw  -variable srate -value 96000 -font times
-
-pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
-
-# Lock
-
-frame .status.lock
-label .status.lock.text -text "Lock" -justify left
-checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times
-checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times
-checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times
-
-pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 
-
-# Sync
-
-frame .status.sync
-label .status.sync.text -text "Sync" -justify left
-checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times
-checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times
-checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times
-
-pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 
-
-# Timecode
-
-frame .status.tc
-label .status.tc.text -text "Timecode" -justify left
-checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times
-checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times
-checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times
-
-pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 
-
-# SPDIF In
-
-frame .status.spdif
-label .status.spdif.text -text "SPDIF In" -justify left
-label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times
-checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times
-
-pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 
-
-pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1
-
-
-#
-# CONTROL 
-#
-
-proc setprof {} {
-    global CTRLPROG
-    global spprof
-    exec $CTRLPROG pro $spprof
-}
-
-proc setemph {} {
-    global CTRLPROG
-    global spemph
-    exec $CTRLPROG emphasis $spemph
-}
-
-proc setnoaud {} {
-    global CTRLPROG
-    global spnoaud
-    exec $CTRLPROG dolby $spnoaud
-}
-
-proc setoptical {} {
-    global CTRLPROG
-    global spoptical
-    exec $CTRLPROG optout $spoptical
-}
-
-proc setspdifin {} {
-    global CTRLPROG
-    global spdifin
-    exec $CTRLPROG spdifin [expr $spdifin - 1]
-}
-
-proc setsyncsource {} {
-    global CTRLPROG
-    global syncsource
-    exec $CTRLPROG syncref [expr $syncsource -1]
-}
-
-
-proc setmaster {} {
-    global CTRLPROG
-    global master
-    exec $CTRLPROG master $master
-}
-
-proc setwordclock {} {
-    global CTRLPROG
-    global wordclock
-    exec $CTRLPROG wordclock $wordclock
-}
-
-proc setadat1cd {} {
-    global CTRLPROG
-    global adat1cd
-    exec $CTRLPROG adat1cd $adat1cd
-}
-
-
-frame .control
-
-# SPDIF In & SPDIF Out
-
-
-frame .control.spdif
-
-frame .control.spdif.in
-label .control.spdif.in.text -text "SPDIF In" -justify left
-radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times
-radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times
-radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times
-
-checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
-
-pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
-
-label .control.spdif.space
-
-frame .control.spdif.out
-label .control.spdif.out.text -text "SPDIF Out" -justify left
-checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times
-checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times
-checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times
-checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times
-
-pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
-
-pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
-
-# Sync Mode & Sync Source
-
-frame .control.sync
-frame .control.sync.mode
-label .control.sync.mode.text -text "Sync Mode" -justify left
-checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times
-checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times
-
-pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
-
-label .control.sync.space
-
-frame .control.sync.src
-label .control.sync.src.text -text "Sync Source" -justify left
-radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times
-radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times
-radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times
-radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times
-
-pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
-
-pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
-
-label .control.space -text "" -width 10
-
-# Buffer Size
-
-frame .control.buf
-label .control.buf.text -text "Buffer Size (Latency)" -justify left
-radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times
-radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times
-radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times
-radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times
-radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times
-radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times
-radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times
-radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times
-
-pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 
-
-# Offset
-
-frame .control.offset
-
-frame .control.offset.in
-label .control.offset.in.text -text "Offset In" -justify left
-label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
-label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
-label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
-label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
-
-pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
-
-label .control.offset.space
-
-frame .control.offset.out
-label .control.offset.out.text -text "Offset Out" -justify left
-label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
-label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
-label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
-label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
-
-pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
-
-pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
-
-
-pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
-
-
-label .statustext -text Status -justify center -relief ridge
-label .controltext -text Control -justify center -relief ridge
-
-label .statusspace
-label .controlspace
-
-pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
-
-
-proc get_bit {output sstr} {
-    set idx1 [string last [concat $sstr 1] $output]
-    set idx1 [expr $idx1 != -1]
-    return $idx1
-}
-
-proc get_val {output sstr} {
-    set val [string wordend $output [string last $sstr $output]] 
-    set val [string range $output $val [expr $val+1]]
-    return $val
-}
-
-proc get_val2 {output sstr} {
-    set val [string wordend $output [string first $sstr $output]] 
-    set val [string range $output $val [expr $val+2]]
-    return $val
-}
-
-proc get_control {} {
-    global spprof
-    global spemph
-    global spnoaud
-    global spoptical
-    global spdifin
-    global ssrate
-    global master
-    global wordclock
-    global syncsource
-    global CTRLPROG
-
-    set f [open "| $CTRLPROG control" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-    set spprof [ get_bit $ooo "pro"]
-    set spemph [ get_bit $ooo "emphasis"]
-    set spnoaud [ get_bit $ooo "dolby"]
-    set spoptical [ get_bit $ooo "opt_out"]
-    set spdifin [ expr [ get_val $ooo "spdif_in"] + 1]
-    set ssrate [ expr [ get_val $ooo "latency"] + 1]
-    set master [ expr [ get_val $ooo "master"]]
-    set wordclock [ expr [ get_val $ooo "wordclock"]]
-    set syncsource [ expr [ get_val $ooo "sync_ref"] + 1]
-}
-
-proc get_status {} {
-    global srate
-    global ctrlcom
-
-    global adatlock1
-    global adatlock2
-    global adatlock3
-
-    global adatsync1
-    global adatsync2
-    global adatsync3
-
-    global tcbusy
-    global tcout
-    global tcvalid
-
-    global spdiferr
-    global crystal
-    global .status.spdif.text
-    global CTRLPROG
-
-
-    set f [open "| $CTRLPROG status" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-# samplerate
-
-    set idx1 [string last "sr48 1" $ooo]
-    set idx2 [string last "doublespeed 1" $ooo]
-    if {$idx1 >= 0} {
-	set fact1 48000
-    } else {
-	set fact1 44100
-    }
-
-    if {$idx2 >= 0} {
-	set fact2 2
-    } else {
-	set fact2 1
-    }
-    set srate [expr $fact1 * $fact2]
-#   ADAT lock
-
-    set val [get_val $ooo lockmask]
-    set adatlock1 0
-    set adatlock2 0
-    set adatlock3 0
-    if {[expr $val & 1]} {
-       set adatlock3 1
-    }
-    if {[expr $val & 2]} {
-       set adatlock2 1
-    }
-    if {[expr $val & 4]} {
-       set adatlock1 1
-    }
-
-#  ADAT sync
-    set val [get_val $ooo syncmask]
-    set adatsync1 0
-    set adatsync2 0
-    set adatsync3 0
-
-    if {[expr $val & 1]} {
-       set adatsync3 1
-    }
-    if {[expr $val & 2]} {
-       set adatsync2 1
-    }
-    if {[expr $val & 4]} {
-       set adatsync1 1
-    }
-
-# TC busy
-
-    set tcbusy [get_bit $ooo "busy"]
-    set tcout [get_bit $ooo "out"]
-    set tcvalid [get_bit $ooo "valid"]
-    set spdiferr [expr [get_bit $ooo "spdif_error"] == 0]
-
-#  000=64kHz, 100=88.2kHz, 011=96kHz
-#  111=32kHz, 110=44.1kHz, 101=48kHz
-
-    set val [get_val $ooo crystalrate]
-
-    set crystal "--.- kHz"
-    if {$val == 0} {
-        set crystal "64 kHz"
-    }
-    if {$val == 4} {
-        set crystal "88.2 kHz"
-    }
-    if {$val == 3} {
-        set crystal "96 kHz"
-    }
-    if {$val == 7} {
-        set crystal "32 kHz"
-    }
-    if {$val == 6} {
-        set crystal "44.1 kHz"
-    }
-    if {$val == 5} {
-        set crystal "48 kHz"
-    }
-    .status.spdif.sr configure -text $crystal
-}
-
-proc get_offset {} {
-    global inoffset
-    global outoffset
-    global CTRLPROG
-
-    set f [open "| $CTRLPROG mix" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-    if { [string match "*devnr*" $ooo] } {
-	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-	set val [get_val2 $ooo i_offset]
-	.control.offset.in.off0 configure -text "dev\#0: $val"
-	set val [get_val2 $ooo o_offset]
-	.control.offset.out.off0 configure -text "dev\#0: $val"
-    } else {
-	.control.offset.in.off0 configure -text "dev\#0: -"
-	.control.offset.out.off0 configure -text "dev\#0: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-	set val [get_val2 $ooo i_offset]
-	.control.offset.in.off1 configure -text "dev\#1: $val"
-	set val [get_val2 $ooo o_offset]
-	.control.offset.out.off1 configure -text "dev\#1: $val"
-    } else {
-	.control.offset.in.off1 configure -text "dev\#1: -"
-	.control.offset.out.off1 configure -text "dev\#1: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-	set val [get_val2 $ooo i_offset]
-	.control.offset.in.off2 configure -text "dev\#2: $val"
-	set val [get_val2 $ooo o_offset]
-	.control.offset.out.off2 configure -text "dev\#2: $val"
-    } else {
-	.control.offset.in.off2 configure -text "dev\#2: -"
-	.control.offset.out.off2 configure -text "dev\#2: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-	set val [get_val2 $ooo i_offset]
-	.control.offset.in.off3 configure -text "dev\#3: $val"
-	set val [get_val2 $ooo o_offset]
-	.control.offset.out.off3 configure -text "dev\#3: $val"
-    } else {
-	.control.offset.in.off3 configure -text "dev\#3: -"
-	.control.offset.out.off3 configure -text "dev\#3: -"
-    }
-}
-
-
-proc get_all {} {
-get_status
-get_control
-get_offset
-}
-
-# main
-while {1} {
-  after 200
-  get_all
-  update
-}
diff --git a/Documentation/sound/oss/solo1 b/Documentation/sound/oss/solo1
deleted file mode 100644
index 6f53d40..0000000
--- a/Documentation/sound/oss/solo1
+++ /dev/null
@@ -1,70 +0,0 @@
-Recording
----------
-
-Recording does not work on the author's card, but there
-is at least one report of it working on later silicon.
-The chip behaves differently than described in the data sheet,
-likely due to a chip bug. Working around this would require
-the help of ESS (for example by publishing an errata sheet),
-but ESS has not done so so far.
-
-Also, the chip only supports 24 bit addresses for recording,
-which means it cannot work on some Alpha mainboards.
-
-
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (or later, available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-The card has an OPL compatible FM synthesizer.
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/sound/oss/sonicvibes b/Documentation/sound/oss/sonicvibes
deleted file mode 100644
index 84dee2e..0000000
--- a/Documentation/sound/oss/sonicvibes
+++ /dev/null
@@ -1,81 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-The card both has an OPL compatible FM synthesizer as well as
-a wavetable synthesizer.
-
-I haven't managed so far to get the OPL synth running.
-
-Using the wavetable synthesizer requires allocating
-1-4MB of physically contiguous memory, which isn't possible
-currently on Linux without ugly hacks like the bigphysarea
-patch. Therefore, the driver doesn't support wavetable
-synthesis.
-
-
-No support from S3
-------------------
-
-I do not get any support from S3. Therefore, the driver
-still has many problems. For example, although the manual
-states that the chip should be able to access the sample
-buffer anywhere in 32bit address space, I haven't managed to
-get it working with buffers above 16M. Therefore, the card
-has the same disadvantages as ISA soundcards.
-
-Given that the card is also very noisy, and if you haven't
-already bought it, you should strongly opt for one of the
-comparatively priced Ensoniq products.
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/sound/oss/ultrasound b/Documentation/sound/oss/ultrasound
index 32cd504..eed331c 100644
--- a/Documentation/sound/oss/ultrasound
+++ b/Documentation/sound/oss/ultrasound
@@ -19,7 +19,7 @@
 no_wave_dma option
 
 This option defaults to a value of 0, which allows the Ultrasound wavetable
-DSP to use DMA for for playback and downloading samples. This is the same
+DSP to use DMA for playback and downloading samples. This is the same
 as the old behaviour. If set to 1, no DMA is needed for downloading samples,
 and allows owners of a GUS MAX to make use of simultaneous digital audio
 (/dev/dsp), MIDI, and wavetable playback.
diff --git a/Documentation/sound/oss/vwsnd b/Documentation/sound/oss/vwsnd
index a6ea0a1..4c6cbdb 100644
--- a/Documentation/sound/oss/vwsnd
+++ b/Documentation/sound/oss/vwsnd
@@ -12,7 +12,7 @@
 
 The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio
 codec chip.  The AD1843 is accessed through the Cobalt I/O ASIC, also
-known as Lithium.  This driver programs both both chips.
+known as Lithium.  This driver programs both chips.
 
 ==============================================================================
 QUICK CONFIGURATION
diff --git a/Documentation/sparc/sbus_drivers.txt b/Documentation/sparc/sbus_drivers.txt
index 4b93516..8418d35 100644
--- a/Documentation/sparc/sbus_drivers.txt
+++ b/Documentation/sparc/sbus_drivers.txt
@@ -25,8 +25,8 @@
 used members of this structure, and their typical usage,
 will be detailed below.
 
-	Here is a piece of skeleton code for perofming a device
-probe in an SBUS driverunder Linux:
+	Here is a piece of skeleton code for performing a device
+probe in an SBUS driver under Linux:
 
 	static int __devinit mydevice_probe_one(struct sbus_dev *sdev)
 	{
@@ -98,7 +98,7 @@
 
 	Any memory allocated, registers mapped, IRQs registered,
 etc. must be undone by your .remove method so that all resources
-of your device are relased by the time it returns.
+of your device are released by the time it returns.
 
 	You should _NOT_ use the for_each_sbus(), for_each_sbusdev(),
 and for_all_sbusdev() interfaces.  They are deprecated, will be
diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx
index 9c45f3d..a1e0ee2 100644
--- a/Documentation/spi/pxa2xx
+++ b/Documentation/spi/pxa2xx
@@ -124,12 +124,12 @@
 The "pxa2xx_spi_chip.timeout_microsecs" fields is used to efficiently handle
 trailing bytes in the SSP receiver fifo.  The correct value for this field is
 dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific
-slave device.  Please note the the PXA2xx SSP 1 does not support trailing byte
+slave device.  Please note that the PXA2xx SSP 1 does not support trailing byte
 timeouts and must busy-wait any trailing bytes.
 
 The "pxa2xx_spi_chip.enable_loopback" field is used to place the SSP porting
 into internal loopback mode.  In this mode the SSP controller internally
-connects the SSPTX pin the the SSPRX pin.  This is useful for initial setup
+connects the SSPTX pin to the SSPRX pin.  This is useful for initial setup
 testing.
 
 The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific
@@ -208,7 +208,7 @@
 -----------------------
 The pxa2xx_spi driver support both DMA and interrupt driven PIO message
 transfers.  The driver defaults to PIO mode and DMA transfers must enabled by
-setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and and
+setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and
 ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero.  The DMA
 mode support both coherent and stream based DMA mappings.
 
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index 068732d3..7279579 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -262,7 +262,7 @@
 Developer boards often play by different rules than product boards, and one
 example is the potential need to hotplug SPI devices and/or controllers.
 
-For those cases you might need to use use spi_busnum_to_master() to look
+For those cases you might need to use spi_busnum_to_master() to look
 up the spi bus master, and will likely need spi_new_device() to provide the
 board info based on the board that was hotplugged.  Of course, you'd later
 call at least spi_unregister_device() when that board is removed.
@@ -322,7 +322,7 @@
 the SPI device using "struct spi_message".  When remove() returns,
 the driver guarantees that it won't submit any more such messages.
 
-  - An spi_message is a sequence of of protocol operations, executed
+  - An spi_message is a sequence of protocol operations, executed
     as one atomic sequence.  SPI driver controls include:
 
       + when bidirectional reads and writes start ... by how its
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt
index e409e5d..02a4812 100644
--- a/Documentation/stable_kernel_rules.txt
+++ b/Documentation/stable_kernel_rules.txt
@@ -4,7 +4,7 @@
 "-stable" tree:
 
  - It must be obviously correct and tested.
- - It can not be bigger than 100 lines, with context.
+ - It cannot be bigger than 100 lines, with context.
  - It must fix only one thing.
  - It must fix a real bug that bothers people (not a, "This could be a
    problem..." type thing).
@@ -14,7 +14,7 @@
    critical.
  - No "theoretical race condition" issues, unless an explanation of how the
    race can be exploited is also provided.
- - It can not contain any "trivial" fixes in it (spelling changes,
+ - It cannot contain any "trivial" fixes in it (spelling changes,
    whitespace cleanups, etc).
  - It must be accepted by the relevant subsystem maintainer.
  - It must follow the Documentation/SubmittingPatches rules.
diff --git a/Documentation/uml/UserModeLinux-HOWTO.txt b/Documentation/uml/UserModeLinux-HOWTO.txt
index 544430e..b60590e 100644
--- a/Documentation/uml/UserModeLinux-HOWTO.txt
+++ b/Documentation/uml/UserModeLinux-HOWTO.txt
@@ -157,7 +157,7 @@
   13. What to do when UML doesn't work
 
      13.1 Strange compilation errors when you build from source
-     13.2 UML hangs on boot after mounting devfs
+     13.2 (obsolete)
      13.3 A variety of panics and hangs with /tmp on a reiserfs  filesystem
      13.4 The compile fails with errors about conflicting types for 'open', 'dup', and 'waitpid'
      13.5 UML doesn't work when /tmp is an NFS filesystem
@@ -379,31 +379,6 @@
   bug fixes and enhancements that have gone into subsequent releases.
 
 
-  If you build your own kernel, and want to boot it from one of the
-  filesystems distributed from this site, then, in nearly all cases,
-  devfs must be compiled into the kernel and mounted at boot time.  The
-  exception is the SuSE filesystem.  For this, devfs must either not be
-  in the kernel at all, or "devfs=nomount" must be on the kernel command
-  line.  Any disagreement between the kernel and the filesystem being
-  booted about whether devfs is being used will result in the boot
-  getting no further than single-user mode.
-
-
-  If you don't want to use devfs, you can remove the need for it from a
-  filesystem by copying /dev from someplace, making a bunch of /dev/ubd
-  devices:
-
-
-  UML# for i in 0 1 2 3 4 5 6 7; do mknod ubd$i b 98 $i; done
-
-
-
-
-  and changing /etc/fstab and /etc/inittab to refer to the non-devfs
-  devices.
-
-
-
   22..22..  CCoommppiilliinngg aanndd iinnssttaalllliinngg kkeerrnneell mmoodduulleess
 
   UML modules are built in the same way as the native kernel (with the
@@ -839,9 +814,7 @@
   +o  None - device=none
 
 
-     This causes the device to disappear.  If you are using devfs, the
-     device will not appear in /dev.  If not, then attempts to open it
-     will return -ENODEV.
+     This causes the device to disappear.
 
 
 
@@ -1047,7 +1020,7 @@
 
   Note that the IP address you assign to the host end of the tap device
   must be different than the IP you assign to the eth device inside UML.
-  If you are short on IPs and don't want to comsume two per UML, then
+  If you are short on IPs and don't want to consume two per UML, then
   you can reuse the host's eth IP address for the host ends of the tap
   devices.  Internally, the UMLs must still get unique IPs for their eth
   devices.  You can also give the UMLs non-routable IPs (192.168.x.x or
@@ -2058,7 +2031,7 @@
   there are multiple COWs associated with a backing file, a -d merge of
   one of them will invalidate all of the others.  However, it is
   convenient if you're short of disk space, and it should also be
-  noticably faster than a non-destructive merge.
+  noticeably faster than a non-destructive merge.
 
 
 
@@ -3898,29 +3871,6 @@
 
 
 
-  1133..22..  UUMMLL hhaannggss oonn bboooott aafftteerr mmoouunnttiinngg ddeevvffss
-
-  The boot looks like this:
-
-
-       VFS: Mounted root (ext2 filesystem) readonly.
-       Mounted devfs on /dev
-
-
-
-
-  You're probably running a recent distribution on an old machine.  I
-  saw this with the RH7.1 filesystem running on a Pentium.  The shared
-  library loader, ld.so, was executing an instruction (cmove) which the
-  Pentium didn't support.  That instruction was apparently added later.
-  If you run UML under the debugger, you'll see the hang caused by one
-  instruction causing an infinite SIGILL stream.
-
-
-  The fix is to boot UML on an older filesystem.
-
-
-
   1133..33..  AA vvaarriieettyy ooff ppaanniiccss aanndd hhaannggss wwiitthh //ttmmpp oonn aa rreeiisseerrffss  ffiilleessyyss--
   tteemm
 
@@ -3953,9 +3903,9 @@
 
   1133..55..  UUMMLL ddooeessnn''tt wwoorrkk wwhheenn //ttmmpp iiss aann NNFFSS ffiilleessyysstteemm
 
-  This seems to be a similar situation with the resierfs problem above.
+  This seems to be a similar situation with the ReiserFS problem above.
   Some versions of NFS seems not to handle mmap correctly, which UML
-  depends on.  The workaround is have /tmp be non-NFS directory.
+  depends on.  The workaround is have /tmp be a non-NFS directory.
 
 
   1133..66..  UUMMLL hhaannggss oonn bboooott wwhheenn ccoommppiilleedd wwiitthh ggpprrooff ssuuppppoorrtt
@@ -4022,7 +3972,7 @@
   nneett
 
   If you can connect to the host, and the host can connect to UML, but
-  you can not connect to any other machines, then you may need to enable
+  you cannot connect to any other machines, then you may need to enable
   IP Masquerading on the host.  Usually this is only experienced when
   using private IP addresses (192.168.x.x or 10.x.x.x) for host/UML
   networking, rather than the public address space that your host is
@@ -4671,7 +4621,7 @@
   Chris Reahard built a specialized root filesystem for running a DNS
   server jailed inside UML.  It's available from the download
   <http://user-mode-linux.sourceforge.net/dl-sf.html>  page in the Jail
-  Filesysems section.
+  Filesystems section.
 
 
 
diff --git a/Documentation/unshare.txt b/Documentation/unshare.txt
index 90a5e9e..a864351 100644
--- a/Documentation/unshare.txt
+++ b/Documentation/unshare.txt
@@ -260,7 +260,7 @@
        a pointer to it.
 
   7.4) Appropriately modify architecture specific code to register the
-       the new system call.
+       new system call.
 
 8) Test Specification
 ---------------------
diff --git a/Documentation/usb/URB.txt b/Documentation/usb/URB.txt
index a49e5f2..8ffce74 100644
--- a/Documentation/usb/URB.txt
+++ b/Documentation/usb/URB.txt
@@ -184,7 +184,7 @@
 Note that even when an error (or unlink) is reported, data may have been
 transferred.  That's because USB transfers are packetized; it might take
 sixteen packets to transfer your 1KByte buffer, and ten of them might
-have transferred succesfully before the completion was called.
+have transferred successfully before the completion was called.
 
 
 NOTE:  ***** WARNING *****
diff --git a/Documentation/usb/acm.txt b/Documentation/usb/acm.txt
index 8ef45ea..737d610 100644
--- a/Documentation/usb/acm.txt
+++ b/Documentation/usb/acm.txt
@@ -49,20 +49,6 @@
   Unfortunately many modems and most ISDN TAs use proprietary interfaces and
 thus won't work with this drivers. Check for ACM compliance before buying.
 
-  The driver (with devfs) creates these devices in /dev/usb/acm:
-
-	crw-r--r--   1 root     root     166,   0 Apr  1 10:49 0
-	crw-r--r--   1 root     root     166,   1 Apr  1 10:49 1
-	crw-r--r--   1 root     root     166,   2 Apr  1 10:49 2
-
-  And so on, up to 31, with the limit being possible to change in acm.c to up
-to 256, so you can use up to 256 USB modems with one computer (you'll need
-three USB cards for that, though).
-
-  If you don't use devfs, then you can create device nodes with the same
-minor/major numbers anywhere you want, but either the above location or
-/dev/usb/ttyACM0 is preferred.
-
   To use the modems you need these modules loaded:
 
 	usbcore.ko
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
index 39c68f8..9cf83e8 100644
--- a/Documentation/usb/error-codes.txt
+++ b/Documentation/usb/error-codes.txt
@@ -126,7 +126,7 @@
 			urb->transfer_flags.
 
 -ENODEV			Device was removed.  Often preceded by a burst of
-			other errors, since the hub driver does't detect
+			other errors, since the hub driver doesn't detect
 			device removal events immediately.
 
 -EXDEV			ISO transfer only partially completed
@@ -145,7 +145,7 @@
 hardware problems such as bad devices (including firmware) or cables.
 
 (**) This is also one of several codes that different kinds of host
-controller use to to indicate a transfer has failed because of device
+controller use to indicate a transfer has failed because of device
 disconnect.  In the interval before the hub driver starts disconnect
 processing, devices may receive such fault reports for every request.
 
diff --git a/Documentation/usb/hiddev.txt b/Documentation/usb/hiddev.txt
index cd6fb4b..6a79075 100644
--- a/Documentation/usb/hiddev.txt
+++ b/Documentation/usb/hiddev.txt
@@ -118,7 +118,7 @@
 HIDIOCGDEVINFO - struct hiddev_devinfo (read)
 Gets a hiddev_devinfo structure which describes the device.
 
-HIDIOCGSTRING - struct struct hiddev_string_descriptor (read/write)
+HIDIOCGSTRING - struct hiddev_string_descriptor (read/write)
 Gets a string descriptor from the device. The caller must fill in the
 "index" field to indicate which descriptor should be returned.
 
diff --git a/Documentation/usb/mtouchusb.txt b/Documentation/usb/mtouchusb.txt
index cd806bf..e43cfff 100644
--- a/Documentation/usb/mtouchusb.txt
+++ b/Documentation/usb/mtouchusb.txt
@@ -11,7 +11,7 @@
    Changed reset from standard USB dev reset to vendor reset
    Changed data sent to host from compensated to raw coordinates
    Eliminated vendor/product module params
-   Performed multiple successfull tests with an EXII-5010UC
+   Performed multiple successful tests with an EXII-5010UC
 
 SUPPORTED HARDWARE:
 
@@ -38,7 +38,7 @@
 drivers.  Although 3M produces a binary only driver available for
 download, I persist in updating this driver since I would like to use the
 touchscreen for embedded apps using QTEmbedded, DirectFB, etc. So I feel the
-logical choice is to use Linux Imput.
+logical choice is to use Linux Input.
 
 Currently there is no way to calibrate the device via this driver.  Even if
 the device could be calibrated, the driver pulls to raw coordinate data from
@@ -63,7 +63,7 @@
 Implement a control urb again to handle requests to and from the device
 such as calibration, etc once/if it becomes available.
 
-DISCLAMER:
+DISCLAIMER:
 
 I am not a MicroTouch/3M employee, nor have I ever been.  3M does not support 
 this driver!  If you want touch drivers only supported within X, please go to:
diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt
index a2dee6e..8dc2bac 100644
--- a/Documentation/usb/usb-serial.txt
+++ b/Documentation/usb/usb-serial.txt
@@ -13,7 +13,6 @@
   Currently the driver can handle up to 256 different serial interfaces at
   one time. 
 
-  If you are not using devfs:
     The major number that the driver uses is 188 so to use the driver,
     create the following nodes:
 	mknod /dev/ttyUSB0 c 188 0
@@ -26,10 +25,6 @@
 	mknod /dev/ttyUSB254 c 188 254
 	mknod /dev/ttyUSB255 c 188 255
 
-  If you are using devfs:
-    The devices supported by this driver will show up as
-    /dev/usb/tts/{0,1,...}
-
   When the device is connected and recognized by the driver, the driver
   will print to the system log, which node(s) the device has been bound
   to.
@@ -228,7 +223,7 @@
 		-Cypress HID->COM RS232 adapter
 	
 		Note: Cypress Semiconductor claims no affiliation with the
-			the hid->com device.
+			hid->com device.
 
 	Most devices using chipsets under the CY4601 family should
      work with the driver.  As long as they stay true to the CY4601
@@ -277,7 +272,7 @@
   work under SMP with the uhci driver.
 
   The driver is generally working, though we still have a few more ioctls
-  to implement and final testing and debugging to do.  The paralled port
+  to implement and final testing and debugging to do.  The parallel port
   on the USB 2 is supported as a serial to parallel converter; in other
   words, it appears as another USB serial port on Linux, even though
   physically it is really a parallel port.  The Digi Acceleport USB 8
@@ -427,7 +422,7 @@
   debug			- extra verbose debugging info
   			  (default: 0; nonzero enables)
   use_lowlatency	- use low_latency flag to speed up tty layer
-			  when reading from from the device.
+			  when reading from the device.
 			  (default: 0; nonzero enables)
 
   See http://www.uuhaus.de/linux/palmconnect.html for up-to-date
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 669a09a..126e59d9 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -16,7 +16,7 @@
  15 -> DViCO FusionHDTV DVB-T1                             [18ac:db00]
  16 -> KWorld LTV883RF
  17 -> DViCO FusionHDTV 3 Gold-Q                           [18ac:d810,18ac:d800]
- 18 -> Hauppauge Nova-T DVB-T                              [0070:9002,0070:9001]
+ 18 -> Hauppauge Nova-T DVB-T                              [0070:9002,0070:9001,0070:9000]
  19 -> Conexant DVB-T reference design                     [14f1:0187]
  20 -> Provideo PV259                                      [1540:2580]
  21 -> DViCO FusionHDTV DVB-T Plus                         [18ac:db10,18ac:db11]
@@ -41,7 +41,7 @@
  40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid                [0070:9400,0070:9402]
  41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)  [0070:9800,0070:9802]
  42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025,1822:0019]
- 43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
+ 43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1,12ab:2300]
  44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50,18ac:db54]
  45 -> KWorld HardwareMpegTV XPert                         [17de:0840]
  46 -> DViCO FusionHDTV DVB-T Hybrid                       [18ac:db40,18ac:db44]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 94cf695..6fb82ac 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -97,3 +97,4 @@
  96 -> Medion Md8800 Quadro                     [16be:0007,16be:0008]
  97 -> LifeView FlyDVB-S /Acorp TV134DS         [5168:0300,4e42:0300]
  98 -> Proteus Pro 2309                         [0919:2003]
+ 99 -> AVerMedia TV Hybrid A16AR                [1461:2c00]
diff --git a/Documentation/video4linux/README.pvrusb2 b/Documentation/video4linux/README.pvrusb2
index c73a32c..a4b7ae8 100644
--- a/Documentation/video4linux/README.pvrusb2
+++ b/Documentation/video4linux/README.pvrusb2
@@ -155,7 +155,7 @@
   pvrusb2-i2c-core.[ch] - This module provides an implementation of a
     kernel-friendly I2C adaptor driver, through which other external
     I2C client drivers (e.g. msp3400, tuner, lirc) may connect and
-    operate corresponding chips within the the pvrusb2 device.  It is
+    operate corresponding chips within the pvrusb2 device.  It is
     through here that other V4L modules can reach into this driver to
     operate specific pieces (and those modules are in turn driven by
     glue logic which is coordinated by pvrusb2-hdw, doled out by
diff --git a/Documentation/video4linux/Zoran b/Documentation/video4linux/Zoran
index 040a2c8..deb218f 100644
--- a/Documentation/video4linux/Zoran
+++ b/Documentation/video4linux/Zoran
@@ -144,7 +144,7 @@
 
 The CCIR defines parameters needed for broadcasting the signal.
 The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,...
-The CCIR says not much about about the colorsystem used !!!
+The CCIR says not much about the colorsystem used !!!
 And talking about a colorsystem says not to much about how it is broadcast.
 
 The CCIR standards A,E,F are not used any more.
diff --git a/Documentation/video4linux/cx2341x/fw-decoder-api.txt b/Documentation/video4linux/cx2341x/fw-decoder-api.txt
index 9df4fb3..78bf5f2 100644
--- a/Documentation/video4linux/cx2341x/fw-decoder-api.txt
+++ b/Documentation/video4linux/cx2341x/fw-decoder-api.txt
@@ -102,7 +102,7 @@
 Name 	CX2341X_DEC_GET_XFER_INFO
 Enum 	9/0x09
 Description
-	This API call may be used to detect an end of stream condtion.
+	This API call may be used to detect an end of stream condition.
 Result[0]
 	Stream type
 Result[1]
diff --git a/Documentation/video4linux/cx2341x/fw-encoder-api.txt b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
index 001c686..15df0df 100644
--- a/Documentation/video4linux/cx2341x/fw-encoder-api.txt
+++ b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
@@ -280,7 +280,7 @@
 Param[1]
 	Unknown, but leaving this to 0 seems to work best. Indications are that
 	this might have to do with USB support, although passing anything but 0
-	onl breaks things.
+	only breaks things.
 
 -------------------------------------------------------------------------------
 
diff --git a/Documentation/video4linux/cx2341x/fw-osd-api.txt b/Documentation/video4linux/cx2341x/fw-osd-api.txt
index da98ae3..0a602f3 100644
--- a/Documentation/video4linux/cx2341x/fw-osd-api.txt
+++ b/Documentation/video4linux/cx2341x/fw-osd-api.txt
@@ -97,7 +97,7 @@
 Result[1]
 	top left vertical offset
 Result[2]
-	bottom right hotizontal offset
+	bottom right horizontal offset
 Result[3]
 	bottom right vertical offset
 
diff --git a/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt b/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt
index 93fec32..faccee6 100644
--- a/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt
+++ b/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt
@@ -30,7 +30,7 @@
 GP_SAMPLE register is at 0x35C058
 
 Bits are then right shifted into the GP_SAMPLE register at the specified
-rate; you get an interrupt when a full DWORD is recieved.
+rate; you get an interrupt when a full DWORD is received.
 You need to recover the actual RC5 bits out of the (oversampled) IR sensor
 bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
 actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
diff --git a/Documentation/video4linux/et61x251.txt b/Documentation/video4linux/et61x251.txt
index cd584f2..1bdee8f 100644
--- a/Documentation/video4linux/et61x251.txt
+++ b/Documentation/video4linux/et61x251.txt
@@ -80,7 +80,7 @@
   high compression quality (see also "Notes for V4L2 application developers"
   paragraph);
 - full support for the capabilities of every possible image sensors that can
-  be connected to the ET61X[12]51 bridges, including, for istance, red, green,
+  be connected to the ET61X[12]51 bridges, including, for instance, red, green,
   blue and global gain adjustments and exposure control (see "Supported
   devices" paragraph for details);
 - use of default color settings for sunlight conditions;
@@ -222,7 +222,7 @@
 	[root@localhost #] echo 1 > i2c_reg
 	[root@localhost #] cat i2c_val
 
-Note that if the sensor registers can not be read, "cat" will fail.
+Note that if the sensor registers cannot be read, "cat" will fail.
 To avoid race conditions, all the I/O accesses to the files are serialized.
 
 
diff --git a/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
index 93fec32..faccee6 100644
--- a/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
+++ b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
@@ -30,7 +30,7 @@
 GP_SAMPLE register is at 0x35C058
 
 Bits are then right shifted into the GP_SAMPLE register at the specified
-rate; you get an interrupt when a full DWORD is recieved.
+rate; you get an interrupt when a full DWORD is received.
 You need to recover the actual RC5 bits out of the (oversampled) IR sensor
 bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
 actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
diff --git a/Documentation/video4linux/meye.txt b/Documentation/video4linux/meye.txt
index 2137da9..ecb3416 100644
--- a/Documentation/video4linux/meye.txt
+++ b/Documentation/video4linux/meye.txt
@@ -29,7 +29,7 @@
 
 The third one, present in recent (more or less last year) Picturebooks
 (C1M* models), is not supported. The manufacturer has given the specs
-to the developers under a NDA (which allows the develoment of a GPL
+to the developers under a NDA (which allows the development of a GPL
 driver however), but things are not moving very fast (see
 http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011).
 
diff --git a/Documentation/video4linux/sn9c102.txt b/Documentation/video4linux/sn9c102.txt
index 1d20895..8cda472 100644
--- a/Documentation/video4linux/sn9c102.txt
+++ b/Documentation/video4linux/sn9c102.txt
@@ -60,7 +60,7 @@
 development of this project, despite several requests for enough detailed
 specifications of the register tables, compression engine and video data format
 of the above chips. Nevertheless, these informations are no longer necessary,
-becouse all the aspects related to these chips are known and have been
+because all the aspects related to these chips are known and have been
 described in detail in this documentation.
 
 The driver relies on the Video4Linux2 and USB core modules. It has been
@@ -85,7 +85,7 @@
   high compression quality (see also "Notes for V4L2 application developers"
   and "Video frame formats" paragraphs);
 - full support for the capabilities of many of the possible image sensors that
-  can be connected to the SN9C10x bridges, including, for istance, red, green,
+  can be connected to the SN9C10x bridges, including, for instance, red, green,
   blue and global gain adjustments and exposure (see "Supported devices"
   paragraph for details);
 - use of default color settings for sunlight conditions;
diff --git a/Documentation/video4linux/w9968cf.txt b/Documentation/video4linux/w9968cf.txt
index 0d53ce7..e0bba83 100644
--- a/Documentation/video4linux/w9968cf.txt
+++ b/Documentation/video4linux/w9968cf.txt
@@ -15,7 +15,7 @@
 5.  Supported devices
 6.  Module dependencies
 7.  Module loading
-8.  Module paramaters
+8.  Module parameters
 9.  Contact information
 10. Credits
 
diff --git a/Documentation/video4linux/zr36120.txt b/Documentation/video4linux/zr36120.txt
index ac6d92d..1a1c2d0 100644
--- a/Documentation/video4linux/zr36120.txt
+++ b/Documentation/video4linux/zr36120.txt
@@ -118,9 +118,9 @@
 response, and mail me if you got a working tvcard addition.
 
 PS. <TVCard editors behold!)
-    Dont forget to set video_input to the number of inputs
+    Don't forget to set video_input to the number of inputs
     you defined in the video_mux part of the tvcard definition.
-    Its a common error to add a channel but not incrementing
+    It's a common error to add a channel but not incrementing
     video_input and getting angry with me/v4l/linux/linus :(
 
 You are now ready to test the framegrabber with your favorite
diff --git a/Documentation/vm/numa b/Documentation/vm/numa
index 4b8db1b..e93ad94 100644
--- a/Documentation/vm/numa
+++ b/Documentation/vm/numa
@@ -22,7 +22,7 @@
 encapsulating all the pieces of information into a bootmem_data_t
 structure. Node specific calls have been added to the allocator. 
 In theory, any platform which uses the bootmem allocator should 
-be able to to put the bootmem and mem_map data structures anywhere
+be able to put the bootmem and mem_map data structures anywhere
 it deems best.
 
 Each node's page allocation data structures have also been encapsulated
diff --git a/Documentation/watchdog/watchdog-api.txt b/Documentation/watchdog/watchdog-api.txt
index 958ff3d..7e8ae83 100644
--- a/Documentation/watchdog/watchdog-api.txt
+++ b/Documentation/watchdog/watchdog-api.txt
@@ -45,7 +45,7 @@
 some of the drivers support the configuration option "Disable watchdog
 shutdown on close", CONFIG_WATCHDOG_NOWAYOUT.  If it is set to Y when
 compiling the kernel, there is no way of disabling the watchdog once
-it has been started.  So, if the watchdog dameon crashes, the system
+it has been started.  So, if the watchdog daemon crashes, the system
 will reboot after the timeout has passed.
 
 Some other drivers will not disable the watchdog, unless a specific
@@ -207,7 +207,7 @@
 support the GETBOOTSTATUS call.
 
 Some drivers can measure the temperature using the GETTEMP ioctl.  The
-returned value is the temperature in degrees farenheit.
+returned value is the temperature in degrees fahrenheit.
 
     int temperature;
     ioctl(fd, WDIOC_GETTEMP, &temperature);
@@ -258,13 +258,13 @@
 	Timeout default varies according to frequency, supports
 	SETTIMEOUT
 
-	Watchdog can not be turned off, CONFIG_WATCHDOG_NOWAYOUT
+	Watchdog cannot be turned off, CONFIG_WATCHDOG_NOWAYOUT
 	does not make sense
 
 	GETSUPPORT returns the watchdog_info struct, and
 	GETSTATUS returns the supported options. GETBOOTSTATUS
 	returns a 1 if the last reset was caused by the
-	watchdog and a 0 otherwise. This watchdog can not be
+	watchdog and a 0 otherwise. This watchdog cannot be
 	disabled once it has been started. The wdt_period kernel
 	parameter selects which bit of the time base changing
 	from 0->1 will trigger the watchdog exception. Changing
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index 74b77f9..f3c57f4 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -109,7 +109,7 @@
 Rebooting
 
    reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
-   bios	  Use the CPU reboto vector for warm reset
+   bios	  Use the CPU reboot vector for warm reset
    warm   Don't set the cold reboot flag
    cold   Set the cold reboot flag
    triple Force a triple fault (init)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7c238e4..17becb9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -144,11 +144,9 @@
 S:	Maintained
 
 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
-P:	Russell King
-M:	rmk+serial@arm.linux.org.uk
 L:	linux-serial@vger.kernel.org
 W:	http://serial.sourceforge.net
-S:	Maintained
+S:	Orphan
 
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 P:	Paul Gortmaker
@@ -989,6 +987,13 @@
 W:	http://ebtables.sourceforge.net/
 S:	Maintained
 
+ECRYPT FILE SYSTEM
+P:	Mike Halcrow, Phillip Hellewell
+M:	mhalcrow@us.ibm.com, phillip@hellewell.homeip.net
+L:	ecryptfs-devel@lists.sourceforge.net
+W:	http://ecryptfs.sourceforge.net/
+S:	Supported
+
 EDAC-CORE
 P:	Doug Thompson
 M:	norsk5@xmission.com
@@ -1913,11 +1918,6 @@
 W: 	http://www.syskonnect.com
 S: 	Supported
 
-MAESTRO PCI SOUND DRIVERS
-P:	Zach Brown
-M:	zab@zabbo.net
-S:	Odd Fixes
-
 MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
 P: Michael Kerrisk
 M: mtk-manpages@gmx.net
@@ -2004,9 +2004,7 @@
 S:	Maintained
 
 MULTIMEDIA CARD (MMC) SUBSYSTEM
-P:	Russell King
-M:	rmk+mmc@arm.linux.org.uk
-S:	Maintained
+S:	Orphan
 
 MULTISOUND SOUND DRIVER
 P:	Andrew Veliath
@@ -2456,6 +2454,19 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+READ-COPY UPDATE (RCU)
+P:	Dipankar Sarma
+M:	dipankar@in.ibm.com
+W:	http://www.rdrop.com/users/paulmck/rclock/
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+
+RCUTORTURE MODULE
+P:	Josh Triplett
+M:	josh@freedesktop.org
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 REAL TIME CLOCK DRIVER
 P:	Paul Gortmaker
 M:	p_gortmaker@yahoo.com
@@ -2729,14 +2740,6 @@
 L:	stable@kernel.org
 S:	Maintained
 
-STABLE BRANCH:
-P:	Greg Kroah-Hartman
-M:	greg@kroah.com
-P:	Chris Wright
-M:	chrisw@sous-sol.org
-L:	stable@kernel.org
-S:	Maintained
-
 TPM DEVICE DRIVER
 P:	Kylene Hall
 M:	kjhall@us.ibm.com
@@ -2843,17 +2846,13 @@
 M:	lethal@linux-sh.org
 L:	linuxsh-dev@lists.sourceforge.net (subscribers-only)
 W:	http://www.linux-sh.org
-W:	http://www.m17n.org/linux-sh/
 S:	Maintained
 
 SUPERH64 (sh64)
 P:	Paul Mundt
 M:	lethal@linux-sh.org
-P:	Richard Curnow
-M:	rc@rc0.org.uk
 L:	linuxsh-shmedia-dev@lists.sourceforge.net
 W:	http://www.linux-sh.org
-W:	http://www.rc0.org.uk/sh64
 S:	Maintained
 
 SUN3/3X
@@ -2888,6 +2887,11 @@
 W:	http://tcp-lp-mod.sourceforge.net/
 S:	Maintained
 
+TI FLASH MEDIA INTERFACE DRIVER
+P:      Alex Dubov
+M:      oakad@yahoo.com
+S:      Maintained
+
 TI OMAP RANDOM NUMBER GENERATOR SUPPORT
 P:	Deepak Saxena
 M:	dsaxena@plexity.net
@@ -3411,12 +3415,6 @@
 L:	usbb2k-api-dev@nongnu.org
 S:	Maintained
 
-YMFPCI YAMAHA PCI SOUND (Use ALSA instead)
-P:	Pete Zaitcev
-M:	zaitcev@yahoo.com
-L:	linux-kernel@vger.kernel.org
-S:	Obsolete
-
 Z8530 DRIVER FOR AX.25
 P:	Joerg Reuter
 M:	jreuter@yaina.de
diff --git a/Makefile b/Makefile
index 4c6c5e3..adb2c74 100644
--- a/Makefile
+++ b/Makefile
@@ -1321,7 +1321,7 @@
 		--langdef=kconfig \
 		--language-force=kconfig \
 		--regex-kconfig='/^[[:blank:]]*config[[:blank:]]+([[:alnum:]_]+)/\1/'; \
-	    $(all-defconfigs) | xargs $1 -a \
+	    $(all-defconfigs) | xargs -r $1 -a \
 		--langdef=dotconfig \
 		--language-force=dotconfig \
 		--regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'; \
@@ -1329,7 +1329,7 @@
 	    $(all-sources) | xargs $1 -a; \
 	    $(all-kconfigs) | xargs $1 -a \
 		--regex='/^[ \t]*config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
-	    $(all-defconfigs) | xargs $1 -a \
+	    $(all-defconfigs) | xargs -r $1 -a \
 		--regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
 	else \
 	    $(all-sources) | xargs $1 -a; \
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 2b36afd..7e55ea6 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -534,7 +534,7 @@
 	bool "Discontiguous Memory Support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 	help
-	  Say Y to upport efficient handling of discontiguous physical memory,
+	  Say Y to support 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.
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index f042cc42..8b02420 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/alpha/kernel/ksyms.c
+ * linux/arch/alpha/kernel/alpha_ksyms.c
  *
  * Export the alpha-specific functions that are needed for loadable
  * modules.
@@ -36,7 +36,6 @@
 #include <asm/cacheflush.h>
 #include <asm/vga.h>
 
-#define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
 
 extern struct hwrpb_struct *hwrpb;
@@ -116,7 +115,7 @@
 EXPORT_SYMBOL(sys_exit);
 EXPORT_SYMBOL(sys_write);
 EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
 EXPORT_SYMBOL(sys_setsid);
 EXPORT_SYMBOL(sys_wait4);
 
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 01ecd09..c95e95e 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -655,12 +655,12 @@
 .end kernel_thread
 
 /*
- * execve(path, argv, envp)
+ * kernel_execve(path, argv, envp)
  */
 	.align	4
-	.globl	execve
-	.ent	execve
-execve:
+	.globl	kernel_execve
+	.ent	kernel_execve
+kernel_execve:
 	/* We can be called from a module.  */
 	ldgp	$gp, 0($27)
 	lda	$sp, -(32+SIZEOF_PT_REGS+8)($sp)
@@ -704,7 +704,7 @@
 
 1:	lda	$sp, 32+SIZEOF_PT_REGS+8($sp)
 	ret
-.end execve
+.end kernel_execve
 
 
 /*
diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S
index 1e2a62a..e27d23c 100644
--- a/arch/alpha/kernel/head.S
+++ b/arch/alpha/kernel/head.S
@@ -1,5 +1,5 @@
 /*
- * alpha/boot/head.S
+ * arch/alpha/kernel/head.S
  *
  * initial boot stuff.. At this point, the bootloader has already
  * switched into OSF/1 PAL-code, and loaded us at the correct address
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index 08b8302..0caa45a 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -1,5 +1,5 @@
 /*
- *	linux/arch/alpha/kernel/machvec.h
+ *	linux/arch/alpha/kernel/machvec_impl.h
  *
  *	Copyright (C) 1997, 1998  Richard Henderson
  *
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 73c7622..ad61736 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -111,22 +111,26 @@
 
 static int
 osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
-	    ino_t ino, unsigned int d_type)
+	    u64 ino, unsigned int d_type)
 {
 	struct osf_dirent __user *dirent;
 	struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
 	unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1);
+	unsigned int d_ino;
 
 	buf->error = -EINVAL;	/* only used if we fail */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	if (buf->basep) {
 		if (put_user(offset, buf->basep))
 			return -EFAULT;
 		buf->basep = NULL;
 	}
 	dirent = buf->dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
 	if (copy_to_user(dirent->d_name, name, namlen) ||
@@ -402,15 +406,15 @@
 
 	down_read(&uts_sem);
 	error = -EFAULT;
-	if (copy_to_user(name + 0, system_utsname.sysname, 32))
+	if (copy_to_user(name + 0, utsname()->sysname, 32))
 		goto out;
-	if (copy_to_user(name + 32, system_utsname.nodename, 32))
+	if (copy_to_user(name + 32, utsname()->nodename, 32))
 		goto out;
-	if (copy_to_user(name + 64, system_utsname.release, 32))
+	if (copy_to_user(name + 64, utsname()->release, 32))
 		goto out;
-	if (copy_to_user(name + 96, system_utsname.version, 32))
+	if (copy_to_user(name + 96, utsname()->version, 32))
 		goto out;
-	if (copy_to_user(name + 128, system_utsname.machine, 32))
+	if (copy_to_user(name + 128, utsname()->machine, 32))
 		goto out;
 
 	error = 0;
@@ -449,8 +453,8 @@
 
 	down_read(&uts_sem);
 	for (i = 0; i < len; ++i) {
-		__put_user(system_utsname.domainname[i], name + i);
-		if (system_utsname.domainname[i] == '\0')
+		__put_user(utsname()->domainname[i], name + i);
+		if (utsname()->domainname[i] == '\0')
 			break;
 	}
 	up_read(&uts_sem);
@@ -607,12 +611,12 @@
 asmlinkage long
 osf_sysinfo(int command, char __user *buf, long count)
 {
-	static char * sysinfo_table[] = {
-		system_utsname.sysname,
-		system_utsname.nodename,
-		system_utsname.release,
-		system_utsname.version,
-		system_utsname.machine,
+	char *sysinfo_table[] = {
+		utsname()->sysname,
+		utsname()->nodename,
+		utsname()->release,
+		utsname()->version,
+		utsname()->machine,
 		"alpha",	/* instruction set architecture */
 		"dummy",	/* hardware serial number */
 		"dummy",	/* hardware manufacturer */
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index 9d7dff2..7569232 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -229,7 +229,7 @@
 
 static struct tty_driver *srmcons_driver;
 
-static struct tty_operations srmcons_ops = {
+static const struct tty_operations srmcons_ops = {
 	.open		= srmcons_open,
 	.close		= srmcons_close,
 	.write		= srmcons_write,
diff --git a/arch/alpha/lib/dbg_stackcheck.S b/arch/alpha/lib/dbg_stackcheck.S
index 3c1f3e6..78f6b92 100644
--- a/arch/alpha/lib/dbg_stackcheck.S
+++ b/arch/alpha/lib/dbg_stackcheck.S
@@ -1,5 +1,5 @@
 /*
- * arch/alpha/lib/stackcheck.S
+ * arch/alpha/lib/dbg_stackcheck.S
  * Contributed by Richard Henderson (rth@tamu.edu)
  *
  * Verify that we have not overflowed the stack.  Oops if we have.
diff --git a/arch/alpha/lib/dbg_stackkill.S b/arch/alpha/lib/dbg_stackkill.S
index e9f6a9d..c1e40a1 100644
--- a/arch/alpha/lib/dbg_stackkill.S
+++ b/arch/alpha/lib/dbg_stackkill.S
@@ -1,5 +1,5 @@
 /*
- * arch/alpha/lib/killstack.S
+ * arch/alpha/lib/dbg_stackkill.S
  * Contributed by Richard Henderson (rth@cygnus.com)
  *
  * Clobber the balance of the kernel stack, hoping to catch
diff --git a/arch/alpha/lib/memset.S b/arch/alpha/lib/memset.S
index 8ff6e7e..311b8cf 100644
--- a/arch/alpha/lib/memset.S
+++ b/arch/alpha/lib/memset.S
@@ -1,5 +1,5 @@
 /*
- * linux/arch/alpha/memset.S
+ * linux/arch/alpha/lib/memset.S
  *
  * This is an efficient (and small) implementation of the C library "memset()"
  * function for the alpha.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f9362ee..adb05de 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -629,7 +629,7 @@
 	depends on CPU_CP15_MMU
 	default y if !ARCH_EBSA110
 	help
-	  ARM processors can not fetch/store information which is not
+	  ARM processors cannot fetch/store information which is not
 	  naturally aligned on the bus, i.e., a 4 byte fetch must start at an
 	  address divisible by 4. On 32-bit ARM processors, these non-aligned
 	  fetch/store instructions will be emulated in software if you say
diff --git a/arch/arm/boot/compressed/head-clps7500.S b/arch/arm/boot/compressed/head-clps7500.S
index 941c5f5..4f3c78a 100644
--- a/arch/arm/boot/compressed/head-clps7500.S
+++ b/arch/arm/boot/compressed/head-clps7500.S
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/boot/compressed/head.S
+ * linux/arch/arm/boot/compressed/head-clps7500.S
  *
  * Copyright (C) 1999, 2000, 2001 Nexus Electronics Ltd
  */
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index e5ab51b..2568d31 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -237,7 +237,8 @@
  */
 		cmp	r4, r2
 		bhs	wont_overwrite
-		add	r0, r4, #4096*1024	@ 4MB largest kernel size
+		sub	r3, sp, r5		@ > compressed kernel size
+		add	r0, r4, r3, lsl #2	@ allow for 4x expansion
 		cmp	r0, r5
 		bls	wont_overwrite
 
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 29818bd..30046ad 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-sa1100/sa1111.c
+ * linux/arch/arm/common/sa1111.c
  *
  * SA1111 support
  *
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 5365d4e..ebc3e74 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -234,18 +234,18 @@
 
 	/*
 	 * Now setup the pagetables for our kernel direct
-	 * mapped region.  We round TEXTADDR down to the
-	 * nearest megabyte boundary.  It is assumed that
-	 * the kernel fits within 4 contigous 1MB sections.
+	 * mapped region.
 	 */
 	add	r0, r4,  #(TEXTADDR & 0xff000000) >> 18	@ start of kernel
 	str	r3, [r0, #(TEXTADDR & 0x00f00000) >> 18]!
-	add	r3, r3, #1 << 20
-	str	r3, [r0, #4]!			@ KERNEL + 1MB
-	add	r3, r3, #1 << 20
-	str	r3, [r0, #4]!			@ KERNEL + 2MB
-	add	r3, r3, #1 << 20
-	str	r3, [r0, #4]			@ KERNEL + 3MB
+
+	ldr	r6, =(_end - PAGE_OFFSET - 1)	@ r6 = number of sections
+	mov	r6, r6, lsr #20			@ needed for kernel minus 1
+
+1:	add	r3, r3, #1 << 20
+	str	r3, [r0, #4]!
+	subs	r6, r6, #1
+	bgt	1b
 
 	/*
 	 * Then map first 1MB of ram in case it contains our boot params.
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0a722e7..6bbd93d 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -348,7 +348,7 @@
 	       cpu_name, processor_id, (int)processor_id & 15,
 	       proc_arch[cpu_architecture()], cr_alignment);
 
-	sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
+	sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
 	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
 	elf_hwcap = list->elf_hwcap;
 #ifndef CONFIG_ARM_THUMB
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 68e9634..421329f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -36,7 +36,9 @@
  * The online bitmask indicates that the CPU is up and running.
  */
 cpumask_t cpu_possible_map;
+EXPORT_SYMBOL(cpu_possible_map);
 cpumask_t cpu_online_map;
+EXPORT_SYMBOL(cpu_online_map);
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 8170af4..00c18d3 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -279,7 +279,7 @@
 	return error;
 }
 
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
 {
 	struct pt_regs regs;
 	int ret;
@@ -317,7 +317,7 @@
  out:
 	return ret;
 }
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
 
 /*
  * Since loff_t is a 64 bit type we avoid a lot of ABI hastle
diff --git a/arch/arm/mach-ep93xx/edb9315a.c b/arch/arm/mach-ep93xx/edb9315a.c
index bfefdaa..fa958e9 100644
--- a/arch/arm/mach-ep93xx/edb9315a.c
+++ b/arch/arm/mach-ep93xx/edb9315a.c
@@ -44,10 +44,40 @@
 	.resource	= &edb9315a_flash_resource,
 };
 
+static struct ep93xx_eth_data edb9315a_eth_data = {
+	.phy_id			= 1,
+};
+
+static struct resource edb9315a_eth_resource[] = {
+	{
+		.start	= EP93XX_ETHERNET_PHYS_BASE,
+		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_EP93XX_ETHERNET,
+		.end	= IRQ_EP93XX_ETHERNET,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device edb9315a_eth_device = {
+	.name		= "ep93xx-eth",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &edb9315a_eth_data,
+	},
+	.num_resources	= 2,
+	.resource	= edb9315a_eth_resource,
+};
+
 static void __init edb9315a_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9315a_flash);
+
+	memcpy(edb9315a_eth_data.dev_addr,
+		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
+	platform_device_register(&edb9315a_eth_device);
 }
 
 MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index e760fd4f..694590a 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -43,10 +43,37 @@
 	.resource	= &gesbc9312_flash_resource,
 };
 
+static struct ep93xx_eth_data gesbc9312_eth_data = {
+	.phy_id			= 1,
+};
+
+static struct resource gesbc9312_eth_resource[] = {
+	{
+		.start	= EP93XX_ETHERNET_PHYS_BASE,
+		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_EP93XX_ETHERNET,
+		.end	= IRQ_EP93XX_ETHERNET,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device gesbc9312_eth_device = {
+	.name		= "ep93xx-eth",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &gesbc9312_eth_data,
+	},
+	.num_resources	= 2,
+	.resource	= gesbc9312_eth_resource,
+};
+
 static void __init gesbc9312_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&gesbc9312_flash);
+	platform_device_register(&gesbc9312_eth_device);
 }
 
 MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index df315f2..3a4bf90 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -157,12 +157,42 @@
 	.num_resources		= 0,
 };
 
+static struct ep93xx_eth_data ts72xx_eth_data = {
+	.phy_id			= 1,
+};
+
+static struct resource ts72xx_eth_resource[] = {
+	{
+		.start	= EP93XX_ETHERNET_PHYS_BASE,
+		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_EP93XX_ETHERNET,
+		.end	= IRQ_EP93XX_ETHERNET,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device ts72xx_eth_device = {
+	.name		= "ep93xx-eth",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &ts72xx_eth_data,
+	},
+	.num_resources	= 2,
+	.resource	= ts72xx_eth_resource,
+};
+
 static void __init ts72xx_init_machine(void)
 {
 	ep93xx_init_devices();
 	if (board_is_ts7200())
 		platform_device_register(&ts72xx_flash);
 	platform_device_register(&ts72xx_rtc_device);
+
+	memcpy(ts72xx_eth_data.dev_addr,
+		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
+	platform_device_register(&ts72xx_eth_device);
 }
 
 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
diff --git a/arch/arm/mach-imx/leds.c b/arch/arm/mach-imx/leds.c
index 471c1db..cf30803 100644
--- a/arch/arm/mach-imx/leds.c
+++ b/arch/arm/mach-imx/leds.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-imx/leds.h
+ * linux/arch/arm/mach-imx/leds.c
  *
  * Copyright (C) 2004 Sascha Hauer <sascha@saschahauer.de>
  *
diff --git a/arch/arm/mach-imx/leds.h b/arch/arm/mach-imx/leds.h
index 83fa21e..49dc1c1 100644
--- a/arch/arm/mach-imx/leds.h
+++ b/arch/arm/mach-imx/leds.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-imx/leds.h
+ * arch/arm/mach-imx/leds.h
  *
  * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
  *
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
index 2cebb28..7bc94f3 100644
--- a/arch/arm/mach-ixp4xx/coyote-pci.c
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -1,5 +1,5 @@
 /*
- * arch/arch/mach-ixp4xx/coyote-pci.c
+ * arch/arm/mach-ixp4xx/coyote-pci.c
  *
  * PCI setup routines for ADI Engineering Coyote platform
  *
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
index ed52708..509a95a 100644
--- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -1,5 +1,5 @@
 /*
- * arch/arch/mach-ixp4xx/ixdpg425-pci.c
+ * arch/arm/mach-ixp4xx/ixdpg425-pci.c
  *
  * PCI setup routines for Intel IXDPG425 Platform
  *
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index a691011..a21b12f 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -164,7 +164,7 @@
 	/* CPLD doesn't have ack capability, but some devices may */
 
 #if defined (CPLD_INTMASK_TOUCH)
-	/* The touch control *must* mask the the interrupt because the
+	/* The touch control *must* mask the interrupt because the
 	 * interrupt bit is read by the driver to determine if the pen
 	 * is still down. */
 	if (irq == IRQ_TOUCH)
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 976edfb8..c4b7902 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap1/id.c
+ * linux/arch/arm/mach-omap1/serial.c
  *
  * OMAP1 CPU identification code
  *
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 2db6b73..c37b0e6 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/board-apollon.c
+ * linux/arch/arm/mach-omap2/board-apollon.c
  *
  * Copyright (C) 2005,2006 Samsung Electronics
  * Author: Kyungmin Park <kyungmin.park@samsung.com>
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index eaecbf4..9093815 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/board-generic.c
+ * linux/arch/arm/mach-omap2/board-generic.c
  *
  * Copyright (C) 2005 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 996aeda..26a95a6 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/board-h4.c
+ * linux/arch/arm/mach-omap2/board-h4.c
  *
  * Copyright (C) 2005 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 1ed2fff..1187009 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/irq.c
+ * linux/arch/arm/mach-omap2/irq.c
  *
  * Interrupt handler for OMAP2 boards.
  *
diff --git a/arch/arm/mach-omap2/prcm-regs.h b/arch/arm/mach-omap2/prcm-regs.h
index 22ac7be..5e1c4b5 100644
--- a/arch/arm/mach-omap2/prcm-regs.h
+++ b/arch/arm/mach-omap2/prcm-regs.h
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap2/prcm-reg.h
+ * linux/arch/arm/mach-omap2/prcm-regs.h
  *
  * OMAP24XX Power Reset and Clock Management (PRCM) registers
  *
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 0884bc7..aaa5589 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-omap/omap2/serial.c
+ * arch/arm/mach-omap2/serial.c
  *
  * OMAP2 serial support.
  *
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S
index a5ef7f6..b275766 100644
--- a/arch/arm/mach-omap2/sram-fn.S
+++ b/arch/arm/mach-omap2/sram-fn.S
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap2/sram.S
+ * linux/arch/arm/mach-omap2/sram-fn.S
  *
  * Omap2 specific functions that need to be run in internal SRAM
  *
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
index f582ed2..daa8d3d 100644
--- a/arch/arm/mach-pnx4008/clock.c
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -735,6 +735,16 @@
 	.enable_reg = UARTCLKCTRL_REG,
 };
 
+static struct clk wdt_ck = {
+	.name = "wdt_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = TIMCLKCTRL_REG,
+};
+
 /* These clocks are visible outside this module
  * and can be initialized
  */
@@ -765,6 +775,7 @@
 	&uart4_ck,
 	&uart5_ck,
 	&uart6_ck,
+	&wdt_ck,
 };
 
 static int local_clk_enable(struct clk *clk)
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 6dbcaf1..a72476c 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/video/w100fb.c
+ * linux/arch/arm/mach-pxa/corgi_lcd.c
  *
  * Corgi/Spitz LCD Specific Code
  *
@@ -431,10 +431,10 @@
 
 #include <asm/arch/pxafb.h>
 
-void spitz_lcd_power(int on)
+void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
 {
 	if (on)
-		lcdtg_hw_init(480);
+		lcdtg_hw_init(var->xres);
 	else
 		lcdtg_suspend();
 }
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 5efa847..45fb2c3 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -204,13 +204,6 @@
 	}
 };
 
-static struct pxafb_mach_info pxa_fb_info;
-
-void __init set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info)
-{
-	memcpy(&pxa_fb_info,hard_pxa_fb_info,sizeof(struct pxafb_mach_info));
-}
-
 static struct resource pxafb_resources[] = {
 	[0] = {
 		.start	= 0x44000000,
@@ -230,7 +223,6 @@
 	.name		= "pxa2xx-fb",
 	.id		= -1,
 	.dev		= {
- 		.platform_data	= &pxa_fb_info,
 		.dma_mask	= &fb_dma_mask,
 		.coherent_dma_mask = 0xffffffff,
 	},
@@ -238,6 +230,11 @@
 	.resource	= pxafb_resources,
 };
 
+void __init set_pxa_fb_info(struct pxafb_mach_info *info)
+{
+	pxafb_device.dev.platform_data = info;
+}
+
 void __init set_pxa_fb_parent(struct device *parent_dev)
 {
 	pxafb_device.dev.parent = parent_dev;
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 6914d22..3e4b0ab 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -82,7 +82,7 @@
 	}
 }
 
-static void idp_lcd_power(int on)
+static void idp_lcd_power(int on, struct fb_var_screeninfo *var)
 {
 	if (on) {
 		IDP_CPLD_LCD |= (1<<0);
@@ -99,7 +99,7 @@
 	idp_vlcd(on);
 }
 
-static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+static struct pxafb_mode_info sharp_lm8v31_mode = {
 	.pixclock	= 270000,
 	.xres		= 640,
 	.yres		= 480,
@@ -112,6 +112,11 @@
 	.lower_margin	= 0,
 	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	.cmap_greyscale	= 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+	.modes          = &sharp_lm8v31_mode,
+	.num_modes      = 1,
 	.cmap_inverse	= 0,
 	.cmap_static	= 0,
 	.lccr0		= LCCR0_SDS,
diff --git a/arch/arm/mach-pxa/leds.h b/arch/arm/mach-pxa/leds.h
index 4f829b8..7f0dfe0 100644
--- a/arch/arm/mach-pxa/leds.h
+++ b/arch/arm/mach-pxa/leds.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-pxa/leds.h
+ * arch/arm/mach-pxa/leds.h
  *
  * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
  *
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 12479ae..eff2a91 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -248,7 +248,7 @@
 }
 
 /* 5.7" TFT QVGA (LoLo display number 1) */
-static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = {
+static struct pxafb_mode_info sharp_lq057q3dc02_mode = {
 	.pixclock		= 150000,
 	.xres			= 320,
 	.yres			= 240,
@@ -260,13 +260,18 @@
 	.upper_margin		= 0x08,
 	.lower_margin		= 0x14,
 	.sync			= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq057q3dc02 = {
+	.modes			= &sharp_lq057q3dc02_mode,
+	.num_modes		= 1,
 	.lccr0			= 0x07800080,
 	.lccr3			= 0x00400000,
 	.pxafb_backlight_power	= lpd270_backlight_power,
 };
 
 /* 12.1" TFT SVGA (LoLo display number 2) */
-static struct pxafb_mach_info sharp_lq121s1dg31 __initdata = {
+static struct pxafb_mode_info sharp_lq121s1dg31_mode = {
 	.pixclock		= 50000,
 	.xres			= 800,
 	.yres			= 600,
@@ -278,13 +283,18 @@
 	.upper_margin		= 0x14,
 	.lower_margin		= 0x0a,
 	.sync			= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq121s1dg31 = {
+	.modes			= &sharp_lq121s1dg31_mode,
+	.num_modes		= 1,
 	.lccr0			= 0x07800080,
 	.lccr3			= 0x00400000,
 	.pxafb_backlight_power	= lpd270_backlight_power,
 };
 
 /* 3.6" TFT QVGA (LoLo display number 3) */
-static struct pxafb_mach_info sharp_lq036q1da01 __initdata = {
+static struct pxafb_mode_info sharp_lq036q1da01_mode = {
 	.pixclock		= 150000,
 	.xres			= 320,
 	.yres			= 240,
@@ -296,13 +306,18 @@
 	.upper_margin		= 0x03,
 	.lower_margin		= 0x03,
 	.sync			= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq036q1da01 = {
+	.modes			= &sharp_lq036q1da01_mode,
+	.num_modes		= 1,
 	.lccr0			= 0x07800080,
 	.lccr3			= 0x00400000,
 	.pxafb_backlight_power	= lpd270_backlight_power,
 };
 
 /* 6.4" TFT VGA (LoLo display number 5) */
-static struct pxafb_mach_info sharp_lq64d343 __initdata = {
+static struct pxafb_mode_info sharp_lq64d343_mode = {
 	.pixclock		= 25000,
 	.xres			= 640,
 	.yres			= 480,
@@ -314,13 +329,18 @@
 	.upper_margin		= 0x22,
 	.lower_margin		= 0x00,
 	.sync			= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq64d343 = {
+	.modes			= &sharp_lq64d343_mode,
+	.num_modes		= 1,
 	.lccr0			= 0x07800080,
 	.lccr3			= 0x00400000,
 	.pxafb_backlight_power	= lpd270_backlight_power,
 };
 
 /* 10.4" TFT VGA (LoLo display number 7) */
-static struct pxafb_mach_info sharp_lq10d368 __initdata = {
+static struct pxafb_mode_info sharp_lq10d368_mode = {
 	.pixclock		= 25000,
 	.xres			= 640,
 	.yres			= 480,
@@ -332,13 +352,18 @@
 	.upper_margin		= 0x22,
 	.lower_margin		= 0x00,
 	.sync			= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq10d368 = {
+	.modes			= &sharp_lq10d368_mode,
+	.num_modes		= 1,
 	.lccr0			= 0x07800080,
 	.lccr3			= 0x00400000,
 	.pxafb_backlight_power	= lpd270_backlight_power,
 };
 
 /* 3.5" TFT QVGA (LoLo display number 8) */
-static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = {
+static struct pxafb_mode_info sharp_lq035q7db02_20_mode = {
 	.pixclock		= 150000,
 	.xres			= 240,
 	.yres			= 320,
@@ -350,6 +375,11 @@
 	.upper_margin		= 0x05,
 	.lower_margin		= 0x14,
 	.sync			= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq035q7db02_20 = {
+	.modes			= &sharp_lq035q7db02_20_mode,
+	.num_modes		= 1,
 	.lccr0			= 0x07800080,
 	.lccr3			= 0x00400000,
 	.pxafb_backlight_power	= lpd270_backlight_power,
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 83ff5ce..157cf47 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -352,7 +352,7 @@
 	&pxa_ssp,
 };
 
-static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+static struct pxafb_mode_info sharp_lm8v31_mode = {
 	.pixclock	= 270000,
 	.xres		= 640,
 	.yres		= 480,
@@ -365,6 +365,11 @@
 	.lower_margin	= 0,
 	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	.cmap_greyscale	= 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+	.modes		= &sharp_lm8v31_mode,
+	.num_modes	= 1,
 	.cmap_inverse	= 0,
 	.cmap_static	= 0,
 	.lccr0		= LCCR0_SDS,
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index a7e9b96..7ba0447 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -279,7 +279,7 @@
 	}
 }
 
-static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
+static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
 	.pixclock		= 50000,
 	.xres			= 640,
 	.yres			= 480,
@@ -291,12 +291,9 @@
 	.upper_margin		= 0,
 	.lower_margin		= 0,
 	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
-	.lccr0			= LCCR0_Act,
-	.lccr3			= LCCR3_PCP,
-	.pxafb_backlight_power	= mainstone_backlight_power,
 };
 
-static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
+static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
 	.pixclock		= 110000,
 	.xres			= 240,
 	.yres			= 320,
@@ -308,6 +305,10 @@
 	.upper_margin		= 1,
 	.lower_margin		= 10,
 	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info mainstone_pxafb_info = {
+	.num_modes      	= 1,
 	.lccr0			= LCCR0_Act,
 	.lccr3			= LCCR3_PCP,
 	.pxafb_backlight_power	= mainstone_backlight_power,
@@ -448,9 +449,11 @@
 	/* reading Mainstone's "Virtual Configuration Register"
 	   might be handy to select LCD type here */
 	if (0)
-		set_pxa_fb_info(&toshiba_ltm04c380k);
+		mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
 	else
-		set_pxa_fb_info(&toshiba_ltm035a776c);
+		mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
+
+	set_pxa_fb_info(&mainstone_pxafb_info);
 
 	pxa_set_mci_info(&mainstone_mci_platform_data);
 	pxa_set_ficp_info(&mainstone_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 6dbff6d..5e8c098 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -296,27 +296,25 @@
 
 
 /* PXAFB device */
-static struct pxafb_mach_info poodle_fb_info __initdata = {
+static struct pxafb_mode_info poodle_fb_mode = {
 	.pixclock	= 144700,
-
 	.xres		= 320,
 	.yres		= 240,
 	.bpp		= 16,
-
 	.hsync_len	= 7,
 	.left_margin	= 11,
 	.right_margin	= 30,
-
 	.vsync_len	= 2,
 	.upper_margin	= 2,
 	.lower_margin	= 0,
 	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
 
+static struct pxafb_mach_info poodle_fb_info = {
+	.modes		= &poodle_fb_mode,
+	.num_modes	= 1,
 	.lccr0		= LCCR0_Act | LCCR0_Sngl | LCCR0_Color,
 	.lccr3		= 0,
-
-	.pxafb_backlight_power	= NULL,
-	.pxafb_lcd_power	= NULL,
 };
 
 static struct platform_device *devices[] __initdata = {
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 1c32a93..401cdb8 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -407,21 +407,42 @@
 /*
  * Spitz PXA Framebuffer
  */
-static struct pxafb_mach_info spitz_pxafb_info __initdata = {
-        .pixclock       = 19231,
-        .xres           = 480,
-        .yres           = 640,
-        .bpp            = 16,
-        .hsync_len      = 40,
-        .left_margin    = 46,
-        .right_margin   = 125,
-        .vsync_len      = 3,
-        .upper_margin   = 1,
-        .lower_margin   = 0,
-        .sync           = 0,
-        .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
-        .lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
-        .pxafb_lcd_power = spitz_lcd_power,
+
+static struct pxafb_mode_info spitz_pxafb_modes[] = {
+{
+	.pixclock       = 19231,
+	.xres           = 480,
+	.yres           = 640,
+	.bpp            = 16,
+	.hsync_len      = 40,
+	.left_margin    = 46,
+	.right_margin   = 125,
+	.vsync_len      = 3,
+	.upper_margin   = 1,
+	.lower_margin   = 0,
+	.sync           = 0,
+},{
+	.pixclock       = 134617,
+	.xres           = 240,
+	.yres           = 320,
+	.bpp            = 16,
+	.hsync_len      = 20,
+	.left_margin    = 20,
+	.right_margin   = 46,
+	.vsync_len      = 2,
+	.upper_margin   = 1,
+	.lower_margin   = 0,
+	.sync           = 0,
+},
+};
+
+static struct pxafb_mach_info spitz_pxafb_info = {
+	.modes          = &spitz_pxafb_modes[0],
+	.num_modes      = 2,
+	.fixed_modes    = 1,
+	.lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
+	.lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
+	.pxafb_lcd_power = spitz_lcd_power,
 };
 
 
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 7c3007d..910571e 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -368,7 +368,7 @@
 	}
 };
 
-static struct pxafb_mach_info sharp_lcd __initdata = {
+static struct pxafb_mode_info sharp_lcd_mode = {
     .pixclock		= 78000,
     .xres		= 640,
     .yres		= 480,
@@ -381,6 +381,11 @@
     .lower_margin	= 0,
     .sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
     .cmap_greyscale	= 0,
+};
+
+static struct pxafb_mach_info sharp_lcd = {
+    .modes		= &sharp_lcd_mode,
+    .num_modes	= 1,
     .cmap_inverse	= 0,
     .cmap_static	= 0,
     .lccr0		= LCCR0_Color | LCCR0_Pas | LCCR0_Dual,
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index df37594..63965c7 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -13,7 +13,7 @@
 	bool "Simtec Electronics ANUBIS"
 	select CPU_S3C2440
 	help
-	  Say Y gere if you are using the Simtec Electronics ANUBIS
+	  Say Y here if you are using the Simtec Electronics ANUBIS
 	  development system
 
 config MACH_OSIRIS
diff --git a/arch/arm/mach-s3c2410/s3c2400-gpio.c b/arch/arm/mach-s3c2410/s3c2400-gpio.c
index f2a7817..1576d01 100644
--- a/arch/arm/mach-s3c2410/s3c2400-gpio.c
+++ b/arch/arm/mach-s3c2410/s3c2400-gpio.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/gpio.c
+/* linux/arch/arm/mach-s3c2410/s3c2400-gpio.c
  *
  * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
  *
diff --git a/arch/arm/mach-s3c2410/s3c2410-clock.c b/arch/arm/mach-s3c2410/s3c2410-clock.c
index 9971866..00abe19 100644
--- a/arch/arm/mach-s3c2410/s3c2410-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2410-clock.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/clock.c
+/* linux/arch/arm/mach-s3c2410/s3c2410-clock.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c
index 471a714..a2098f6 100644
--- a/arch/arm/mach-s3c2410/s3c2410-gpio.c
+++ b/arch/arm/mach-s3c2410/s3c2410-gpio.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/gpio.c
+/* linux/arch/arm/mach-s3c2410/s3c2410-gpio.c
  *
  * Copyright (c) 2004-2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2410/s3c2442.c
index debae24..581667e 100644
--- a/arch/arm/mach-s3c2410/s3c2442.c
+++ b/arch/arm/mach-s3c2410/s3c2442.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440.c
+/* linux/arch/arm/mach-s3c2410/s3c2442.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c
index 0d13546..ec702f8 100644
--- a/arch/arm/mach-s3c2410/s3c244x-irq.c
+++ b/arch/arm/mach-s3c2410/s3c244x-irq.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
+/* linux/arch/arm/mach-s3c2410/s3c244x-irq.c
  *
  * Copyright (c) 2003,2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c244x.h b/arch/arm/mach-s3c2410/s3c244x.h
index 3e7f5f7..1488c1e 100644
--- a/arch/arm/mach-s3c2410/s3c244x.h
+++ b/arch/arm/mach-s3c2410/s3c244x.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c2440.h
+/* arch/arm/mach-s3c2410/s3c244x.h
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/usb-simtec.h b/arch/arm/mach-s3c2410/usb-simtec.h
index 92c0cc8..d8aa612 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.h
+++ b/arch/arm/mach-s3c2410/usb-simtec.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/usb-simtec.c
+/* linux/arch/arm/mach-s3c2410/usb-simtec.h
  *
  * Copyright (c) 2004 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
index 3c6441d..2ea2a65 100644
--- a/arch/arm/mach-sa1100/dma.c
+++ b/arch/arm/mach-sa1100/dma.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/kernel/dma-sa1100.c
+ * arch/arm/mach-sa1100/dma.c
  *
  * Support functions for the SA11x0 internal DMA channels.
  *
diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c
index 7cd86d3..5386a81f 100644
--- a/arch/arm/mach-shark/leds.c
+++ b/arch/arm/mach-shark/leds.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/kernel/leds-shark.c
+ * arch/arm/mach-shark/leds.c
  * by Alexander Schulz
  *
  * derived from:
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e566cbe..f866bf6 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -27,7 +27,7 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-extern void _stext, __data_start, _end;
+extern void _stext, _etext, __data_start, _end;
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
 /*
diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c
index 6576143..726ad2b 100644
--- a/arch/arm/oprofile/op_model_xscale.c
+++ b/arch/arm/oprofile/op_model_xscale.c
@@ -33,9 +33,6 @@
 #define PMU_CNT64	0x008	/* Make CCNT count every 64th cycle */
 
 /* TODO do runtime detection */
-#ifdef CONFIG_ARCH_IOP310
-#define XSCALE_PMU_IRQ  IRQ_XS80200_PMU
-#endif
 #ifdef CONFIG_ARCH_IOP32X
 #define XSCALE_PMU_IRQ  IRQ_IOP32X_CORE_PMU
 #endif
diff --git a/arch/arm/plat-omap/sram-fn.S b/arch/arm/plat-omap/sram-fn.S
index 85cffe2..9e1813c 100644
--- a/arch/arm/plat-omap/sram-fn.S
+++ b/arch/arm/plat-omap/sram-fn.S
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/plat-omap/sram.S
+ * linux/arch/arm/plat-omap/sram-fn.S
  *
  * Functions that need to be run in internal SRAM
  *
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index ab5e950..0221ba3 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -198,8 +198,10 @@
 	vfp_single_dump("pack: final", vs);
 	{
 		s32 d = vfp_single_pack(vs);
+#ifdef DEBUG
 		pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func,
 			 sd, d, exceptions);
+#endif
 		vfp_put_float(d, sd);
 	}
 
diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c
index e7eb070..466ddb5 100644
--- a/arch/arm26/kernel/setup.c
+++ b/arch/arm26/kernel/setup.c
@@ -143,7 +143,7 @@
 
 	dump_cpu_info();
 
-	sprintf(system_utsname.machine, "%s", list->arch_name);
+	sprintf(init_utsname()->machine, "%s", list->arch_name);
 	sprintf(elf_platform, "%s", list->elf_name);
 	elf_hwcap = list->elf_hwcap;
 
diff --git a/arch/arm26/kernel/sys_arm.c b/arch/arm26/kernel/sys_arm.c
index 8545789..dc05aba 100644
--- a/arch/arm26/kernel/sys_arm.c
+++ b/arch/arm26/kernel/sys_arm.c
@@ -283,7 +283,7 @@
 }
 
 /* FIXME - see if this is correct for arm26 */
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
 {
 	struct pt_regs regs;
         int ret;
@@ -320,4 +320,4 @@
         return ret;
 }
 
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c
index 6ec5693..8deb600 100644
--- a/arch/avr32/kernel/sys_avr32.c
+++ b/arch/avr32/kernel/sys_avr32.c
@@ -49,3 +49,17 @@
 		fput(file);
 	return error;
 }
+
+int kernel_execve(const char *file, char **argv, char **envp)
+{
+	register long scno asm("r8") = __NR_execve;
+	register long sc1 asm("r12") = (long)file;
+	register long sc2 asm("r11") = (long)argv;
+	register long sc3 asm("r10") = (long)envp;
+
+	asm volatile("scall"
+		     : "=r"(sc1)
+		     : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
+		     : "cc", "memory");
+	return sc1;
+}
diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig
index 8b50e84..734d5f3 100644
--- a/arch/cris/arch-v10/drivers/Kconfig
+++ b/arch/cris/arch-v10/drivers/Kconfig
@@ -550,7 +550,7 @@
 	select BLK_DEV_IDEDMA
 	help
 	  Enable this to get support for ATA/IDE.
-	  You can't use paralell ports or SCSI ports
+	  You can't use parallel ports or SCSI ports
 	  at the same time.
 
 
@@ -744,7 +744,7 @@
 	default "FF"
 	help
 	  This is a bitmask with information of what bits in PA that a user
-	  can change change the value on using ioctl's.
+	  can change the value on using ioctl's.
 	  Bit set = changeable.
 	  You probably want 00 here.
 
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
index 22f0ddc..4f79d8e 100644
--- a/arch/cris/arch-v32/Kconfig
+++ b/arch/cris/arch-v32/Kconfig
@@ -162,7 +162,7 @@
 	depends on ETRAX_ARCH_V32
 	default "0"
 	help
-	  SDRAM configuration for group 1. The defult value is 0
+	  SDRAM configuration for group 1. The default value is 0
 	  because group 1 is not used in the default configuration,
 	  described in the help for SDRAM_GRP0_CONFIG.
 
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 464ecae..2d0023f 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -28,6 +28,7 @@
 
 /* CPU masks */
 cpumask_t cpu_online_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_online_map);
 cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
 EXPORT_SYMBOL(phys_cpu_present_map);
 
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 7af3d5d..ca8b45a 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -160,7 +160,7 @@
 	show_etrax_copyright();
 
 	/* Setup utsname */
-	strcpy(system_utsname.machine, cris_machine_name);
+	strcpy(init_utsname()->machine, cris_machine_name);
 }
 
 static void *c_start(struct seq_file *m, loff_t *pos)
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index f7b171b..cf1c446 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -86,6 +86,14 @@
 	  with a lot of RAM, this can be wasteful of precious low memory.
 	  Setting this option will put user-space page tables in high memory.
 
+config LARGE_ALLOCS
+	bool "Allow allocating large blocks (> 1MB) of memory"
+	help
+	  Allow the slab memory allocator to keep chains for very large memory
+	  sizes - up to 32MB. You may need this if your system has a lot of
+	  RAM, and you need to able to allocate very large contiguous chunks.
+	  If unsure, say N.
+
 source "mm/Kconfig"
 
 choice
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 32db349..e8f73ed 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -8,7 +8,7 @@
 extra-y:= head.o init_task.o vmlinux.lds
 
 obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
-	 process.o traps.o ptrace.o signal.o dma.o \
+	 kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \
 	 sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
 	 debug-stub.o irq.o sleep.o uaccess.o
 
diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S
new file mode 100644
index 0000000..9b074a1
--- /dev/null
+++ b/arch/frv/kernel/kernel_execve.S
@@ -0,0 +1,33 @@
+/* in-kernel program execution
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.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/linkage.h>
+#include <asm/unistd.h>
+
+###############################################################################
+#
+# Do a system call from kernel instead of calling sys_execve so we end up with
+# proper pt_regs.
+#
+# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+#
+# On entry: GR8/GR9/GR10: arguments to function
+# On return: GR8: syscall return.
+#
+###############################################################################
+	.globl		kernel_execve
+	.type		kernel_execve,@function
+kernel_execve:
+	setlos		__NR_execve,gr7
+	tira		gr0,#0
+	bralr
+
+	.size		kernel_execve,.-kernel_execve
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index d96a57e..a8c61da 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -31,7 +31,6 @@
 #include <linux/serial_reg.h>
 
 #include <asm/setup.h>
-#include <asm/serial.h>
 #include <asm/irq.h>
 #include <asm/sections.h>
 #include <asm/pgalloc.h>
diff --git a/arch/h8300/kernel/ints.c b/arch/h8300/kernel/ints.c
index 1488b6a..1bfc77e 100644
--- a/arch/h8300/kernel/ints.c
+++ b/arch/h8300/kernel/ints.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/h8300/platform/h8300h/ints.c
+ * linux/arch/h8300/kernel/ints.c
  *
  * Yoshinori Sato <ysato@users.sourceforge.jp>
  *
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index 0f61b7a..302a2df 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -25,6 +25,7 @@
 #include <asm/cachectl.h>
 #include <asm/traps.h>
 #include <asm/ipc.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -280,3 +281,26 @@
                ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
 }
 #endif
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long res __asm__("er0");
+	register const char * _a __asm__("er1") = filename;
+	register void *_b __asm__("er2") = argv;
+	register void *_c __asm__("er3") = envp;
+	__asm__ __volatile__ ("mov.l %1,er0\n\t"
+			"trapa	#0\n\t"
+			: "=r" (res)
+			: "g" (__NR_execve),
+			  "g" (_a),
+			  "g" (_b),
+			  "g" (_c)
+			: "cc", "memory");
+	return res;
+}
+
+
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 3fd2f25..8ff1c6f 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -682,7 +682,7 @@
 	depends on ACPI
 	default n
 	---help---
-	This enables the the kernel to boot on EFI platforms using
+	This enables the kernel to boot on EFI platforms using
 	system configuration information passed to it from the firmware.
 	This also enables the kernel to use any EFI runtime services that are
 	available (such as the EFI variable services).
@@ -1142,7 +1142,7 @@
 
 config KPROBES
 	bool "Kprobes (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && MODULES
+	depends on KALLSYMS && EXPERIMENTAL && MODULES
 	help
 	  Kprobes allows you to trap at almost any kernel address and
 	  execute a callback function.  register_kprobe() establishes
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 1aaea6a..92f79cd 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -62,8 +62,6 @@
 #include <mach_mpparse.h>
 #endif				/* CONFIG_X86_LOCAL_APIC */
 
-static inline int gsi_irq_sharing(int gsi) { return gsi; }
-
 #endif				/* X86 */
 
 #define BAD_MADT_ENTRY(entry, end) (					    \
@@ -468,12 +466,7 @@
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-#ifdef CONFIG_X86_IO_APIC
-	if (use_pci_vector() && !platform_legacy_irq(gsi))
-		*irq = IO_APIC_VECTOR(gsi);
-	else
-#endif
-		*irq = gsi_irq_sharing(gsi);
+	*irq = gsi;
 	return 0;
 }
 
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 2799baa..d9f3e3c 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -184,7 +184,16 @@
 
 static int __init x86_fxsr_setup(char * s)
 {
+	/* Tell all the other CPU's to not use it... */
 	disable_x86_fxsr = 1;
+
+	/*
+	 * ... and clear the bits early in the boot_cpu_data
+	 * so that the bootup process doesn't try to do this
+	 * either.
+	 */
+	clear_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability);
+	clear_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability);
 	return 1;
 }
 __setup("nofxsr", x86_fxsr_setup);
@@ -660,8 +669,7 @@
 	 */
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
-	if (current->mm)
-		BUG();
+	BUG_ON(current->mm);
 	enter_lazy_tlb(&init_mm, current);
 
 	load_esp0(t, thread);
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index f943698..8b40648 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -498,8 +498,7 @@
 		check_range_for_systab(md);
 	}
 
-	if (!efi.systab)
-		BUG();
+	BUG_ON(!efi.systab);
 
 	status = phys_efi_set_virtual_address_map(
 			memmap.desc_size * memmap.nr_map,
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index ea5f4e7..d07ed31 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -34,35 +34,15 @@
  * moves to arch independent land
  */
 
-DEFINE_SPINLOCK(i8259A_lock);
-
-static void end_8259A_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
-							irq_desc[irq].action)
-		enable_8259A_irq(irq);
-}
-
-#define shutdown_8259A_irq	disable_8259A_irq
-
 static int i8259A_auto_eoi;
-
+DEFINE_SPINLOCK(i8259A_lock);
 static void mask_and_ack_8259A(unsigned int);
 
-unsigned int startup_8259A_irq(unsigned int irq)
-{ 
-	enable_8259A_irq(irq);
-	return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type i8259A_irq_type = {
-	.typename = "XT-PIC",
-	.startup = startup_8259A_irq,
-	.shutdown = shutdown_8259A_irq,
-	.enable = enable_8259A_irq,
-	.disable = disable_8259A_irq,
-	.ack = mask_and_ack_8259A,
-	.end = end_8259A_irq,
+static struct irq_chip i8259A_chip = {
+	.name		= "XT-PIC",
+	.mask		= disable_8259A_irq,
+	.unmask		= enable_8259A_irq,
+	.mask_ack	= mask_and_ack_8259A,
 };
 
 /*
@@ -133,7 +113,7 @@
 {
 	disable_irq_nosync(irq);
 	io_apic_irqs &= ~(1<<irq);
-	irq_desc[irq].chip = &i8259A_irq_type;
+	set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
 	enable_irq(irq);
 }
 
@@ -327,12 +307,12 @@
 	outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
 	if (auto_eoi)
 		/*
-		 * in AEOI mode we just have to mask the interrupt
+		 * In AEOI mode we just have to mask the interrupt
 		 * when acking.
 		 */
-		i8259A_irq_type.ack = disable_8259A_irq;
+		i8259A_chip.mask_ack = disable_8259A_irq;
 	else
-		i8259A_irq_type.ack = mask_and_ack_8259A;
+		i8259A_chip.mask_ack = mask_and_ack_8259A;
 
 	udelay(100);		/* wait for 8259A to initialize */
 
@@ -389,12 +369,13 @@
 			/*
 			 * 16 old-style INTA-cycle interrupts:
 			 */
-			irq_desc[i].chip = &i8259A_irq_type;
+			set_irq_chip_and_handler(i, &i8259A_chip,
+						 handle_level_irq);
 		} else {
 			/*
 			 * 'high' PCI IRQs filled in on demand
 			 */
-			irq_desc[i].chip = &no_irq_type;
+			irq_desc[i].chip = &no_irq_chip;
 		}
 	}
 }
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index fd0df75..b7287fb 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -31,6 +31,9 @@
 #include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/sysdev.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/htirq.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -38,6 +41,8 @@
 #include <asm/timer.h>
 #include <asm/i8259.h>
 #include <asm/nmi.h>
+#include <asm/msidef.h>
+#include <asm/hypertransport.h>
 
 #include <mach_apic.h>
 #include <mach_apicdef.h>
@@ -86,15 +91,6 @@
 	int apic, pin, next;
 } irq_2_pin[PIN_MAP_SIZE];
 
-int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
-#ifdef CONFIG_PCI_MSI
-#define vector_to_irq(vector) 	\
-	(platform_legacy_irq(vector) ? vector : vector_irq[vector])
-#else
-#define vector_to_irq(vector)	(vector)
-#endif
-
-
 union entry_union {
 	struct { u32 w1, w2; };
 	struct IO_APIC_route_entry entry;
@@ -280,7 +276,7 @@
 			break;
 		entry = irq_2_pin + entry->next;
 	}
-	set_irq_info(irq, cpumask);
+	set_native_irq_info(irq, cpumask);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
@@ -1181,46 +1177,45 @@
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
 u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
 
-int assign_irq_vector(int irq)
+static int __assign_irq_vector(int irq)
 {
 	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
-	unsigned long flags;
 	int vector;
 
-	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
+	BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
 
-	spin_lock_irqsave(&vector_lock, flags);
-
-	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
-		spin_unlock_irqrestore(&vector_lock, flags);
+	if (IO_APIC_VECTOR(irq) > 0)
 		return IO_APIC_VECTOR(irq);
-	}
-next:
+
 	current_vector += 8;
 	if (current_vector == SYSCALL_VECTOR)
-		goto next;
+		current_vector += 8;
 
 	if (current_vector >= FIRST_SYSTEM_VECTOR) {
 		offset++;
-		if (!(offset%8)) {
-			spin_unlock_irqrestore(&vector_lock, flags);
+		if (!(offset % 8))
 			return -ENOSPC;
-		}
 		current_vector = FIRST_DEVICE_VECTOR + offset;
 	}
 
 	vector = current_vector;
-	vector_irq[vector] = irq;
-	if (irq != AUTO_ASSIGN)
-		IO_APIC_VECTOR(irq) = vector;
-
-	spin_unlock_irqrestore(&vector_lock, flags);
+	IO_APIC_VECTOR(irq) = vector;
 
 	return vector;
 }
 
-static struct hw_interrupt_type ioapic_level_type;
-static struct hw_interrupt_type ioapic_edge_type;
+static int assign_irq_vector(int irq)
+{
+	unsigned long flags;
+	int vector;
+
+	spin_lock_irqsave(&vector_lock, flags);
+	vector = __assign_irq_vector(irq);
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	return vector;
+}
+static struct irq_chip ioapic_chip;
 
 #define IOAPIC_AUTO	-1
 #define IOAPIC_EDGE	0
@@ -1228,16 +1223,14 @@
 
 static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
 {
-	unsigned idx;
-
-	idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;
-
 	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
 			trigger == IOAPIC_LEVEL)
-		irq_desc[idx].chip = &ioapic_level_type;
+		set_irq_chip_and_handler(irq, &ioapic_chip,
+					 handle_fasteoi_irq);
 	else
-		irq_desc[idx].chip = &ioapic_edge_type;
-	set_intr_gate(vector, interrupt[idx]);
+		set_irq_chip_and_handler(irq, &ioapic_chip,
+					 handle_edge_irq);
+	set_intr_gate(vector, interrupt[irq]);
 }
 
 static void __init setup_IO_APIC_irqs(void)
@@ -1346,7 +1339,8 @@
 	 * The timer IRQ doesn't have to know that behind the
 	 * scene we have a 8259A-master in AEOI mode ...
 	 */
-	irq_desc[0].chip = &ioapic_edge_type;
+	irq_desc[0].chip = &ioapic_chip;
+	set_irq_handler(0, handle_edge_irq);
 
 	/*
 	 * Add it to the IO-APIC irq-routing table:
@@ -1481,17 +1475,12 @@
 		);
 	}
 	}
-	if (use_pci_vector())
-		printk(KERN_INFO "Using vector-based indexing\n");
 	printk(KERN_DEBUG "IRQ to pin mappings:\n");
 	for (i = 0; i < NR_IRQS; i++) {
 		struct irq_pin_list *entry = irq_2_pin + i;
 		if (entry->pin < 0)
 			continue;
- 		if (use_pci_vector() && !platform_legacy_irq(i))
-			printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
-		else
-			printk(KERN_DEBUG "IRQ%d ", i);
+		printk(KERN_DEBUG "IRQ%d ", i);
 		for (;;) {
 			printk("-> %d:%d", entry->apic, entry->pin);
 			if (!entry->next)
@@ -1918,6 +1907,8 @@
  */
 
 /*
+ * Startup quirk:
+ *
  * Starting up a edge-triggered IO-APIC interrupt is
  * nasty - we need to make sure that we get the edge.
  * If it is already asserted for some reason, we need
@@ -1925,8 +1916,10 @@
  *
  * This is not complete - we should be able to fake
  * an edge even if it isn't on the 8259A...
+ *
+ * (We do this for level-triggered IRQs too - it cannot hurt.)
  */
-static unsigned int startup_edge_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(unsigned int irq)
 {
 	int was_pending = 0;
 	unsigned long flags;
@@ -1943,47 +1936,18 @@
 	return was_pending;
 }
 
-/*
- * Once we have recorded IRQ_PENDING already, we can mask the
- * interrupt for real. This prevents IRQ storms from unhandled
- * devices.
- */
-static void ack_edge_ioapic_irq(unsigned int irq)
+static void ack_ioapic_irq(unsigned int irq)
 {
-	move_irq(irq);
-	if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
-					== (IRQ_PENDING | IRQ_DISABLED))
-		mask_IO_APIC_irq(irq);
+	move_native_irq(irq);
 	ack_APIC_irq();
 }
 
-/*
- * Level triggered interrupts can just be masked,
- * and shutting down and starting up the interrupt
- * is the same as enabling and disabling them -- except
- * with a startup need to return a "was pending" value.
- *
- * Level triggered interrupts are special because we
- * do not touch any IO-APIC register while handling
- * them. We ack the APIC in the end-IRQ handler, not
- * in the start-IRQ-handler. Protection against reentrance
- * from the same interrupt is still provided, both by the
- * generic IRQ layer and by the fact that an unacked local
- * APIC does not accept IRQs.
- */
-static unsigned int startup_level_ioapic_irq (unsigned int irq)
-{
-	unmask_IO_APIC_irq(irq);
-
-	return 0; /* don't check for pending */
-}
-
-static void end_level_ioapic_irq (unsigned int irq)
+static void ack_ioapic_quirk_irq(unsigned int irq)
 {
 	unsigned long v;
 	int i;
 
-	move_irq(irq);
+	move_native_irq(irq);
 /*
  * It appears there is an erratum which affects at least version 0x11
  * of I/O APIC (that's the 82093AA and cores integrated into various
@@ -2018,105 +1982,26 @@
 	}
 }
 
-#ifdef CONFIG_PCI_MSI
-static unsigned int startup_edge_ioapic_vector(unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	return startup_edge_ioapic_irq(irq);
-}
-
-static void ack_edge_ioapic_vector(unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	move_native_irq(vector);
-	ack_edge_ioapic_irq(irq);
-}
-
-static unsigned int startup_level_ioapic_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	return startup_level_ioapic_irq (irq);
-}
-
-static void end_level_ioapic_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	move_native_irq(vector);
-	end_level_ioapic_irq(irq);
-}
-
-static void mask_IO_APIC_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	mask_IO_APIC_irq(irq);
-}
-
-static void unmask_IO_APIC_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	unmask_IO_APIC_irq(irq);
-}
-
-#ifdef CONFIG_SMP
-static void set_ioapic_affinity_vector (unsigned int vector,
-					cpumask_t cpu_mask)
-{
-	int irq = vector_to_irq(vector);
-
-	set_native_irq_info(vector, cpu_mask);
-	set_ioapic_affinity_irq(irq, cpu_mask);
-}
-#endif
-#endif
-
-static int ioapic_retrigger(unsigned int irq)
+static int ioapic_retrigger_irq(unsigned int irq)
 {
 	send_IPI_self(IO_APIC_VECTOR(irq));
 
 	return 1;
 }
 
-/*
- * Level and edge triggered IO-APIC interrupts need different handling,
- * so we use two separate IRQ descriptors. Edge triggered IRQs can be
- * handled with the level-triggered descriptor, but that one has slightly
- * more overhead. Level-triggered interrupts cannot be handled with the
- * edge-triggered handler, without risking IRQ storms and other ugly
- * races.
- */
-static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
-	.typename 	= "IO-APIC-edge",
-	.startup 	= startup_edge_ioapic,
-	.shutdown 	= shutdown_edge_ioapic,
-	.enable 	= enable_edge_ioapic,
-	.disable 	= disable_edge_ioapic,
-	.ack 		= ack_edge_ioapic,
-	.end 		= end_edge_ioapic,
+static struct irq_chip ioapic_chip __read_mostly = {
+	.name 		= "IO-APIC",
+	.startup 	= startup_ioapic_irq,
+	.mask	 	= mask_IO_APIC_irq,
+	.unmask	 	= unmask_IO_APIC_irq,
+	.ack 		= ack_ioapic_irq,
+	.eoi 		= ack_ioapic_quirk_irq,
 #ifdef CONFIG_SMP
-	.set_affinity 	= set_ioapic_affinity,
+	.set_affinity 	= set_ioapic_affinity_irq,
 #endif
-	.retrigger	= ioapic_retrigger,
+	.retrigger	= ioapic_retrigger_irq,
 };
 
-static struct hw_interrupt_type ioapic_level_type __read_mostly = {
-	.typename 	= "IO-APIC-level",
-	.startup 	= startup_level_ioapic,
-	.shutdown 	= shutdown_level_ioapic,
-	.enable 	= enable_level_ioapic,
-	.disable 	= disable_level_ioapic,
-	.ack 		= mask_and_ack_level_ioapic,
-	.end 		= end_level_ioapic,
-#ifdef CONFIG_SMP
-	.set_affinity 	= set_ioapic_affinity,
-#endif
-	.retrigger	= ioapic_retrigger,
-};
 
 static inline void init_IO_APIC_traps(void)
 {
@@ -2135,11 +2020,6 @@
 	 */
 	for (irq = 0; irq < NR_IRQS ; irq++) {
 		int tmp = irq;
-		if (use_pci_vector()) {
-			if (!platform_legacy_irq(tmp))
-				if ((tmp = vector_to_irq(tmp)) == -1)
-					continue;
-		}
 		if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
 			/*
 			 * Hmm.. We don't have an entry for this,
@@ -2150,20 +2030,21 @@
 				make_8259A_irq(irq);
 			else
 				/* Strange. Oh, well.. */
-				irq_desc[irq].chip = &no_irq_type;
+				irq_desc[irq].chip = &no_irq_chip;
 		}
 	}
 }
 
-static void enable_lapic_irq (unsigned int irq)
-{
-	unsigned long v;
+/*
+ * The local APIC irq-chip implementation:
+ */
 
-	v = apic_read(APIC_LVT0);
-	apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
+static void ack_apic(unsigned int irq)
+{
+	ack_APIC_irq();
 }
 
-static void disable_lapic_irq (unsigned int irq)
+static void mask_lapic_irq (unsigned int irq)
 {
 	unsigned long v;
 
@@ -2171,21 +2052,19 @@
 	apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
 }
 
-static void ack_lapic_irq (unsigned int irq)
+static void unmask_lapic_irq (unsigned int irq)
 {
-	ack_APIC_irq();
+	unsigned long v;
+
+	v = apic_read(APIC_LVT0);
+	apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
 }
 
-static void end_lapic_irq (unsigned int i) { /* nothing */ }
-
-static struct hw_interrupt_type lapic_irq_type __read_mostly = {
-	.typename 	= "local-APIC-edge",
-	.startup 	= NULL, /* startup_irq() not used for IRQ0 */
-	.shutdown 	= NULL, /* shutdown_irq() not used for IRQ0 */
-	.enable 	= enable_lapic_irq,
-	.disable 	= disable_lapic_irq,
-	.ack 		= ack_lapic_irq,
-	.end 		= end_lapic_irq
+static struct irq_chip lapic_chip __read_mostly = {
+	.name		= "local-APIC-edge",
+	.mask		= mask_lapic_irq,
+	.unmask		= unmask_lapic_irq,
+	.eoi		= ack_apic,
 };
 
 static void setup_nmi (void)
@@ -2356,7 +2235,7 @@
 	printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
 
 	disable_8259A_irq(0);
-	irq_desc[0].chip = &lapic_irq_type;
+	set_irq_chip_and_handler(0, &lapic_chip, handle_fasteoi_irq);
 	apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);	/* Fixed mode */
 	enable_8259A_irq(0);
 
@@ -2531,6 +2410,238 @@
 
 device_initcall(ioapic_init_sysfs);
 
+/*
+ * Dynamic irq allocate and deallocation
+ */
+int create_irq(void)
+{
+	/* Allocate an unused irq */
+	int irq, new, vector;
+	unsigned long flags;
+
+	irq = -ENOSPC;
+	spin_lock_irqsave(&vector_lock, flags);
+	for (new = (NR_IRQS - 1); new >= 0; new--) {
+		if (platform_legacy_irq(new))
+			continue;
+		if (irq_vector[new] != 0)
+			continue;
+		vector = __assign_irq_vector(new);
+		if (likely(vector > 0))
+			irq = new;
+		break;
+	}
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	if (irq >= 0) {
+		set_intr_gate(vector, interrupt[irq]);
+		dynamic_irq_init(irq);
+	}
+	return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	dynamic_irq_cleanup(irq);
+
+	spin_lock_irqsave(&vector_lock, flags);
+	irq_vector[irq] = 0;
+	spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+/*
+ * MSI mesage composition
+ */
+#ifdef CONFIG_PCI_MSI
+static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+{
+	int vector;
+	unsigned dest;
+
+	vector = assign_irq_vector(irq);
+	if (vector >= 0) {
+		dest = cpu_mask_to_apicid(TARGET_CPUS);
+
+		msg->address_hi = MSI_ADDR_BASE_HI;
+		msg->address_lo =
+			MSI_ADDR_BASE_LO |
+			((INT_DEST_MODE == 0) ?
+				MSI_ADDR_DEST_MODE_PHYSICAL:
+				MSI_ADDR_DEST_MODE_LOGICAL) |
+			((INT_DELIVERY_MODE != dest_LowestPrio) ?
+				MSI_ADDR_REDIRECTION_CPU:
+				MSI_ADDR_REDIRECTION_LOWPRI) |
+			MSI_ADDR_DEST_ID(dest);
+
+		msg->data =
+			MSI_DATA_TRIGGER_EDGE |
+			MSI_DATA_LEVEL_ASSERT |
+			((INT_DELIVERY_MODE != dest_LowestPrio) ?
+				MSI_DATA_DELIVERY_FIXED:
+				MSI_DATA_DELIVERY_LOWPRI) |
+			MSI_DATA_VECTOR(vector);
+	}
+	return vector;
+}
+
+#ifdef CONFIG_SMP
+static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+	struct msi_msg msg;
+	unsigned int dest;
+	cpumask_t tmp;
+	int vector;
+
+	cpus_and(tmp, mask, cpu_online_map);
+	if (cpus_empty(tmp))
+		tmp = TARGET_CPUS;
+
+	vector = assign_irq_vector(irq);
+	if (vector < 0)
+		return;
+
+	dest = cpu_mask_to_apicid(mask);
+
+	read_msi_msg(irq, &msg);
+
+	msg.data &= ~MSI_DATA_VECTOR_MASK;
+	msg.data |= MSI_DATA_VECTOR(vector);
+	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+	write_msi_msg(irq, &msg);
+	set_native_irq_info(irq, mask);
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
+ * which implement the MSI or MSI-X Capability Structure.
+ */
+static struct irq_chip msi_chip = {
+	.name		= "PCI-MSI",
+	.unmask		= unmask_msi_irq,
+	.mask		= mask_msi_irq,
+	.ack		= ack_ioapic_irq,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_msi_irq_affinity,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev)
+{
+	struct msi_msg msg;
+	int ret;
+	ret = msi_compose_msg(dev, irq, &msg);
+	if (ret < 0)
+		return ret;
+
+	write_msi_msg(irq, &msg);
+
+	set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq);
+
+	return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	return;
+}
+
+#endif /* CONFIG_PCI_MSI */
+
+/*
+ * Hypertransport interrupt support
+ */
+#ifdef CONFIG_HT_IRQ
+
+#ifdef CONFIG_SMP
+
+static void target_ht_irq(unsigned int irq, unsigned int dest)
+{
+	u32 low, high;
+	low  = read_ht_irq_low(irq);
+	high = read_ht_irq_high(irq);
+
+	low  &= ~(HT_IRQ_LOW_DEST_ID_MASK);
+	high &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
+
+	low  |= HT_IRQ_LOW_DEST_ID(dest);
+	high |= HT_IRQ_HIGH_DEST_ID(dest);
+
+	write_ht_irq_low(irq, low);
+	write_ht_irq_high(irq, high);
+}
+
+static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+	unsigned int dest;
+	cpumask_t tmp;
+
+	cpus_and(tmp, mask, cpu_online_map);
+	if (cpus_empty(tmp))
+		tmp = TARGET_CPUS;
+
+	cpus_and(mask, tmp, CPU_MASK_ALL);
+
+	dest = cpu_mask_to_apicid(mask);
+
+	target_ht_irq(irq, dest);
+	set_native_irq_info(irq, mask);
+}
+#endif
+
+static struct hw_interrupt_type ht_irq_chip = {
+	.name		= "PCI-HT",
+	.mask		= mask_ht_irq,
+	.unmask		= unmask_ht_irq,
+	.ack		= ack_ioapic_irq,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_ht_irq_affinity,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
+{
+	int vector;
+
+	vector = assign_irq_vector(irq);
+	if (vector >= 0) {
+		u32 low, high;
+		unsigned dest;
+		cpumask_t tmp;
+
+		cpus_clear(tmp);
+		cpu_set(vector >> 8, tmp);
+		dest = cpu_mask_to_apicid(tmp);
+
+		high = 	HT_IRQ_HIGH_DEST_ID(dest);
+
+		low =	HT_IRQ_LOW_BASE |
+			HT_IRQ_LOW_DEST_ID(dest) |
+			HT_IRQ_LOW_VECTOR(vector) |
+			((INT_DEST_MODE == 0) ?
+				HT_IRQ_LOW_DM_PHYSICAL :
+				HT_IRQ_LOW_DM_LOGICAL) |
+			HT_IRQ_LOW_RQEOI_EDGE |
+			((INT_DELIVERY_MODE != dest_LowestPrio) ?
+				HT_IRQ_LOW_MT_FIXED :
+				HT_IRQ_LOW_MT_ARBITRATED) |
+			HT_IRQ_LOW_IRQ_MASKED;
+
+		write_ht_irq_low(irq, low);
+		write_ht_irq_high(irq, high);
+
+		set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq);
+	}
+	return vector;
+}
+#endif /* CONFIG_HT_IRQ */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- */
@@ -2684,7 +2795,7 @@
 
 	ioapic_write_entry(ioapic, pin, entry);
 	spin_lock_irqsave(&ioapic_lock, flags);
-	set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
+	set_native_irq_info(irq, TARGET_CPUS);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return 0;
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 5fe547c..3dd2e18 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -55,6 +55,7 @@
 {	
 	/* high bit used in ret_from_ code */
 	int irq = ~regs->orig_eax;
+	struct irq_desc *desc = irq_desc + irq;
 #ifdef CONFIG_4KSTACKS
 	union irq_ctx *curctx, *irqctx;
 	u32 *isp;
@@ -94,7 +95,7 @@
 	 * current stack (which is the irq stack already after all)
 	 */
 	if (curctx != irqctx) {
-		int arg1, arg2, ebx;
+		int arg1, arg2, arg3, ebx;
 
 		/* build the stack frame on the IRQ stack */
 		isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
@@ -110,16 +111,17 @@
 			(curctx->tinfo.preempt_count & SOFTIRQ_MASK);
 
 		asm volatile(
-			"       xchgl   %%ebx,%%esp      \n"
-			"       call    __do_IRQ         \n"
+			"       xchgl  %%ebx,%%esp      \n"
+			"       call   *%%edi           \n"
 			"       movl   %%ebx,%%esp      \n"
-			: "=a" (arg1), "=d" (arg2), "=b" (ebx)
-			:  "0" (irq),   "1" (regs),  "2" (isp)
-			: "memory", "cc", "ecx"
+			: "=a" (arg1), "=d" (arg2), "=c" (arg3), "=b" (ebx)
+			:  "0" (irq),   "1" (desc),  "2" (regs),  "3" (isp),
+			   "D" (desc->handle_irq)
+			: "memory", "cc"
 		);
 	} else
 #endif
-		__do_IRQ(irq, regs);
+		desc->handle_irq(irq, desc, regs);
 
 	irq_exit();
 
@@ -253,7 +255,8 @@
 		for_each_online_cpu(j)
 			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
-		seq_printf(p, " %14s", irq_desc[i].chip->typename);
+		seq_printf(p, " %8s", irq_desc[i].chip->name);
+		seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index afe6505..d98e44b 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -230,20 +230,20 @@
 				      struct pt_regs *regs)
 {
 	unsigned long *sara = (unsigned long *)&regs->esp;
-        struct kretprobe_instance *ri;
 
-        if ((ri = get_free_rp_inst(rp)) != NULL) {
-                ri->rp = rp;
-                ri->task = current;
+	struct kretprobe_instance *ri;
+
+	if ((ri = get_free_rp_inst(rp)) != NULL) {
+		ri->rp = rp;
+		ri->task = current;
 		ri->ret_addr = (kprobe_opcode_t *) *sara;
 
 		/* Replace the return addr with trampoline addr */
 		*sara = (unsigned long) &kretprobe_trampoline;
-
-                add_rp_inst(ri);
-        } else {
-                rp->nmissed++;
-        }
+		add_rp_inst(ri);
+	} else {
+		rp->nmissed++;
+	}
 }
 
 /*
@@ -359,7 +359,7 @@
  void __kprobes kretprobe_trampoline_holder(void)
  {
 	asm volatile ( ".global kretprobe_trampoline\n"
- 			"kretprobe_trampoline: \n"
+			"kretprobe_trampoline: \n"
 			"	pushf\n"
 			/* skip cs, eip, orig_eax, es, ds */
 			"	subl $20, %esp\n"
@@ -395,14 +395,15 @@
  */
 fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
 {
-        struct kretprobe_instance *ri = NULL;
-        struct hlist_head *head;
-        struct hlist_node *node, *tmp;
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head, empty_rp;
+	struct hlist_node *node, *tmp;
 	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+	INIT_HLIST_HEAD(&empty_rp);
 	spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
+	head = kretprobe_inst_table_head(current);
 
 	/*
 	 * It is possible to have multiple instances associated with a given
@@ -413,14 +414,14 @@
 	 * We can handle this because:
 	 *     - instances are always inserted at the head of the list
 	 *     - when multiple return probes are registered for the same
-         *       function, the first instance's ret_addr will point to the
+	 *       function, the first instance's ret_addr will point to the
 	 *       real return address, and all the rest will point to
 	 *       kretprobe_trampoline
 	 */
 	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
+		if (ri->task != current)
 			/* another task is sharing our hash bucket */
-                        continue;
+			continue;
 
 		if (ri->rp && ri->rp->handler){
 			__get_cpu_var(current_kprobe) = &ri->rp->kp;
@@ -429,7 +430,7 @@
 		}
 
 		orig_ret_address = (unsigned long)ri->ret_addr;
-		recycle_rp_inst(ri);
+		recycle_rp_inst(ri, &empty_rp);
 
 		if (orig_ret_address != trampoline_address)
 			/*
@@ -444,6 +445,10 @@
 
 	spin_unlock_irqrestore(&kretprobe_lock, flags);
 
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
 	return (void*)orig_ret_address;
 }
 
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index 983f957..445211e 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -1,5 +1,5 @@
 /*
- * linux/kernel/ldt.c
+ * linux/arch/i386/kernel/ldt.c
  *
  * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
  * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 96cd023..dad02a9 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -297,9 +297,9 @@
 	if (user_mode_vm(regs))
 		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
 	printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
-	       regs->eflags, print_tainted(), system_utsname.release,
-	       (int)strcspn(system_utsname.version, " "),
-	       system_utsname.version);
+	       regs->eflags, print_tainted(), init_utsname()->release,
+	       (int)strcspn(init_utsname()->version, " "),
+	       init_utsname()->version);
 	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
 		regs->eax,regs->ebx,regs->ecx,regs->edx);
 	printk("ESI: %08lx EDI: %08lx EBP: %08lx",
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 0831f70..4bb8b77 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -612,6 +612,7 @@
 /* which logical CPUs are on which nodes */
 cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly =
 				{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
+EXPORT_SYMBOL(node_2_cpu_mask);
 /* which node each logical CPU is on */
 int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
 EXPORT_SYMBOL(cpu_2_node);
@@ -647,7 +648,7 @@
 {
 	int cpu = smp_processor_id();
 	int apicid = logical_smp_processor_id();
-	int node = apicid_to_node(hard_smp_processor_id());
+	int node = apicid_to_node(apicid);
 
 	if (!node_online(node))
 		node = first_online_node;
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index 8fdb1fb..4048397 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -21,6 +21,7 @@
 #include <linux/utsname.h>
 
 #include <asm/uaccess.h>
+#include <asm/unistd.h>
 #include <asm/ipc.h>
 
 /*
@@ -210,7 +211,7 @@
 	if (!name)
 		return -EFAULT;
 	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	return err?-EFAULT:0;
 }
@@ -226,16 +227,21 @@
   
   	down_read(&uts_sem);
 	
-	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
-	error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
-	error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
-	error |= __put_user(0,name->release+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
-	error |= __put_user(0,name->version+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-	error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+	error = __copy_to_user(&name->sysname, &utsname()->sysname,
+			       __OLD_UTS_LEN);
+	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+				__OLD_UTS_LEN);
+	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->release, &utsname()->release,
+				__OLD_UTS_LEN);
+	error |= __put_user(0, name->release + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->version, &utsname()->version,
+				__OLD_UTS_LEN);
+	error |= __put_user(0, name->version + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->machine, &utsname()->machine,
+				__OLD_UTS_LEN);
+	error |= __put_user(0, name->machine + __OLD_UTS_LEN);
 	
 	up_read(&uts_sem);
 	
@@ -243,3 +249,17 @@
 
 	return error;
 }
+
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
+	: "=a" (__res)
+	: "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory");
+	return __res;
+}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 6820b8d..00489b7 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -357,9 +357,9 @@
 		KERN_EMERG "EIP:    %04x:[<%08lx>]    %s VLI\n"
 		KERN_EMERG "EFLAGS: %08lx   (%s %.*s)\n",
 		smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-		print_tainted(), regs->eflags, system_utsname.release,
-		(int)strcspn(system_utsname.version, " "),
-		system_utsname.version);
+		print_tainted(), regs->eflags, init_utsname()->release,
+		(int)strcspn(init_utsname()->version, " "),
+		init_utsname()->version);
 	print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
 	printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
 		regs->eax, regs->ebx, regs->ecx, regs->edx);
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
index 8285225..5929f884 100644
--- a/arch/i386/mach-visws/visws_apic.c
+++ b/arch/i386/mach-visws/visws_apic.c
@@ -1,5 +1,5 @@
 /*
- *	linux/arch/i386/mach_visws/visws_apic.c
+ *	linux/arch/i386/mach-visws/visws_apic.c
  *
  *	Copyright (C) 1999 Bent Hagemark, Ingo Molnar
  *
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 51e3739..455597d 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -153,8 +153,7 @@
 	 */
 	if (node_start_pfn[nid] > max_pfn)
 		node_start_pfn[nid] = max_pfn;
-	if (node_start_pfn[nid] > node_end_pfn[nid])
-		BUG();
+	BUG_ON(node_start_pfn[nid] > node_end_pfn[nid]);
 }
 
 /* 
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 90089c1..1674161 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -569,8 +569,7 @@
 	int bad_ppro;
 
 #ifdef CONFIG_FLATMEM
-	if (!mem_map)
-		BUG();
+	BUG_ON(!mem_map);
 #endif
 	
 	bad_ppro = ppro_with_ram_bug();
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 83c3645..b60d7e8 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -393,7 +393,7 @@
  * We pretend to bring them out of full D3 state, and restore the proper
  * IRQ, PCI cache line size, and BARs, otherwise the device won't function
  * properly.  In some cases, the device will generate an interrupt on
- * the wrong IRQ line, causing any devices sharing the the line it's
+ * the wrong IRQ line, causing any devices sharing the line it's
  * *supposed* to use to be disabled by the kernel's IRQ debug code.
  */
 static u16 toshiba_line_size;
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index 4a8995c..47f02af 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -981,10 +981,6 @@
 							pci_name(bridge), 'A' + pin, irq);
 				}
 				if (irq >= 0) {
-					if (use_pci_vector() &&
-						!platform_legacy_irq(irq))
-						irq = IO_APIC_VECTOR(irq);
-
 					printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
 						pci_name(dev), 'A' + pin, irq);
 					dev->irq = irq;
@@ -1169,33 +1165,3 @@
 	}
 	return 0;
 }
-
-int pci_vector_resources(int last, int nr_released)
-{
-	int count = nr_released;
-
-	int next = last;
-	int offset = (last % 8);
-
-	while (next < FIRST_SYSTEM_VECTOR) {
-		next += 8;
-#ifdef CONFIG_X86_64
-		if (next == IA32_SYSCALL_VECTOR)
-			continue;
-#else
-		if (next == SYSCALL_VECTOR)
-			continue;
-#endif
-		count++;
-		if (next >= FIRST_SYSTEM_VECTOR) {
-			if (offset%8) {
-				next = FIRST_DEVICE_VECTOR + offset;
-				offset++;
-				continue;
-			}
-			count--;
-		}
-	}
-
-	return count;
-}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 0b7f701..70f7eb9 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -516,7 +516,7 @@
 
 config KPROBES
 	bool "Kprobes (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && MODULES
+	depends on KALLSYMS && EXPERIMENTAL && MODULES
 	help
 	  Kprobes allows you to trap at almost any kernel address and
 	  execute a callback function.  register_kprobe() establishes
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 0daacc2..246eb3d 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -940,7 +940,7 @@
 	printk(KERN_INFO " no serial options enabled\n");
 }
 
-static struct tty_operations hp_ops = {
+static const struct tty_operations hp_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index bddbd22..9d6a3f2 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -125,6 +125,7 @@
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
 {
+	compat_ino_t ino;
 	int err;
 
 	if ((u64) stat->size > MAX_NON_LFS ||
@@ -132,11 +133,15 @@
 	    !old_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
+	ino = stat->ino;
+	if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+		return -EOVERFLOW;
+
 	if (clear_user(ubuf, sizeof(*ubuf)))
 		return -EFAULT;
 
 	err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
-	err |= __put_user(stat->ino, &ubuf->st_ino);
+	err |= __put_user(ino, &ubuf->st_ino);
 	err |= __put_user(stat->mode, &ubuf->st_mode);
 	err |= __put_user(stat->nlink, &ubuf->st_nlink);
 	err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
@@ -1222,16 +1227,20 @@
 };
 
 static int
-filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
+filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino,
 	   unsigned int d_type)
 {
 	struct compat_dirent __user * dirent;
 	struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
 	int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4);
+	u32 d_ino;
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	buf->error = -EFAULT;	/* only used if we fail.. */
 	dirent = buf->previous;
 	if (dirent)
@@ -1239,7 +1248,7 @@
 			return -EFAULT;
 	dirent = buf->current_dir;
 	buf->previous = dirent;
-	if (put_user(ino, &dirent->d_ino)
+	if (put_user(d_ino, &dirent->d_ino)
 	    || put_user(reclen, &dirent->d_reclen)
 	    || copy_to_user(dirent->d_name, name, namlen)
 	    || put_user(0, dirent->d_name + namlen))
@@ -1287,17 +1296,21 @@
 }
 
 static int
-fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
+fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino,
 	      unsigned int d_type)
 {
 	struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
 	struct old_linux32_dirent __user * dirent;
+	u32 d_ino;
 
 	if (buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	buf->count++;
 	dirent = buf->dirent;
-	if (put_user(ino, &dirent->d_ino)
+	if (put_user(d_ino, &dirent->d_ino)
 	    || put_user(offset, &dirent->d_offset)
 	    || put_user(namlen, &dirent->d_namlen)
 	    || copy_to_user(dirent->d_name, name, namlen)
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 3149749..cfa099b 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -30,6 +30,7 @@
 obj-$(CONFIG_KPROBES)		+= kprobes.o jprobes.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)	+= uncached.o
 obj-$(CONFIG_AUDIT)		+= audit.o
+obj-$(CONFIG_PCI_MSI)		+= msi_ia64.o
 mca_recovery-y			+= mca_drv.o mca_drv_asm.o
 
 obj-$(CONFIG_IA64_ESI)		+= esi.o
diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c
index e683630..4d4993a 100644
--- a/arch/ia64/kernel/acpi-processor.c
+++ b/arch/ia64/kernel/acpi-processor.c
@@ -1,5 +1,5 @@
 /*
- * arch/ia64/kernel/cpufreq/processor.c
+ * arch/ia64/kernel/acpi-processor.c
  *
  * Copyright (C) 2005 Intel Corporation
  * 	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 12701cf..3390b7c 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1,5 +1,5 @@
 /*
- * ia64/kernel/entry.S
+ * arch/ia64/kernel/entry.S
  *
  * Kernel entry points.
  *
@@ -492,11 +492,11 @@
 	br.ret.sptk.many rp
 END(prefetch_stack)
 
-GLOBAL_ENTRY(execve)
+GLOBAL_ENTRY(kernel_execve)
 	mov r15=__NR_execve			// put syscall number in place
 	break __BREAK_SYSCALL
 	br.ret.sptk.many rp
-END(execve)
+END(kernel_execve)
 
 GLOBAL_ENTRY(clone)
 	mov r15=__NR_clone			// put syscall number in place
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index a041367..ab2d19c 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/ia64/kernel/irq.c
+ * linux/arch/ia64/kernel/irq_ia64.c
  *
  * Copyright (C) 1998-2001 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
@@ -30,6 +30,7 @@
 #include <linux/smp_lock.h>
 #include <linux/threads.h>
 #include <linux/bitops.h>
+#include <linux/irq.h>
 
 #include <asm/delay.h>
 #include <asm/intrinsics.h>
@@ -105,6 +106,25 @@
 	return test_and_set_bit(pos, ia64_vector_mask);
 }
 
+/*
+ * Dynamic irq allocate and deallocation for MSI
+ */
+int create_irq(void)
+{
+	int vector = assign_irq_vector(AUTO_ASSIGN);
+
+	if (vector >= 0)
+		dynamic_irq_init(vector);
+
+	return vector;
+}
+
+void destroy_irq(unsigned int irq)
+{
+	dynamic_irq_cleanup(irq);
+	free_irq_vector(irq);
+}
+
 #ifdef CONFIG_SMP
 #	define IS_RESCHEDULE(vec)	(vec == IA64_IPI_RESCHEDULE)
 #else
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 169ec3a..51217d6 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -90,7 +90,7 @@
 	p->ainsn.target_br_reg = 0;
 
 	/* Check for Break instruction
- 	 * Bits 37:40 Major opcode to be zero
+	 * Bits 37:40 Major opcode to be zero
 	 * Bits 27:32 X6 to be zero
 	 * Bits 32:35 X3 to be zero
 	 */
@@ -104,19 +104,19 @@
 		switch (major_opcode) {
 		  case INDIRECT_CALL_OPCODE:
 	 		p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
- 			p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
- 			break;
+			p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+			break;
 		  case IP_RELATIVE_PREDICT_OPCODE:
 		  case IP_RELATIVE_BRANCH_OPCODE:
 			p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
- 			break;
+			break;
 		  case IP_RELATIVE_CALL_OPCODE:
- 			p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
- 			p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
- 			p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
- 			break;
+			p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
+			p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+			p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+			break;
 		}
- 	} else if (bundle_encoding[template][slot] == X) {
+	} else if (bundle_encoding[template][slot] == X) {
 		switch (major_opcode) {
 		  case LONG_CALL_OPCODE:
 			p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
@@ -258,18 +258,18 @@
 
 	switch (slot) {
 	  case 0:
- 		*major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
- 		*kprobe_inst = bundle->quad0.slot0;
-		break;
+		*major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
+		*kprobe_inst = bundle->quad0.slot0;
+		  break;
 	  case 1:
- 		*major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
-  		kprobe_inst_p0 = bundle->quad0.slot1_p0;
-  		kprobe_inst_p1 = bundle->quad1.slot1_p1;
-  		*kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
+		*major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
+		kprobe_inst_p0 = bundle->quad0.slot1_p0;
+		kprobe_inst_p1 = bundle->quad1.slot1_p1;
+		*kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
 		break;
 	  case 2:
- 		*major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
- 		*kprobe_inst = bundle->quad1.slot2;
+		*major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
+		*kprobe_inst = bundle->quad1.slot2;
 		break;
 	}
 }
@@ -290,11 +290,11 @@
 		return -EINVAL;
 	}
 
- 	if (in_ivt_functions(addr)) {
- 		printk(KERN_WARNING "Kprobes can't be inserted inside "
+	if (in_ivt_functions(addr)) {
+		printk(KERN_WARNING "Kprobes can't be inserted inside "
 				"IVT functions at 0x%lx\n", addr);
- 		return -EINVAL;
- 	}
+		return -EINVAL;
+	}
 
 	if (slot == 1 && bundle_encoding[template][1] != L) {
 		printk(KERN_WARNING "Inserting kprobes on slot #1 "
@@ -338,12 +338,13 @@
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kretprobe_instance *ri = NULL;
-	struct hlist_head *head;
+	struct hlist_head *head, empty_rp;
 	struct hlist_node *node, *tmp;
 	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =
 		((struct fnptr *)kretprobe_trampoline)->ip;
 
+	INIT_HLIST_HEAD(&empty_rp);
 	spin_lock_irqsave(&kretprobe_lock, flags);
 	head = kretprobe_inst_table_head(current);
 
@@ -369,7 +370,7 @@
 			ri->rp->handler(ri, regs);
 
 		orig_ret_address = (unsigned long)ri->ret_addr;
-		recycle_rp_inst(ri);
+		recycle_rp_inst(ri, &empty_rp);
 
 		if (orig_ret_address != trampoline_address)
 			/*
@@ -387,6 +388,10 @@
 	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	preempt_enable_no_resched();
 
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
 	/*
 	 * By returning a non-zero value, we are telling
 	 * kprobe_handler() that we don't want the post_handler
@@ -424,14 +429,14 @@
 	bundle_t *bundle;
 
 	bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle;
- 	template = bundle->quad0.template;
+	template = bundle->quad0.template;
 
 	if(valid_kprobe_addr(template, slot, addr))
 		return -EINVAL;
 
 	/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
- 	if (slot == 1 && bundle_encoding[template][1] == L)
-  		slot++;
+	if (slot == 1 && bundle_encoding[template][1] == L)
+		slot++;
 
 	/* Get kprobe_inst and major_opcode from the bundle */
 	get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
@@ -489,21 +494,22 @@
  */
 static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
-  	unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
-  	unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
- 	unsigned long template;
- 	int slot = ((unsigned long)p->addr & 0xf);
+	unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
+	unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
+	unsigned long template;
+	int slot = ((unsigned long)p->addr & 0xf);
 
 	template = p->ainsn.insn->bundle.quad0.template;
 
- 	if (slot == 1 && bundle_encoding[template][1] == L)
- 		slot = 2;
+	if (slot == 1 && bundle_encoding[template][1] == L)
+		slot = 2;
 
 	if (p->ainsn.inst_flag) {
 
 		if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
 			/* Fix relative IP address */
- 			regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr;
+			regs->cr_iip = (regs->cr_iip - bundle_addr) +
+					resume_addr;
 		}
 
 		if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
@@ -540,18 +546,18 @@
 	}
 
 	if (slot == 2) {
- 		if (regs->cr_iip == bundle_addr + 0x10) {
- 			regs->cr_iip = resume_addr + 0x10;
- 		}
- 	} else {
- 		if (regs->cr_iip == bundle_addr) {
- 			regs->cr_iip = resume_addr;
- 		}
+		if (regs->cr_iip == bundle_addr + 0x10) {
+			regs->cr_iip = resume_addr + 0x10;
+		}
+	} else {
+		if (regs->cr_iip == bundle_addr) {
+			regs->cr_iip = resume_addr;
+		}
 	}
 
 turn_ss_off:
-  	/* Turn off Single Step bit */
-  	ia64_psr(regs)->ss = 0;
+	/* Turn off Single Step bit */
+	ia64_psr(regs)->ss = 0;
 }
 
 static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
@@ -587,7 +593,7 @@
 
 	/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
 	if (slot == 1 && bundle_encoding[template][1] == L)
-  		slot++;
+		slot++;
 
 	/* Get Kprobe probe instruction at given slot*/
 	get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode);
@@ -627,7 +633,7 @@
 		if (p) {
 			if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
 	 		     (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
-  				ia64_psr(regs)->ss = 0;
+				ia64_psr(regs)->ss = 0;
 				goto no_kprobe;
 			}
 			/* We have reentered the pre_kprobe_handler(), since
@@ -887,7 +893,7 @@
 	 * fix the return address to our jprobe_inst_return() function
 	 * in the jprobes.S file
 	 */
- 	regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
+	regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
 
 	return 1;
 }
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
new file mode 100644
index 0000000..822e59a
--- /dev/null
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -0,0 +1,143 @@
+/*
+ * MSI hooks for standard x86 apic
+ */
+
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/msi.h>
+#include <asm/smp.h>
+
+/*
+ * Shifts for APIC-based data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT		0
+#define	    MSI_DATA_VECTOR(v)		(((u8)v) << MSI_DATA_VECTOR_SHIFT)
+
+#define MSI_DATA_DELIVERY_SHIFT		8
+#define     MSI_DATA_DELIVERY_FIXED	(0 << MSI_DATA_DELIVERY_SHIFT)
+#define     MSI_DATA_DELIVERY_LOWPRI	(1 << MSI_DATA_DELIVERY_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT		14
+#define     MSI_DATA_LEVEL_DEASSERT	(0 << MSI_DATA_LEVEL_SHIFT)
+#define     MSI_DATA_LEVEL_ASSERT	(1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT		15
+#define     MSI_DATA_TRIGGER_EDGE	(0 << MSI_DATA_TRIGGER_SHIFT)
+#define     MSI_DATA_TRIGGER_LEVEL	(1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for APIC-based bus address
+ */
+
+#define MSI_TARGET_CPU_SHIFT		4
+#define MSI_ADDR_HEADER			0xfee00000
+
+#define MSI_ADDR_DESTID_MASK		0xfff0000f
+#define     MSI_ADDR_DESTID_CPU(cpu)	((cpu) << MSI_TARGET_CPU_SHIFT)
+
+#define MSI_ADDR_DESTMODE_SHIFT		2
+#define     MSI_ADDR_DESTMODE_PHYS	(0 << MSI_ADDR_DESTMODE_SHIFT)
+#define	    MSI_ADDR_DESTMODE_LOGIC	(1 << MSI_ADDR_DESTMODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT	3
+#define     MSI_ADDR_REDIRECTION_CPU	(0 << MSI_ADDR_REDIRECTION_SHIFT)
+#define     MSI_ADDR_REDIRECTION_LOWPRI	(1 << MSI_ADDR_REDIRECTION_SHIFT)
+
+static struct irq_chip	ia64_msi_chip;
+
+#ifdef CONFIG_SMP
+static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
+{
+	struct msi_msg msg;
+	u32 addr;
+
+	read_msi_msg(irq, &msg);
+
+	addr = msg.address_lo;
+	addr &= MSI_ADDR_DESTID_MASK;
+	addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask)));
+	msg.address_lo = addr;
+
+	write_msi_msg(irq, &msg);
+	set_native_irq_info(irq, cpu_mask);
+}
+#endif /* CONFIG_SMP */
+
+int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
+{
+	struct msi_msg	msg;
+	unsigned long	dest_phys_id;
+	unsigned int	vector;
+
+	dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
+	vector = irq;
+
+	msg.address_hi = 0;
+	msg.address_lo =
+		MSI_ADDR_HEADER |
+		MSI_ADDR_DESTMODE_PHYS |
+		MSI_ADDR_REDIRECTION_CPU |
+		MSI_ADDR_DESTID_CPU(dest_phys_id);
+
+	msg.data =
+		MSI_DATA_TRIGGER_EDGE |
+		MSI_DATA_LEVEL_ASSERT |
+		MSI_DATA_DELIVERY_FIXED |
+		MSI_DATA_VECTOR(vector);
+
+	write_msi_msg(irq, &msg);
+	set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
+
+	return 0;
+}
+
+void ia64_teardown_msi_irq(unsigned int irq)
+{
+	return;		/* no-op */
+}
+
+static void ia64_ack_msi_irq(unsigned int irq)
+{
+	move_native_irq(irq);
+	ia64_eoi();
+}
+
+static int ia64_msi_retrigger_irq(unsigned int irq)
+{
+	unsigned int vector = irq;
+	ia64_resend_irq(vector);
+
+	return 1;
+}
+
+/*
+ * Generic ops used on most IA64 platforms.
+ */
+static struct irq_chip ia64_msi_chip = {
+	.name		= "PCI-MSI",
+	.mask		= mask_msi_irq,
+	.unmask		= unmask_msi_irq,
+	.ack		= ia64_ack_msi_irq,
+#ifdef CONFIG_SMP
+	.set_affinity	= ia64_set_msi_irq_affinity,
+#endif
+	.retrigger	= ia64_msi_retrigger_irq,
+};
+
+
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
+{
+	if (platform_setup_msi_irq)
+		return platform_setup_msi_irq(irq, pdev);
+
+	return ia64_setup_msi_irq(irq, pdev);
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	if (platform_teardown_msi_irq)
+		return platform_teardown_msi_irq(irq);
+
+	return ia64_teardown_msi_irq(irq);
+}
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
index 2034063..a78b45f 100644
--- a/arch/ia64/kernel/numa.c
+++ b/arch/ia64/kernel/numa.c
@@ -28,6 +28,7 @@
 EXPORT_SYMBOL(cpu_to_node_map);
 
 cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+EXPORT_SYMBOL(node_to_cpu_mask);
 
 void __cpuinit map_cpu_to_node(int cpu, int nid)
 {
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index ea914cc..51922b9 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -8,8 +8,6 @@
  * 2005-10-07 Keith Owens <kaos@sgi.com>
  *	      Add notify_die() hooks.
  */
-#define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
-
 #include <linux/cpu.h>
 #include <linux/pm.h>
 #include <linux/elf.h>
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 84f93c0..c4caa80 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -54,7 +54,6 @@
 #include <asm/processor.h>
 #include <asm/sal.h>
 #include <asm/sections.h>
-#include <asm/serial.h>
 #include <asm/setup.h>
 #include <asm/smp.h>
 #include <asm/system.h>
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 15c7c67..b30be7c 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -810,12 +810,3 @@
 	}
 	return rc;
 }
-
-int pci_vector_resources(int last, int nr_released)
-{
-	int count = nr_released;
-
-	count += (IA64_LAST_DEVICE_VECTOR - last);
-
-	return count;
-}
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
index ab9c48c..2d78f34 100644
--- a/arch/ia64/sn/kernel/Makefile
+++ b/arch/ia64/sn/kernel/Makefile
@@ -19,3 +19,4 @@
 obj-$(CONFIG_IA64_SGI_SN_XP)	+= xpc.o
 xpc-y				:= xpc_main.o xpc_channel.o xpc_partition.o
 obj-$(CONFIG_IA64_SGI_SN_XP)	+= xpnet.o
+obj-$(CONFIG_PCI_MSI)		+= msi_sn.o
diff --git a/drivers/pci/msi-altix.c b/arch/ia64/sn/kernel/msi_sn.c
similarity index 65%
rename from drivers/pci/msi-altix.c
rename to arch/ia64/sn/kernel/msi_sn.c
index bed4183..6ffd1f8 100644
--- a/drivers/pci/msi-altix.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -7,8 +7,10 @@
  */
 
 #include <linux/types.h>
+#include <linux/irq.h>
 #include <linux/pci.h>
 #include <linux/cpumask.h>
+#include <linux/msi.h>
 
 #include <asm/sn/addrs.h>
 #include <asm/sn/intr.h>
@@ -16,17 +18,16 @@
 #include <asm/sn/pcidev.h>
 #include <asm/sn/nodepda.h>
 
-#include "msi.h"
-
 struct sn_msi_info {
 	u64 pci_addr;
 	struct sn_irq_info *sn_irq_info;
 };
 
-static struct sn_msi_info *sn_msi_info;
+static struct sn_msi_info sn_msi_info[NR_IRQS];
 
-static void
-sn_msi_teardown(unsigned int vector)
+static struct irq_chip sn_msi_chip;
+
+void sn_teardown_msi_irq(unsigned int irq)
 {
 	nasid_t nasid;
 	int widget;
@@ -36,7 +37,7 @@
 	struct pcibus_bussoft *bussoft;
 	struct sn_pcibus_provider *provider;
 
-	sn_irq_info = sn_msi_info[vector].sn_irq_info;
+	sn_irq_info = sn_msi_info[irq].sn_irq_info;
 	if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
 		return;
 
@@ -45,9 +46,9 @@
 	provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
 	(*provider->dma_unmap)(pdev,
-			       sn_msi_info[vector].pci_addr,
+			       sn_msi_info[irq].pci_addr,
 			       PCI_DMA_FROMDEVICE);
-	sn_msi_info[vector].pci_addr = 0;
+	sn_msi_info[irq].pci_addr = 0;
 
 	bussoft = SN_PCIDEV_BUSSOFT(pdev);
 	nasid = NASID_GET(bussoft->bs_base);
@@ -56,15 +57,15 @@
 			SWIN_WIDGETNUM(bussoft->bs_base);
 
 	sn_intr_free(nasid, widget, sn_irq_info);
-	sn_msi_info[vector].sn_irq_info = NULL;
+	sn_msi_info[irq].sn_irq_info = NULL;
 
 	return;
 }
 
-int
-sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
-	     u32 *addr_hi, u32 *addr_lo, u32 *data)
+int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
 {
+	struct msi_msg msg;
+	struct msi_desc *entry;
 	int widget;
 	int status;
 	nasid_t nasid;
@@ -73,6 +74,10 @@
 	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
 	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
+	entry = get_irq_data(irq);
+	if (!entry->msi_attrib.is_64)
+		return -EINVAL;
+
 	if (bussoft == NULL)
 		return -EINVAL;
 
@@ -93,7 +98,7 @@
 	if (! sn_irq_info)
 		return -ENOMEM;
 
-	status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1);
+	status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1);
 	if (status) {
 		kfree(sn_irq_info);
 		return -ENOMEM;
@@ -119,29 +124,32 @@
 		return -ENOMEM;
 	}
 
-	sn_msi_info[vector].sn_irq_info = sn_irq_info;
-	sn_msi_info[vector].pci_addr = bus_addr;
+	sn_msi_info[irq].sn_irq_info = sn_irq_info;
+	sn_msi_info[irq].pci_addr = bus_addr;
 
-	*addr_hi = (u32)(bus_addr >> 32);
-	*addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
+	msg.address_hi = (u32)(bus_addr >> 32);
+	msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
 
 	/*
 	 * In the SN platform, bit 16 is a "send vector" bit which
 	 * must be present in order to move the vector through the system.
 	 */
-	*data = 0x100 + (unsigned int)vector;
+	msg.data = 0x100 + irq;
 
 #ifdef CONFIG_SMP
-	set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0);
+	set_irq_affinity_info(irq, sn_irq_info->irq_cpuid, 0);
 #endif
 
+	write_msi_msg(irq, &msg);
+	set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
+
 	return 0;
 }
 
-static void
-sn_msi_target(unsigned int vector, unsigned int cpu,
-	      u32 *addr_hi, u32 *addr_lo)
+#ifdef CONFIG_SMP
+static void sn_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
 {
+	struct msi_msg msg;
 	int slice;
 	nasid_t nasid;
 	u64 bus_addr;
@@ -150,8 +158,10 @@
 	struct sn_irq_info *sn_irq_info;
 	struct sn_irq_info *new_irq_info;
 	struct sn_pcibus_provider *provider;
+	unsigned int cpu;
 
-	sn_irq_info = sn_msi_info[vector].sn_irq_info;
+	cpu = first_cpu(cpu_mask);
+	sn_irq_info = sn_msi_info[irq].sn_irq_info;
 	if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
 		return;
 
@@ -159,19 +169,20 @@
 	 * Release XIO resources for the old MSI PCI address
 	 */
 
+	read_msi_msg(irq, &msg);
         sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
 	pdev = sn_pdev->pdi_linux_pcidev;
 	provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
-	bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo);
+	bus_addr = (u64)(msg.address_hi) << 32 | (u64)(msg.address_lo);
 	(*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE);
-	sn_msi_info[vector].pci_addr = 0;
+	sn_msi_info[irq].pci_addr = 0;
 
 	nasid = cpuid_to_nasid(cpu);
 	slice = cpuid_to_slice(cpu);
 
 	new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
-	sn_msi_info[vector].sn_irq_info = new_irq_info;
+	sn_msi_info[irq].sn_irq_info = new_irq_info;
 	if (new_irq_info == NULL)
 		return;
 
@@ -184,27 +195,36 @@
 					sizeof(new_irq_info->irq_xtalkaddr),
 					SN_DMA_MSI|SN_DMA_ADDR_XIO);
 
-	sn_msi_info[vector].pci_addr = bus_addr;
-	*addr_hi = (u32)(bus_addr >> 32);
-	*addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
+	sn_msi_info[irq].pci_addr = bus_addr;
+	msg.address_hi = (u32)(bus_addr >> 32);
+	msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
+
+	write_msi_msg(irq, &msg);
+	set_native_irq_info(irq, cpu_mask);
 }
+#endif /* CONFIG_SMP */
 
-struct msi_ops sn_msi_ops = {
-	.setup = sn_msi_setup,
-	.teardown = sn_msi_teardown,
-#ifdef CONFIG_SMP
-	.target = sn_msi_target,
-#endif
-};
-
-int
-sn_msi_init(void)
+static void sn_ack_msi_irq(unsigned int irq)
 {
-	sn_msi_info =
-		kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL);
-	if (! sn_msi_info)
-		return -ENOMEM;
-
-	msi_register(&sn_msi_ops);
-	return 0;
+	move_native_irq(irq);
+	ia64_eoi();
 }
+
+static int sn_msi_retrigger_irq(unsigned int irq)
+{
+	unsigned int vector = irq;
+	ia64_resend_irq(vector);
+
+	return 1;
+}
+
+static struct irq_chip sn_msi_chip = {
+	.name		= "PCI-MSI",
+	.mask		= mask_msi_irq,
+	.unmask		= unmask_msi_irq,
+	.ack		= sn_ack_msi_irq,
+#ifdef CONFIG_SMP
+	.set_affinity	= sn_set_msi_irq_affinity,
+#endif
+	.retrigger	= sn_msi_retrigger_irq,
+};
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index b632b9c..462ea17 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -423,7 +423,7 @@
 			"coherency_domain %d, "
 			"region_size %d\n",
 
-			partid, system_utsname.nodename,
+			partid, utsname()->nodename,
 			shubtype ? "shub2" : "shub1", 
 			(u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift,
 			system_size, sharing_size, coher, region_size);
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c
index 007703c..c8173db 100644
--- a/arch/ia64/sn/kernel/xpnet.c
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -225,7 +225,7 @@
 	skb_put(skb, (msg->size - msg->leadin_ignore - msg->tailout_ignore));
 
 	/*
-	 * Move the data over from the the other side.
+	 * Move the data over from the other side.
 	 */
 	if ((XPNET_VERSION_MINOR(msg->version) == 1) &&
 						(msg->embedded_bytes != 0)) {
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index a9cea32..b567351 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -25,6 +25,8 @@
 #include <asm/cachectl.h>
 #include <asm/cacheflush.h>
 #include <asm/ipc.h>
+#include <asm/syscall.h>
+#include <asm/unistd.h>
 
 /*
  * sys_tas() - test-and-set
@@ -205,7 +207,7 @@
 	if (!name)
 		return -EFAULT;
 	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	return err?-EFAULT:0;
 }
@@ -223,3 +225,21 @@
 	return -ENOSYS;
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __scno __asm__ ("r7") = __NR_execve;
+	register long __arg3 __asm__ ("r2") = (long)(envp);
+	register long __arg2 __asm__ ("r1") = (long)(argv);
+	register long __res __asm__ ("r0") = (long)(filename);
+	__asm__ __volatile__ (
+		"trap #" SYSCALL_VECTOR "|| nop"
+		: "=r" (__res)
+		: "r" (__scno), "0" (__res), "r" (__arg2),
+			"r" (__arg3)
+		: "memory");
+	return __res;
+}
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 143c552..90238a8 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -27,6 +27,7 @@
 #include <asm/traps.h>
 #include <asm/ipc.h>
 #include <asm/page.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -663,3 +664,18 @@
 {
 	return PAGE_SIZE;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __res asm ("%d0") = __NR_execve;
+	register long __a asm ("%d1") = (long)(filename);
+	register long __b asm ("%d2") = (long)(argv);
+	register long __c asm ("%d3") = (long)(envp);
+	asm volatile ("trap  #0" : "+d" (__res)
+			: "d" (__a), "d" (__b), "d" (__c));
+	return __res;
+}
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index 49015e3..afcccdc 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/m68k/motorola.c
+ * linux/arch/m68k/mm/motorola.c
  *
  * Routines specific to the Motorola MMU, originally from:
  * linux/arch/m68k/init.c
diff --git a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c
index 6c26522..a2bc2da 100644
--- a/arch/m68k/sun3/sun3dvma.c
+++ b/arch/m68k/sun3/sun3dvma.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/m68k/mm/sun3dvma.c
+ * linux/arch/m68k/sun3/sun3dvma.c
  *
  * Copyright (C) 2000 Sam Creasey
  *
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index e767f2d..6d920d4 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -161,8 +161,8 @@
 	  frequency, it may or may not be the same as the external clock
 	  crystal fitted to your board. Some processors have an internal
 	  PLL and can have their frequency programmed at run time, others
-	  use internal dividers. In gernal the kernel won't setup a PLL
-	  if it is fitted (there are some expections). This value will be
+	  use internal dividers. In general the kernel won't setup a PLL
+	  if it is fitted (there are some exceptions). This value will be
 	  specific to the exact CPU that you are using.
 
 config CLOCK_DIV
@@ -495,7 +495,7 @@
 	hex "Address of the base of system vectors"
 	default "0"
 	help
-	  Define the address of the the system vectors. Commonly this is
+	  Define the address of the system vectors. Commonly this is
 	  put at the start of RAM, but it doesn't have to be. On ColdFire
 	  platforms this address is programmed into the VBR register, thus
 	  actually setting the address to use.
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index d87e1e0..c3494b8 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -26,6 +26,7 @@
 #include <asm/traps.h>
 #include <asm/ipc.h>
 #include <asm/cacheflush.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -206,3 +207,17 @@
 	return PAGE_SIZE;
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __res asm ("%d0") = __NR_execve;
+	register long __a asm ("%d1") = (long)(filename);
+	register long __b asm ("%d2") = (long)(argv);
+	register long __c asm ("%d3") = (long)(envp);
+	asm volatile ("trap  #0" : "+d" (__res)
+			: "d" (__a), "d" (__b), "d" (__c));
+	return __res;
+}
diff --git a/arch/m68knommu/platform/68328/head-pilot.S b/arch/m68knommu/platform/68328/head-pilot.S
index 9e07faa..aecff53 100644
--- a/arch/m68knommu/platform/68328/head-pilot.S
+++ b/arch/m68knommu/platform/68328/head-pilot.S
@@ -1,5 +1,5 @@
 /*
- * linux/arch/m68knommu/platform/68328/head-rom.S
+ * linux/arch/m68knommu/platform/68328/head-pilot.S
  * - A startup file for the MC68328
  *
  * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 30750c5..bfab055 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -203,39 +203,6 @@
 	  <http://www.marvell.com/>.  Say Y here if you wish to build a
 	  kernel for this platform.
 
-config MIPS_IVR
-	bool "Globespan IVR board"
-	select DMA_NONCOHERENT
-	select HW_HAS_PCI
-	select ITE_BOARD_GEN
-	select SYS_HAS_CPU_NEVADA
-	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
-	select SYS_SUPPORTS_LITTLE_ENDIAN
-	help
-	  This is an evaluation board built by Globespan to showcase thir
-	  iVR (Internet Video Recorder) design. It utilizes a QED RM5231
-	  R5000 MIPS core. More information can be found out their website
-	  located at <http://www.globespan.net/>. Say Y here if you wish to
-	  build a kernel for this platform.
-
-config MIPS_ITE8172
-	bool "ITE 8172G board"
-	select DMA_NONCOHERENT
-	select HW_HAS_PCI
-	select ITE_BOARD_GEN
-	select SYS_HAS_CPU_R5432
-	select SYS_HAS_CPU_NEVADA
-	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
-	select SYS_SUPPORTS_LITTLE_ENDIAN
-	help
-	  Ths is an evaluation board made by ITE <http://www.ite.com.tw/>
-	  with ATX form factor that utilizes a MIPS R5000 to work with its
-	  ITE8172G companion internet appliance chip. The MIPS core can be
-	  either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
-	  a kernel for this platform.
-
 config MACH_JAZZ
 	bool "Jazz family of machines"
 	select ARC
@@ -537,6 +504,7 @@
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select ARCH_SPARSEMEM_ENABLE
 	help
 	  Qemu is a software emulator which among other architectures also
@@ -803,7 +771,6 @@
 source "arch/mips/ddb5xxx/Kconfig"
 source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
-source "arch/mips/ite-boards/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/momentum/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
@@ -836,6 +803,10 @@
 	bool
 	default y
 
+config GENERIC_TIME
+	bool
+	default y
+
 config SCHED_NO_NO_OMIT_FRAME_POINTER
 	bool
 	default y
@@ -963,9 +934,6 @@
 config PCI_MARVELL
 	bool
 
-config ITE_BOARD_GEN
-	bool
-
 config SOC_AU1000
 	bool
 	select SOC_AU1X00
@@ -1049,16 +1017,6 @@
 	depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
 	default n
 
-config IT8172_CIR
-	bool
-	depends on MIPS_ITE8172 || MIPS_IVR
-	default y
-
-config IT8712
-	bool
-	depends on MIPS_ITE8172
-	default y
-
 config BOOT_ELF32
 	bool
 
@@ -1841,6 +1799,14 @@
 	bool
 	default y
 
+config LOCKDEP_SUPPORT
+	bool
+	default y
+
+config STACKTRACE_SUPPORT
+	bool
+	default y
+
 source "init/Kconfig"
 
 menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index e521826..2124350 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -287,19 +287,6 @@
 load-$(CONFIG_WR_PPMC)		+= 0xffffffff80100000
 
 #
-# Globespan IVR eval board with QED 5231 CPU
-#
-core-$(CONFIG_ITE_BOARD_GEN)	+= arch/mips/ite-boards/generic/
-core-$(CONFIG_MIPS_IVR)		+= arch/mips/ite-boards/ivr/
-load-$(CONFIG_MIPS_IVR)		+= 0xffffffff80100000
-
-#
-# ITE 8172 eval board with QED 5231 CPU
-#
-core-$(CONFIG_MIPS_ITE8172)	+= arch/mips/ite-boards/qed-4n-s01b/
-load-$(CONFIG_MIPS_ITE8172)	+= 0xffffffff80100000
-
-#
 # For all MIPS, Inc. eval boards
 #
 core-$(CONFIG_MIPS_BOARDS_GEN)	+= arch/mips/mips-boards/generic/
diff --git a/arch/mips/basler/excite/excite_flashtest.c b/arch/mips/basler/excite/excite_flashtest.c
deleted file mode 100644
index f0024a8..0000000
--- a/arch/mips/basler/excite/excite_flashtest.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
-*  Copyright (C) 2005 by Basler Vision Technologies AG
-*  Author: Thies Moeller <thies.moeller@baslerweb.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/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-
-#include <excite.h>
-
-#include <asm/io.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <asm/rm9k-ocd.h> // for ocd_write
-#include <linux/workqueue.h> // for queue
-
-#include "excite_nandflash.h"
-#include "nandflash.h"
-
-#define PFX "excite flashtest: "
-typedef void __iomem *io_reg_t;
-
-#define io_readb(__a__)		__raw_readb((__a__))
-#define io_writeb(__v__, __a__)	__raw_writeb((__v__), (__a__))
-
-
-
-static inline const struct resource *excite_nandflash_get_resource(
-	struct platform_device *d, unsigned long flags, const char *basename)
-{
-	const char fmt[] = "%s_%u";
-	char buf[80];
-
-	if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf))
-		return NULL;
-
-	return platform_get_resource_byname(d, flags, buf);
-}
-
-static inline io_reg_t
-excite_nandflash_map_regs(struct platform_device *d, const char *basename)
-{
-	void *result = NULL;
-	const struct resource *const r =
-	    excite_nandflash_get_resource(d, IORESOURCE_MEM, basename);
-	if (r)
-	   result = ioremap_nocache(r->start, r->end + 1 - r->start);
-	return result;
-}
-
-/* controller and mtd information */
-
-struct excite_nandflash_drvdata {
-	struct mtd_info board_mtd;
-	struct nand_chip board_chip;
-	io_reg_t regs;
-};
-
-
-/* command and control functions */
-static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd)
-{
-	struct nand_chip *this = mtd->priv;
-	io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs;
-
-	switch (cmd) {
-	/* Select the command latch */
-	case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD;
-		break;
-	/* Deselect the command latch */
-	case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA;
-		break;
-	/* Select the address latch */
-	case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR;
-		break;
-	/* Deselect the address latch */
-	case NAND_CTL_CLRALE: this->IO_ADDR_W = regs  + EXCITE_NANDFLASH_DATA;
-		break;
-	/* Select the chip  -- not used */
-	case NAND_CTL_SETNCE:
-		break;
-	/* Deselect the chip -- not used */
-	case NAND_CTL_CLRNCE:
-		break;
-	}
-
-	this->IO_ADDR_R = this->IO_ADDR_W;
-}
-
-/* excite_nandflash_devready()
- *
- * returns 0 if the nand is busy, 1 if it is ready
- */
-static int excite_nandflash_devready(struct mtd_info *mtd)
-{
-	struct excite_nandflash_drvdata *drvdata =
-	    container_of(mtd, struct excite_nandflash_drvdata, board_mtd);
-
-	return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
-}
-
-/* device management functions */
-
-/* excite_nandflash_remove
- *
- * called by device layer to remove the driver
- * the binding to the mtd and all allocated
- * resources are released
- */
-static int excite_nandflash_remove(struct device *dev)
-{
-	struct excite_nandflash_drvdata *this = dev_get_drvdata(dev);
-
-	pr_info(PFX "remove");
-
-	dev_set_drvdata(dev, NULL);
-
-	if (this == NULL) {
-		pr_debug(PFX "call remove without private data!!");
-		return 0;
-	}
-
-
-	/* free the common resources */
-	if (this->regs != NULL) {
-		iounmap(this->regs);
-		this->regs = NULL;
-	}
-
-	kfree(this);
-
-	return 0;
-}
-
-static int elapsed;
-
-void my_workqueue_handler(void *arg)
-{
-	elapsed = 1;
-}
-
-DECLARE_WORK(sigElapsed, my_workqueue_handler, 0);
-
-
-/* excite_nandflash_probe
- *
- * called by device layer when it finds a device matching
- * one our driver can handled. This code checks to see if
- * it can allocate all necessary resources then calls the
- * nand layer to look for devices
-*/
-static int excite_nandflash_probe(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-
-	struct excite_nandflash_drvdata *drvdata;	    /* private driver data     */
-	struct nand_chip              *board_chip;  /* private flash chip data */
-	struct mtd_info               *board_mtd;   /* mtd info for this board */
-
-	int err      = 0;
-	int count    = 0;
-	struct timeval tv,endtv;
-	unsigned int dt;
-
-	pr_info(PFX "probe dev: (%p)\n", dev);
-
-	pr_info(PFX "adjust LB timing\n");
-	ocd_writel(0x00000330, LDP2);
-
-	drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL);
-	if (unlikely(!drvdata)) {
-		printk(KERN_ERR PFX "no memory for drvdata\n");
-		err = -ENOMEM;
-		goto mem_error;
-	}
-
-	/* Initialize structures */
-	memset(drvdata, 0, sizeof(*drvdata));
-
-	/* bind private data into driver */
-	dev_set_drvdata(dev, drvdata);
-
-	/* allocate and map the resource */
-	drvdata->regs =
-	    excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
-
-	if (unlikely(!drvdata->regs)) {
-		printk(KERN_ERR PFX "cannot reserve register region\n");
-		err = -ENXIO;
-		goto io_error;
-	}
-
-	/* initialise our chip */
-	board_chip = &drvdata->board_chip;
-
-	board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA;
-	board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA;
-
-	board_chip->hwcontrol = excite_nandflash_hwcontrol;
-	board_chip->dev_ready = excite_nandflash_devready;
-
-	board_chip->chip_delay = 25;
-	#if 0
-	/* TODO: speedup the initial scan */
-	board_chip->options = NAND_USE_FLASH_BBT;
-	#endif
-	board_chip->eccmode = NAND_ECC_SOFT;
-
-	/* link chip to mtd */
-	board_mtd = &drvdata->board_mtd;
-	board_mtd->priv = board_chip;
-
-
-	pr_info(PFX "FlashTest\n");
-	elapsed = 0;
-/*	schedule_delayed_work(&sigElapsed, 1*HZ);
-	while (!elapsed) {
-		io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
-		count++;
-	}
-	pr_info(PFX "reads in 1 sec --> %d\n",count);
-*/
-	do_gettimeofday(&tv);
-	for (count = 0 ; count < 1000000; count ++) {
-		io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
-	}
-	do_gettimeofday(&endtv);
-	dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec  - tv.tv_usec;
-	pr_info(PFX "%8d us timeval\n",dt);
-	pr_info(PFX "EndFlashTest\n");
-
-/*      return with error to unload everything
-*/
-io_error:
-	iounmap(drvdata->regs);
-
-mem_error:
-	kfree(drvdata);
-
-	if (err == 0)
-		err = -EINVAL;
-	return err;
-}
-
-static struct device_driver excite_nandflash_driver = {
-	.name = "excite_nand",
-	.bus = &platform_bus_type,
-	.probe = excite_nandflash_probe,
-	.remove = excite_nandflash_remove,
-};
-
-static int __init excite_nandflash_init(void)
-{
-	pr_info(PFX "register Driver (Rev: $Revision:$)\n");
-	return driver_register(&excite_nandflash_driver);
-}
-
-static void __exit excite_nandflash_exit(void)
-{
-	driver_unregister(&excite_nandflash_driver);
-	pr_info(PFX "Driver unregistered");
-}
-
-module_init(excite_nandflash_init);
-module_exit(excite_nandflash_exit);
-
-MODULE_AUTHOR("Thies Moeller <thies.moeller@baslerweb.com>");
-MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index c01a017..0b347cf 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -23,7 +23,6 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/gt64120.h>
-#include <asm/serial.h>
 
 #include <asm/mach-cobalt/cobalt.h>
 
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index d370528..35931be 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -161,6 +161,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1304,6 +1306,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index e12a475..c6a0159 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -167,6 +167,8 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_PREEMPT_BKL is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -904,6 +906,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index bfade9a..e535812 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -149,6 +149,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -891,6 +893,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 4baf2ff..adf1e8c 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -146,6 +146,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -889,6 +891,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 93cca15..4fd29ff 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -147,6 +147,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1006,6 +1008,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index ffd9925..025b960 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -147,6 +147,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1006,6 +1008,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 63eac5e..80c9dd9 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -147,6 +147,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1087,6 +1089,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 25a095f..6caa90b 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -149,6 +149,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1290,6 +1292,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index dda469c..c6cae86 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -148,6 +148,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1111,6 +1113,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index fcd3dd1..72f2400 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -146,6 +146,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -852,6 +854,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 8683e0d..fe1387e 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:01 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:57:53 2006
 #
 CONFIG_MIPS=y
 
@@ -147,6 +147,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -165,27 +167,28 @@
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_RELAY=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -203,6 +206,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -229,7 +233,6 @@
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -256,9 +259,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
-# CONFIG_NET_KEY is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=m
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
@@ -267,22 +271,37 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 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_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_NETWORK_SECMARK=y
 # CONFIG_NETFILTER is not set
 
@@ -302,14 +321,13 @@
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
+CONFIG_VLAN_8021Q=m
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -325,13 +343,8 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -342,8 +355,6 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -385,8 +396,9 @@
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -408,12 +420,13 @@
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=m
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -421,10 +434,14 @@
 CONFIG_ISCSI_TCP=m
 CONFIG_SCSI_DECNCR=y
 # CONFIG_SCSI_DECSII is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -454,18 +471,7 @@
 #
 # PHY device support
 #
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -710,7 +716,12 @@
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -745,11 +756,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
@@ -767,7 +780,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=y
-# CONFIG_UFS_FS_WRITE is not set
+CONFIG_UFS_FS_WRITE=y
 # CONFIG_UFS_DEBUG is not set
 
 #
@@ -775,24 +788,25 @@
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -828,45 +842,31 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_RWSEMS is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_VM is not set
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
-# CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_MIPS_UNCACHED is not set
 
 #
 # Security options
 #
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -876,9 +876,12 @@
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -900,7 +903,7 @@
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index 4ace61c..6133c28 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -147,6 +147,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index 5847c91..a484b7d 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -147,6 +147,8 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1180,6 +1182,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index bc4c4f1..21bfcde 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -148,6 +148,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -842,6 +844,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index eb87cbb..1a5b06c 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -149,6 +149,8 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1184,6 +1186,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index cc9b24e..21d53e0 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -153,6 +153,8 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1147,6 +1149,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 50092ba..e3e94c7 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -162,6 +162,8 @@
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
 # CONFIG_MIPS_INSANE_LARGE is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -980,6 +982,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index dec2ba6..b4ab2be 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -153,6 +153,8 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -922,6 +924,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
deleted file mode 100644
index 37f9dd7..0000000
--- a/arch/mips/configs/it8172_defconfig
+++ /dev/null
@@ -1,961 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:11 2006
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-CONFIG_MIPS_ITE8172=y
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_IT8172_REVC is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_ITE_BOARD_GEN=y
-CONFIG_IT8172_CIR=y
-CONFIG_IT8712=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-CONFIG_CPU_NEVADA=y
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_R5432=y
-CONFIG_SYS_HAS_CPU_NEVADA=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-# CONFIG_PCI is not set
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-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_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_PARTITIONS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-# CONFIG_MTD_BLOCK is not set
-# CONFIG_MTD_BLOCK_RO is not set
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0x2000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
-# CONFIG_MTD_ONENAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_RAID_ATTRS=m
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_DM9000 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_QTRONIX_KEYBOARD is not set
-# CONFIG_IT8172_SCR0 is not set
-# CONFIG_IT8172_SCR1 is not set
-# CONFIG_ITE_GPIO is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-# CONFIG_SND is not set
-
-#
-# Open Sound System
-#
-CONFIG_SOUND_PRIME=y
-CONFIG_SOUND_IT8172=y
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# 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
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
deleted file mode 100644
index 18874a4..0000000
--- a/arch/mips/configs/ivr_defconfig
+++ /dev/null
@@ -1,917 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:12 2006
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-CONFIG_MIPS_IVR=y
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_ITE_BOARD_GEN=y
-CONFIG_IT8172_CIR=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-CONFIG_CPU_NEVADA=y
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_NEVADA=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-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_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_RAID_ATTRS=m
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# 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_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_QTRONIX_KEYBOARD=y
-CONFIG_IT8172_SCR0=y
-CONFIG_IT8172_SCR1=y
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# 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
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index 9f1e304..9d4d17a 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -153,6 +153,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -775,6 +777,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index fded3f7..d037466 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -143,6 +143,8 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_RTC_DS1742=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -872,6 +874,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index 320b8cd..1db8249 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -151,6 +151,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -970,6 +972,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 0ba1ef5..aeefe28 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -170,6 +170,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1341,6 +1343,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index adbeead..a3cbd23b 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -148,6 +148,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -799,6 +801,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 79fd544..6570b47 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -148,6 +148,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index 4d87da2..440d65f 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -153,6 +153,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1091,6 +1093,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index a7ac2b0..c2c7ae7 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -150,6 +150,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -839,6 +841,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 853e7bb..67efe27 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -154,6 +154,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -788,6 +790,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index 8524efa..a10f34d 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -153,6 +153,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -842,6 +844,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 1a16e92..741f825 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -149,6 +149,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1000,6 +1002,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 9ea8ede..8576340 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -148,6 +148,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1106,6 +1108,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index c4a1589..3db7427 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -148,6 +148,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1098,6 +1100,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 1cbf270..26b0b98 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -153,6 +153,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -876,6 +878,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index bec30b1..e93266b 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -153,6 +153,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1057,6 +1059,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index f5f799e..9b0dab8 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -145,6 +145,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -733,6 +735,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 2f56502..dd02960 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -155,6 +155,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1335,6 +1337,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 4fee90b..d8a498d 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -158,6 +158,8 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1584,6 +1586,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 9041f09..805a4fe 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -171,6 +171,8 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -873,6 +875,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 02abb2f..6fcb656 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -151,6 +151,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -581,6 +583,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index ca3d0c4..dc312f1 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -151,6 +151,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1059,6 +1061,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index 4e2009a..85615d9 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -151,6 +151,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -968,6 +970,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 535a813..ad7271b 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -151,6 +151,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1146,6 +1148,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 3a3ef20..863f6a7 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -147,6 +147,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index e6b1dea..c10267d 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -155,6 +155,8 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -829,6 +831,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index 06a072b..4d3c132 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -152,6 +152,8 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -760,6 +762,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/dec/boot/Makefile b/arch/mips/dec/boot/Makefile
deleted file mode 100644
index bcea416..0000000
--- a/arch/mips/dec/boot/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for the DECstation family specific parts of the kernel
-#
-
-netboot: all
-	$(LD) -N -G 0 -T ld.ecoff ../../boot/zImage \
-		dec_boot.o ramdisk.img -o nbImage
-
-obj-y	 := decstation.o
-
-clean:
-	rm -f nbImage
diff --git a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c
deleted file mode 100644
index 4db8bac..0000000
--- a/arch/mips/dec/boot/decstation.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * arch/mips/dec/decstation.c
- */
-#include <asm/sections.h>
-
-#define RELOC
-#define INITRD
-#define DEBUG_BOOT
-
-/*
- * Magic number indicating REX PROM available on DECSTATION.
- */
-#define	REX_PROM_MAGIC		0x30464354
-
-#define REX_PROM_CLEARCACHE	0x7c/4
-#define REX_PROM_PRINTF		0x30/4
-
-#define VEC_RESET		0xBFC00000		/* Prom base address */
-#define	PMAX_PROM_ENTRY(x)	(VEC_RESET+((x)*8))	/* Prom jump table */
-#define	PMAX_PROM_PRINTF	PMAX_PROM_ENTRY(17)
-
-#define PARAM	(k_start + 0x2000)
-
-#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
-#define INITRD_START (*(unsigned long *) (PARAM+0x218))
-#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
-
-extern int _ftext;			/* begin and end of kernel image */
-extern void kernel_entry(int, char **, unsigned long, int *);
-
-void * memcpy(void * dest, const void *src, unsigned int count)
-{
-	unsigned long *tmp = (unsigned long *) dest, *s = (unsigned long *) src;
-
-	count >>= 2;
-	while (count--)
-		*tmp++ = *s++;
-
-	return dest;
-}
-
-void dec_entry(int argc, char **argv,
-	       unsigned long magic, int *prom_vec)
-{
-	void (*rex_clear_cache)(void);
-	int (*prom_printf)(char *, ...);
-	unsigned long k_start, len;
-
-	/*
-	 * The DS5100 leaves cpu with BEV enabled, clear it.
-	 */
-	asm(	"lui\t$8,0x3000\n\t"
-		"mtc0\t$8,$12\n\t"
-		".section\t.sdata\n\t"
-		".section\t.sbss\n\t"
-		".section\t.text"
-		: : : "$8");
-
-#ifdef DEBUG_BOOT
-	if (magic == REX_PROM_MAGIC) {
-	prom_printf = (int (*)(char *, ...)) *(prom_vec + REX_PROM_PRINTF);
-	} else {
-		prom_printf = (int (*)(char *, ...)) PMAX_PROM_PRINTF;
-	}
-	prom_printf("Launching kernel...\n");
-#endif
-
-	k_start = (unsigned long) (&kernel_entry) & 0xffff0000;
-
-#ifdef RELOC
-	/*
-	 * Now copy kernel image to its destination.
-	 */
-	len = ((unsigned long) (&_end) - k_start);
-	memcpy((void *)k_start, &_ftext, len);
-#endif
-
-	if (magic == REX_PROM_MAGIC) {
-		rex_clear_cache = (void (*)(void)) * (prom_vec + REX_PROM_CLEARCACHE);
-		rex_clear_cache();
-	}
-
-	kernel_entry(argc, argv, magic, prom_vec);
-}
diff --git a/arch/mips/dec/boot/ld.ecoff b/arch/mips/dec/boot/ld.ecoff
deleted file mode 100644
index aaa633d..0000000
--- a/arch/mips/dec/boot/ld.ecoff
+++ /dev/null
@@ -1,43 +0,0 @@
-OUTPUT_FORMAT("ecoff-littlemips")
-OUTPUT_ARCH(mips)
-ENTRY(dec_entry)
-SECTIONS
-{
-  . = 0x80200000;
-
-  .text :
-  {
-    _ftext = .;
-    *(.text)
-    *(.fixup)
-  }
-  .rdata :
-  {
-    *(.rodata .rodata.* .rdata)
-  }
-  .data :
-  {
-    . = ALIGN(0x1000);
-    ramdisk.img (.data)
-    *(.data)
-  }
-  .sdata :
-  {
-    *(.sdata)
-  }
-  _gp = .;
-  .sbss :
-  {
-    *(.sbss)
-    *(.scommon)
-  }
-  .bss :
-  {
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-  }
-  /DISCARD/ : {
-    *(.reginfo .mdebug .note)
-  }
-}
diff --git a/arch/mips/dec/prom/call_o32.S b/arch/mips/dec/prom/call_o32.S
index 0dd56db..e523454 100644
--- a/arch/mips/dec/prom/call_o32.S
+++ b/arch/mips/dec/prom/call_o32.S
@@ -1,5 +1,5 @@
 /*
- *	arch/mips/dec/call_o32.S
+ *	arch/mips/dec/prom/call_o32.S
  *
  *	O32 interface for the 64 (or N32) ABI.
  *
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 5729474..4cf0c06 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -184,8 +184,6 @@
 	CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
 }
 
-EXPORT_SYMBOL(do_settimeofday);
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
 	setup_irq(dec_interrupt[DEC_IRQ_RTC], irq);
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index cc9b24e..21d53e0 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -153,6 +153,8 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1147,6 +1149,7 @@
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/ite-boards/Kconfig b/arch/mips/ite-boards/Kconfig
deleted file mode 100644
index a6d59ad..0000000
--- a/arch/mips/ite-boards/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-config IT8172_REVC
-	bool "Support for older IT8172 (Rev C)"
-	depends on MIPS_ITE8172
-	help
-	  Say Y here to support the older, Revision C version of the Integrated
-	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
-	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
diff --git a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile
deleted file mode 100644
index 6343153..0000000
--- a/arch/mips/ite-boards/generic/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
-#
-# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
-#
-
-obj-y			+= it8172_setup.o irq.o pmon_prom.o \
-			   time.o lpc.o puts.o reset.o
-
-obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o
-obj-$(CONFIG_KGDB)	+= dbg_io.o
-
-EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ite-boards/generic/dbg_io.c b/arch/mips/ite-boards/generic/dbg_io.c
deleted file mode 100644
index 8e9cd8a..0000000
--- a/arch/mips/ite-boards/generic/dbg_io.c
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-#ifdef CONFIG_KGDB
-
-/* --- CONFIG --- */
-
-/* we need uint32 uint8 */
-/* #include "types.h" */
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-
-/* --- END OF CONFIG --- */
-
-#define         UART16550_BAUD_2400             2400
-#define         UART16550_BAUD_4800             4800
-#define         UART16550_BAUD_9600             9600
-#define         UART16550_BAUD_19200            19200
-#define         UART16550_BAUD_38400            38400
-#define         UART16550_BAUD_57600            57600
-#define         UART16550_BAUD_115200           115200
-
-#define         UART16550_PARITY_NONE           0
-#define         UART16550_PARITY_ODD            0x08
-#define         UART16550_PARITY_EVEN           0x18
-#define         UART16550_PARITY_MARK           0x28
-#define         UART16550_PARITY_SPACE          0x38
-
-#define         UART16550_DATA_5BIT             0x0
-#define         UART16550_DATA_6BIT             0x1
-#define         UART16550_DATA_7BIT             0x2
-#define         UART16550_DATA_8BIT             0x3
-
-#define         UART16550_STOP_1BIT             0x0
-#define         UART16550_STOP_2BIT             0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [stevel] we use the IT8712 serial port for kgdb */
-#define	DEBUG_BASE  0xB40003F8	/* 8712 serial port 1 base address */
-#define MAX_BAUD    115200
-
-/* === END OF CONFIG === */
-
-/* register offset */
-#define         OFS_RCV_BUFFER          0
-#define         OFS_TRANS_HOLD          0
-#define         OFS_SEND_BUFFER         0
-#define         OFS_INTR_ENABLE         1
-#define         OFS_INTR_ID             2
-#define         OFS_DATA_FORMAT         3
-#define         OFS_LINE_CONTROL        3
-#define         OFS_MODEM_CONTROL       4
-#define         OFS_RS232_OUTPUT        4
-#define         OFS_LINE_STATUS         5
-#define         OFS_MODEM_STATUS        6
-#define         OFS_RS232_INPUT         6
-#define         OFS_SCRATCH_PAD         7
-
-#define         OFS_DIVISOR_LSB         0
-#define         OFS_DIVISOR_MSB         1
-
-
-/* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (*((volatile uint8*)(DEBUG_BASE + y)))
-#define UART16550_WRITE(y,z) ((*((volatile uint8*)(DEBUG_BASE + y))) = z)
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
-	/* disable interrupts */
-	UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
-	/* set up baud rate */
-	{
-		uint32 divisor;
-
-		/* set DIAB bit */
-		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
-		/* set divisor */
-		divisor = MAX_BAUD / baud;
-		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
-		/* clear DIAB bit */
-		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-	}
-
-	/* set data format */
-	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_115200,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-	}
-
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
-	return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-
-int putDebugChar(uint8 byte)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_115200,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-	}
-
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
-	UART16550_WRITE(OFS_SEND_BUFFER, byte);
-	return 1;
-}
-
-#endif
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
deleted file mode 100644
index cb59ca4..0000000
--- a/arch/mips/ite-boards/generic/irq.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	ITE 8172G interrupt/setup routines.
- *
- * Copyright 2000,2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- * Part of this file was derived from Carsten Langgaard's
- * arch/mips/mips-boards/atlas/atlas_int.c.
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/serial_reg.h>
-#include <linux/bitops.h>
-
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#include <asm/it8172/it8172_dbg.h>
-
-/* revisit */
-#define EXT_IRQ0_TO_IP 2 /* IP 2 */
-#define EXT_IRQ5_TO_IP 7 /* IP 7 */
-
-#define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
-
-extern void set_debug_traps(void);
-extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
-
-struct it8172_intc_regs volatile *it8172_hw0_icregs =
-	(struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
-
-static void disable_it8172_irq(unsigned int irq_nr)
-{
-	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
-		/* LPC interrupt */
-		it8172_hw0_icregs->lpc_mask |=
-			(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-	} else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
-		/* Local Bus interrupt */
-		it8172_hw0_icregs->lb_mask |=
-			(1 << (irq_nr - IT8172_LB_IRQ_BASE));
-	} else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
-		/* PCI and other interrupts */
-		it8172_hw0_icregs->pci_mask |=
-			(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-	} else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
-		/* NMI interrupts */
-		it8172_hw0_icregs->nmi_mask |=
-			(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-	} else {
-		panic("disable_it8172_irq: bad irq %d", irq_nr);
-	}
-}
-
-static void enable_it8172_irq(unsigned int irq_nr)
-{
-	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
-		/* LPC interrupt */
-		it8172_hw0_icregs->lpc_mask &=
-			~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-	}
-	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
-		/* Local Bus interrupt */
-		it8172_hw0_icregs->lb_mask &=
-			~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
-	}
-	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
-		/* PCI and other interrupts */
-		it8172_hw0_icregs->pci_mask &=
-			~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-	}
-	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
-		/* NMI interrupts */
-		it8172_hw0_icregs->nmi_mask &=
-			~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-	}
-	else {
-		panic("enable_it8172_irq: bad irq %d", irq_nr);
-	}
-}
-
-static unsigned int startup_ite_irq(unsigned int irq)
-{
-	enable_it8172_irq(irq);
-	return 0;
-}
-
-#define shutdown_ite_irq	disable_it8172_irq
-#define mask_and_ack_ite_irq    disable_it8172_irq
-
-static void end_ite_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_it8172_irq(irq);
-}
-
-static struct irq_chip it8172_irq_type = {
-	.typename = "ITE8172",
-	.startup = startup_ite_irq,
-	.shutdown = shutdown_ite_irq,
-	.enable = enable_it8172_irq,
-	.disable = disable_it8172_irq,
-	.ack = mask_and_ack_ite_irq,
-	.end = end_ite_irq,
-};
-
-
-static void enable_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-static void disable_none(unsigned int irq) { }
-static void ack_none(unsigned int irq) { }
-
-/* startup is the same as "enable", shutdown is same as "disable" */
-#define shutdown_none	disable_none
-#define end_none	enable_none
-
-static struct irq_chip cp0_irq_type = {
-	.typename = "CP0 Count",
-	.startup = startup_none,
-	.shutdown = shutdown_none,
-	.enable = enable_none,
-	.disable = disable_none,
-	.ack = ack_none,
-	.end = end_none
-};
-
-void enable_cpu_timer(void)
-{
-        unsigned long flags;
-
-        local_irq_save(flags);
-	set_c0_status(0x100 << EXT_IRQ5_TO_IP);
-        local_irq_restore(flags);
-}
-
-void __init arch_init_irq(void)
-{
-	int i;
-        unsigned long flags;
-
-	/* mask all interrupts */
-	it8172_hw0_icregs->lb_mask  = 0xffff;
-	it8172_hw0_icregs->lpc_mask = 0xffff;
-	it8172_hw0_icregs->pci_mask = 0xffff;
-	it8172_hw0_icregs->nmi_mask = 0xffff;
-
-	/* make all interrupts level triggered */
-	it8172_hw0_icregs->lb_trigger  = 0;
-	it8172_hw0_icregs->lpc_trigger = 0;
-	it8172_hw0_icregs->pci_trigger = 0;
-	it8172_hw0_icregs->nmi_trigger = 0;
-
-	/* active level setting */
-	/* uart, keyboard, and mouse are active high */
-	it8172_hw0_icregs->lpc_level = (0x10 | 0x2 | 0x1000);
-	it8172_hw0_icregs->lb_level |= 0x20;
-
-	/* keyboard and mouse are edge triggered */
-	it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000);
-
-
-#if 0
-	// Enable this piece of code to make internal USB interrupt
-	// edge triggered.
-	it8172_hw0_icregs->pci_trigger |=
-		(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
-	it8172_hw0_icregs->pci_level &=
-		~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
-#endif
-
-	for (i = 0; i <= IT8172_LAST_IRQ; i++) {
-		irq_desc[i].chip = &it8172_irq_type;
-		spin_lock_init(&irq_desc[i].lock);
-	}
-	irq_desc[MIPS_CPU_TIMER_IRQ].chip = &cp0_irq_type;
-	set_c0_status(ALLINTS_NOTIMER);
-}
-
-void mips_spurious_interrupt(struct pt_regs *regs)
-{
-#if 1
-	return;
-#else
-	unsigned long status, cause;
-
-	printk("got spurious interrupt\n");
-	status = read_c0_status();
-	cause = read_c0_cause();
-	printk("status %x cause %x\n", status, cause);
-	printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
-#endif
-}
-
-void it8172_hw0_irqdispatch(struct pt_regs *regs)
-{
-	int irq;
-	unsigned short intstatus = 0, status = 0;
-
-	intstatus = it8172_hw0_icregs->intstatus;
-	if (intstatus & 0x8) {
-		panic("Got NMI interrupt");
-	} else if (intstatus & 0x4) {
-		/* PCI interrupt */
-		irq = 0;
-		status |= it8172_hw0_icregs->pci_req;
-		while (!(status & 0x1)) {
-			irq++;
-			status >>= 1;
-		}
-		irq += IT8172_PCI_DEV_IRQ_BASE;
-	} else if (intstatus & 0x1) {
-		/* Local Bus interrupt */
-		irq = 0;
-		status |= it8172_hw0_icregs->lb_req;
-		while (!(status & 0x1)) {
-			irq++;
-			status >>= 1;
-		}
-		irq += IT8172_LB_IRQ_BASE;
-	} else if (intstatus & 0x2) {
-		/* LPC interrupt */
-		/* Since some lpc interrupts are edge triggered,
-		 * we could lose an interrupt this way because
-		 * we acknowledge all ints at onces. Revisit.
-		 */
-		status |= it8172_hw0_icregs->lpc_req;
-		it8172_hw0_icregs->lpc_req = 0; /* acknowledge ints */
-		irq = 0;
-		while (!(status & 0x1)) {
-			irq++;
-			status >>= 1;
-		}
-		irq += IT8172_LPC_IRQ_BASE;
-	} else
-		return;
-
-	do_IRQ(irq, regs);
-}
-
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
-{
-	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
-
-	if (!pending)
-		mips_spurious_interrupt(regs);
-	else if (pending & CAUSEF_IP7)
-		ll_timer_interrupt(127, regs);
-	else if (pending & CAUSEF_IP2)
-		it8172_hw0_irqdispatch(regs);
-}
-
-void show_pending_irqs(void)
-{
-	fputs("intstatus:  ");
-	put32(it8172_hw0_icregs->intstatus);
-	puts("");
-
-	fputs("pci_req:  ");
-	put32(it8172_hw0_icregs->pci_req);
-	puts("");
-
-	fputs("lb_req:  ");
-	put32(it8172_hw0_icregs->lb_req);
-	puts("");
-
-	fputs("lpc_req:  ");
-	put32(it8172_hw0_icregs->lpc_req);
-	puts("");
-}
diff --git a/arch/mips/ite-boards/generic/it8172_cir.c b/arch/mips/ite-boards/generic/it8172_cir.c
deleted file mode 100644
index bfc25ad..0000000
--- a/arch/mips/ite-boards/generic/it8172_cir.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	IT8172 Consumer IR port generic routines.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#ifdef CONFIG_IT8172_CIR
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_cir.h>
-
-
-volatile struct it8172_cir_regs *cir_regs[NUM_CIR_PORTS] = {
-	(volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR0_BASE)),
-	(volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR1_BASE))};
-
-
-/*
- * Initialize Consumer IR Port.
- */
-int cir_port_init(struct cir_port *cir)
-{
-	int port = cir->port;
-	unsigned char data;
-
-	/* set baud rate */
-	cir_regs[port]->bdlr = cir->baud_rate & 0xff;
-	cir_regs[port]->bdhr = (cir->baud_rate >> 8) & 0xff;
-
-	/* set receiver control register */
-	cir_regs[port]->rcr = (CIR_SET_RDWOS(cir->rdwos) | CIR_SET_RXDCR(cir->rxdcr));
-
-	/* set carrier frequency register */
-	cir_regs[port]->cfr = (CIR_SET_CF(cir->cfq) | CIR_SET_HS(cir->hcfs));
-
-	/* set fifo threshold */
-	data = cir_regs[port]->mstcr & 0xf3;
-	data |= CIR_SET_FIFO_TL(cir->fifo_tl);
-	cir_regs[port]->mstcr = data;
-
-	clear_fifo(cir);
-	enable_receiver(cir);
-	disable_rx_demodulation(cir);
-
-	set_rx_active(cir);
-	int_enable(cir);
-	rx_int_enable(cir);
-
-	return 0;
-}
-
-
-void clear_fifo(struct cir_port *cir)
-{
-	cir_regs[cir->port]->mstcr |= CIR_FIFO_CLEAR;
-}
-
-void enable_receiver(struct cir_port *cir)
-{
-	cir_regs[cir->port]->rcr |= CIR_RXEN;
-}
-
-void disable_receiver(struct cir_port *cir)
-{
-	cir_regs[cir->port]->rcr &= ~CIR_RXEN;
-}
-
-void enable_rx_demodulation(struct cir_port *cir)
-{
-	cir_regs[cir->port]->rcr |= CIR_RXEND;
-}
-
-void disable_rx_demodulation(struct cir_port *cir)
-{
-	cir_regs[cir->port]->rcr &= ~CIR_RXEND;
-}
-
-void set_rx_active(struct cir_port *cir)
-{
-	cir_regs[cir->port]->rcr |= CIR_RXACT;
-}
-
-void int_enable(struct cir_port *cir)
-{
-	cir_regs[cir->port]->ier |= CIR_IEC;
-}
-
-void rx_int_enable(struct cir_port *cir)
-{
-	cir_regs[cir->port]->ier |= CIR_RDAIE;
-}
-
-void dump_regs(struct cir_port *cir)
-{
-	printk("mstcr %x ier %x iir %x cfr %x rcr %x tcr %x tfsr %x rfsr %x\n",
-	cir_regs[cir->port]->mstcr,
-	cir_regs[cir->port]->ier,
-	cir_regs[cir->port]->iir,
-	cir_regs[cir->port]->cfr,
-	cir_regs[cir->port]->rcr,
-	cir_regs[cir->port]->tcr,
-	cir_regs[cir->port]->tfsr,
-	cir_regs[cir->port]->rfsr);
-
-	while (cir_regs[cir->port]->iir & CIR_RDAI) {
-		printk("data %x\n", cir_regs[cir->port]->dr);
-	}
-}
-
-void dump_reg_addr(struct cir_port *cir)
-{
-	printk("dr %x mstcr %x ier %x iir %x cfr %x rcr %x tcr %x bdlr %x bdhr %x tfsr %x rfsr %x\n",
-	(unsigned)&cir_regs[cir->port]->dr,
-	(unsigned)&cir_regs[cir->port]->mstcr,
-	(unsigned)&cir_regs[cir->port]->ier,
-	(unsigned)&cir_regs[cir->port]->iir,
-	(unsigned)&cir_regs[cir->port]->cfr,
-	(unsigned)&cir_regs[cir->port]->rcr,
-	(unsigned)&cir_regs[cir->port]->tcr,
-	(unsigned)&cir_regs[cir->port]->bdlr,
-	(unsigned)&cir_regs[cir->port]->bdhr,
-	(unsigned)&cir_regs[cir->port]->tfsr,
-	(unsigned)&cir_regs[cir->port]->rfsr);
-}
-
-int cir_get_rx_count(struct cir_port *cir)
-{
-	return cir_regs[cir->port]->rfsr & CIR_RXFBC_MASK;
-}
-
-char cir_read_data(struct cir_port *cir)
-{
-	return cir_regs[cir->port]->dr;
-}
-
-char get_int_status(struct cir_port *cir)
-{
-	return cir_regs[cir->port]->iir;
-}
-#endif
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
deleted file mode 100644
index 07faf3c..0000000
--- a/arch/mips/ite-boards/generic/it8172_setup.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	IT8172/QED5231 board setup.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/serial_reg.h>
-#include <linux/major.h>
-#include <linux/kdev_t.h>
-#include <linux/root_dev.h>
-#include <linux/pm.h>
-
-#include <asm/cpu.h>
-#include <asm/time.h>
-#include <asm/io.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/reboot.h>
-#include <asm/traps.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8712.h>
-
-extern struct resource ioport_resource;
-#ifdef CONFIG_SERIO_I8042
-int init_8712_keyboard(void);
-#endif
-
-extern int SearchIT8712(void);
-extern void InitLPCInterface(void);
-extern char * __init prom_getcmdline(void);
-extern void it8172_restart(char *command);
-extern void it8172_halt(void);
-extern void it8172_power_off(void);
-
-extern void it8172_time_init(void);
-
-#ifdef CONFIG_IT8172_REVC
-struct {
-    struct resource ram;
-    struct resource pci_mem;
-    struct resource pci_io;
-    struct resource flash;
-    struct resource boot;
-} it8172_resources = {
-	{
-		.start	= 0,				/* to be initted */
-		.end	= 0,
-		.name	= "RAM",
-		.flags	= IORESOURCE_MEM
-	}, {
-		.start	= 0x10000000,
-		.end	= 0x13FFFFFF,
-		.name	= "PCI Mem",
-		.flags	= IORESOURCE_MEM
-	}, {
-		.start	= 0x14000000,
-		.end	= 0x17FFFFFF
-		.name	= "PCI I/O",
-	}, {
-		.start	= 0x08000000,
-		.end	= 0x0CFFFFFF
-		.name	= "Flash",
-	}, {
-		.start	= 0x1FC00000,
-		.end	= 0x1FFFFFFF
-		.name	= "Boot ROM",
-	}
-};
-#else
-struct {
-    struct resource ram;
-    struct resource pci_mem0;
-    struct resource pci_mem1;
-    struct resource pci_io;
-    struct resource pci_mem2;
-    struct resource pci_mem3;
-    struct resource flash;
-    struct resource boot;
-} it8172_resources = {
-	{
-		.start	= 0,				/* to be initted */
-		.end	= 0,
-		.name	= "RAM",
-		.flags	= IORESOURCE_MEM
-	}, {
-		.start	= 0x0C000000,
-		.end	= 0x0FFFFFFF,
-		.name	= "PCI Mem0",
-		.flags	= IORESOURCE_MEM
-	 }, {
-		.start	= 0x10000000,
-		.end	= 0x13FFFFFF,
-		.name	= "PCI Mem1",
-		.flags	= IORESOURCE_MEM
-	 }, {
-		.start	= 0x14000000,
-		.end	= 0x17FFFFFF
-		.name	= "PCI I/O",
-	}, {
-		.start	= 0x1A000000,
-		.end	= 0x1BFFFFFF,
-		.name	= "PCI Mem2",
-		.flags	= IORESOURCE_MEM
-	}, {
-		.start	= 0x1C000000,
-		.end	= 0x1FBFFFFF,
-		.name	= "PCI Mem3",
-		.flags	= IORESOURCE_MEM
-	}, {
-		.start	= 0x08000000,
-		.end	= 0x0CFFFFFF
-		.name	= "Flash",
-	}, {
-		.start	= 0x1FC00000,
-		.end	= 0x1FFFFFFF
-		.name	= "Boot ROM",
-	}
-};
-#endif
-
-
-void __init it8172_init_ram_resource(unsigned long memsize)
-{
-	it8172_resources.ram.end = memsize;
-}
-
-void __init plat_mem_setup(void)
-{
-	unsigned short dsr;
-	char *argptr;
-
-	argptr = prom_getcmdline();
-#ifdef CONFIG_SERIAL_CONSOLE
-	if ((argptr = strstr(argptr, "console=")) == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
-
-	clear_c0_status(ST0_FR);
-
-	board_time_init = it8172_time_init;
-
-	_machine_restart = it8172_restart;
-	_machine_halt = it8172_halt;
-	pm_power_off = it8172_power_off;
-
-	/*
-	 * IO/MEM resources.
-	 *
-	 * revisit this area.
-	 */
-	set_io_port_base(KSEG1);
-	ioport_resource.start = it8172_resources.pci_io.start;
-	ioport_resource.end = it8172_resources.pci_io.end;
-#ifdef CONFIG_IT8172_REVC
-	iomem_resource.start = it8172_resources.pci_mem.start;
-	iomem_resource.end = it8172_resources.pci_mem.end;
-#else
-	iomem_resource.start = it8172_resources.pci_mem0.start;
-	iomem_resource.end = it8172_resources.pci_mem3.end;
-#endif
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = Root_RAM0;
-#endif
-
-	/*
-	 * Pull enabled devices out of standby
-	 */
-	IT_IO_READ16(IT_PM_DSR, dsr);
-
-	/*
-	 * Fixme: This breaks when these drivers are modules!!!
-	 */
-#ifdef CONFIG_SOUND_IT8172
-	dsr &= ~IT_PM_DSR_ACSB;
-#else
-	dsr |= IT_PM_DSR_ACSB;
-#endif
-#ifdef CONFIG_BLK_DEV_IT8172
-	dsr &= ~IT_PM_DSR_IDESB;
-#else
-	dsr |= IT_PM_DSR_IDESB;
-#endif
-	IT_IO_WRITE16(IT_PM_DSR, dsr);
-
-	InitLPCInterface();
-
-#ifdef CONFIG_MIPS_ITE8172
-	if (SearchIT8712()) {
-		printk("Found IT8712 Super IO\n");
-		/* enable IT8712 serial port */
-		LPCSetConfig(LDN_SERIAL1, 0x30, 0x01); /* enable */
-		LPCSetConfig(LDN_SERIAL1, 0x23, 0x01); /* clock selection */
-#ifdef CONFIG_SERIO_I8042
-		if (init_8712_keyboard()) {
-			printk("Unable to initialize keyboard\n");
-			LPCSetConfig(LDN_KEYBOARD, 0x30, 0x0); /* disable keyboard */
-		} else {
-			LPCSetConfig(LDN_KEYBOARD, 0x30, 0x1); /* enable keyboard */
-			LPCSetConfig(LDN_KEYBOARD, 0xf0, 0x2);
-			LPCSetConfig(LDN_KEYBOARD, 0x71, 0x3);
-
-			LPCSetConfig(LDN_MOUSE, 0x30, 0x1); /* enable mouse */
-
-			LPCSetConfig(0x4, 0x30, 0x1);
-			LPCSetConfig(0x4, 0xf4, LPCGetConfig(0x4, 0xf4) | 0x80);
-
-			if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) ||
-					(LPCGetConfig(LDN_MOUSE, 0x30) == 0))
-				printk("Error: keyboard or mouse not enabled\n");
-
-		}
-#endif
-	}
-	else {
-		printk("IT8712 Super IO not found\n");
-	}
-#endif
-
-#ifdef CONFIG_IT8172_CIR
-	{
-		unsigned long data;
-		//printk("Enabling CIR0\n");
-		IT_IO_READ16(IT_PM_DSR, data);
-		data &= ~IT_PM_DSR_CIR0SB;
-		IT_IO_WRITE16(IT_PM_DSR, data);
-		//printk("DSR register: %x\n", (unsigned)IT_IO_READ16(IT_PM_DSR, data));
-	}
-#endif
-#ifdef CONFIG_IT8172_SCR0
-	{
-		unsigned i;
-		/* Enable Smart Card Reader 0 */
-		/* First power it up */
-		IT_IO_READ16(IT_PM_DSR, i);
-		i &= ~IT_PM_DSR_SCR0SB;
-		IT_IO_WRITE16(IT_PM_DSR, i);
-		/* Then initialize its registers */
-		outb(( IT_SCR_SFR_GATE_UART_OFF     << IT_SCR_SFR_GATE_UART_BIT
-		      |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
-		      |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
-		      |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
-		      |IT_SCR_SFR_ENABLE_ON         << IT_SCR_SFR_ENABLE_BIT),
-		     IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SFR);
-		outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
-		     IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SCDR);
-	}
-#endif /* CONFIG_IT8172_SCR0 */
-#ifdef CONFIG_IT8172_SCR1
-	{
-		unsigned i;
-		/* Enable Smart Card Reader 1 */
-		/* First power it up */
-		IT_IO_READ16(IT_PM_DSR, i);
-		i &= ~IT_PM_DSR_SCR1SB;
-		IT_IO_WRITE16(IT_PM_DSR, i);
-		/* Then initialize its registers */
-		outb(( IT_SCR_SFR_GATE_UART_OFF     << IT_SCR_SFR_GATE_UART_BIT
-		      |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
-		      |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
-		      |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
-		      |IT_SCR_SFR_ENABLE_ON         << IT_SCR_SFR_ENABLE_BIT),
-		     IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SFR);
-		outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
-		     IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SCDR);
-	}
-#endif /* CONFIG_IT8172_SCR1 */
-}
-
-#ifdef CONFIG_SERIO_I8042
-/*
- * According to the ITE Special BIOS Note for waking up the
- * keyboard controller...
- */
-static int init_8712_keyboard(void)
-{
-	unsigned int cmd_port = 0x14000064;
-	unsigned int data_port = 0x14000060;
-	                         ^^^^^^^^^^^
-	Somebody here doesn't grok the concept of io ports.
-
-	unsigned char data;
-	int i;
-
-	outb(0xaa, cmd_port); /* send self-test cmd */
-	i = 0;
-	while (!(inb(cmd_port) & 0x1)) { /* wait output buffer full */
-		i++;
-		if (i > 0xffffff)
-			return 1;
-	}
-
-	data = inb(data_port);
-	outb(0xcb, cmd_port); /* set ps2 mode */
-	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-		i++;
-		if (i > 0xffffff)
-			return 1;
-	}
-	outb(0x01, data_port);
-	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-		i++;
-		if (i > 0xffffff)
-			return 1;
-	}
-
-	outb(0x60, cmd_port); /* write 8042 command byte */
-	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-		i++;
-		if (i > 0xffffff)
-			return 1;
-	}
-	outb(0x45, data_port); /* at interface, keyboard enabled, system flag */
-	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-		i++;
-		if (i > 0xffffff)
-			return 1;
-	}
-
-	outb(0xae, cmd_port); /* enable interface */
-	return 0;
-}
-#endif
diff --git a/arch/mips/ite-boards/generic/lpc.c b/arch/mips/ite-boards/generic/lpc.c
deleted file mode 100644
index cc7584f..0000000
--- a/arch/mips/ite-boards/generic/lpc.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	ITE Semi IT8712 Super I/O functions.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/io.h>
-#include <asm/types.h>
-#include <asm/it8712.h>
-#include <asm/it8172/it8172.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-void LPCEnterMBPnP(void)
-{
-	int i;
-	unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
-
-	for (i = 0; i<4; i++)
-		outb(key[i], LPC_KEY_ADDR);
-
-}
-
-void LPCExitMBPnP(void)
-{
-	outb(0x02, LPC_KEY_ADDR);
-	outb(0x02, LPC_DATA_ADDR);
-}
-
-void LPCSetConfig(char LdnNumber, char Index, char data)
-{
-	LPCEnterMBPnP();				// Enter IT8712 MB PnP mode
-	outb(0x07, LPC_KEY_ADDR);
-	outb(LdnNumber, LPC_DATA_ADDR);
-	outb(Index, LPC_KEY_ADDR);
-	outb(data, LPC_DATA_ADDR);
-	LPCExitMBPnP();
-}
-
-char LPCGetConfig(char LdnNumber, char Index)
-{
-	char rtn;
-
-	LPCEnterMBPnP();				// Enter IT8712 MB PnP mode
-	outb(0x07, LPC_KEY_ADDR);
-	outb(LdnNumber, LPC_DATA_ADDR);
-	outb(Index, LPC_KEY_ADDR);
-	rtn = inb(LPC_DATA_ADDR);
-	LPCExitMBPnP();
-	return rtn;
-}
-
-int SearchIT8712(void)
-{
-	unsigned char Id1, Id2;
-	unsigned short Id;
-
-	LPCEnterMBPnP();
-	outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */
-	Id1 = inb(LPC_DATA_ADDR);
-	outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */
-	Id2 = inb(LPC_DATA_ADDR);
-	Id = (Id1 << 8) | Id2;
-	LPCExitMBPnP();
-	if (Id == 0x8712)
-		return TRUE;
-	else
-		return FALSE;
-}
-
-void InitLPCInterface(void)
-{
-	unsigned char bus, dev_fn;
-	unsigned long data;
-
-	bus = 0;
-	dev_fn = 1<<3 | 4;
-
-
-	/* pci cmd, SERR# Enable */
-	IT_WRITE(IT_CONFADDR,
-		 (bus         << IT_BUSNUM_SHF)   |
-		 (dev_fn      << IT_FUNCNUM_SHF) |
-		 ((0x4 / 4) << IT_REGNUM_SHF));
-	IT_READ(IT_CONFDATA, data);
-	data |= 0x0100;
-	IT_WRITE(IT_CONFADDR,
-		 (bus         << IT_BUSNUM_SHF)   |
-		 (dev_fn      << IT_FUNCNUM_SHF) |
-		 ((0x4 / 4) << IT_REGNUM_SHF));
-	IT_WRITE(IT_CONFDATA, data);
-
-	/* setup serial irq control register */
-	IT_WRITE(IT_CONFADDR,
-		 (bus         << IT_BUSNUM_SHF)   |
-		 (dev_fn      << IT_FUNCNUM_SHF) |
-		 ((0x48 / 4) << IT_REGNUM_SHF));
-	IT_READ(IT_CONFDATA, data);
-	data  = (data & 0xffff00ff) | 0xc400;
-	IT_WRITE(IT_CONFADDR,
-		 (bus         << IT_BUSNUM_SHF)   |
-		 (dev_fn      << IT_FUNCNUM_SHF) |
-		 ((0x48 / 4) << IT_REGNUM_SHF));
-	IT_WRITE(IT_CONFDATA, data);
-
-
-	/* Enable I/O Space Subtractive Decode */
-	/* default 0x4C is 0x3f220000 */
-	IT_WRITE(IT_CONFADDR,
-		 (bus         << IT_BUSNUM_SHF)   |
-		 (dev_fn      << IT_FUNCNUM_SHF) |
-		 ((0x4C / 4) << IT_REGNUM_SHF));
-	IT_WRITE(IT_CONFDATA, 0x3f2200f3);
-}
diff --git a/arch/mips/ite-boards/generic/pmon_prom.c b/arch/mips/ite-boards/generic/pmon_prom.c
deleted file mode 100644
index 7d0a79b..0000000
--- a/arch/mips/ite-boards/generic/pmon_prom.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *    PROM library initialisation code, assuming a version of
- *    pmon is the boot code.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- * This file was derived from Carsten Langgaard's
- * arch/mips/mips-boards/xx files.
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-
-#include <asm/bootinfo.h>
-
-extern int prom_argc;
-extern char **prom_argv, **prom_envp;
-
-typedef struct
-{
-    char *name;
-/*    char *val; */
-}t_env_var;
-
-
-char * __init prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-
-void  __init prom_init_cmdline(void)
-{
-	char *cp;
-	int actr;
-
-	actr = 1; /* Always ignore argv[0] */
-
-	cp = &(arcs_cmdline[0]);
-	while(actr < prom_argc) {
-	        strcpy(cp, prom_argv[actr]);
-		cp += strlen(prom_argv[actr]);
-		*cp++ = ' ';
-		actr++;
-	}
-	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
-		--cp;
-	*cp = '\0';
-
-}
-
-
-char *prom_getenv(char *envname)
-{
-	/*
-	 * Return a pointer to the given environment variable.
-	 * Environment variables are stored in the form of "memsize=64".
-	 */
-
-	t_env_var *env = (t_env_var *)prom_envp;
-	int i;
-
-	i = strlen(envname);
-
-	while(env->name) {
-		if(strncmp(envname, env->name, i) == 0) {
-			return(env->name + strlen(envname) + 1);
-		}
-		env++;
-	}
-	return(NULL);
-}
-
-static inline unsigned char str2hexnum(unsigned char c)
-{
-	if(c >= '0' && c <= '9')
-	return c - '0';
-	if(c >= 'a' && c <= 'f')
-	return c - 'a' + 10;
-	return 0; /* foo */
-}
-
-unsigned long __init prom_free_prom_memory(void)
-{
-	return 0;
-}
-
-unsigned long __init prom_get_memsize(void)
-{
-	char *memsize_str;
-	unsigned int memsize;
-
-	memsize_str = prom_getenv("memsize");
-	if (!memsize_str) {
-#ifdef CONFIG_MIPS_ITE8172
-		memsize = 32;
-#elif defined(CONFIG_MIPS_IVR)
-		memsize = 64;
-#else
-		memsize = 8;
-#endif
-		printk("memsize unknown: setting to %dMB\n", memsize);
-	} else {
-		printk("memsize: %s\n", memsize_str);
-		memsize = simple_strtol(memsize_str, NULL, 0);
-	}
-	return memsize;
-}
diff --git a/arch/mips/ite-boards/generic/puts.c b/arch/mips/ite-boards/generic/puts.c
deleted file mode 100644
index 20b02df..0000000
--- a/arch/mips/ite-boards/generic/puts.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	Low level uart routines to directly access a 16550 uart.
- *
- * Copyright 2000,2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-
-#define SERIAL_BASE   0xB4011800	/* it8172 */
-#define SER_CMD       5
-#define SER_DATA      0x00
-#define TX_BUSY       0x20
-
-#define TIMEOUT       0xffff
-#undef SLOW_DOWN
-
-static const char digits[16] = "0123456789abcdef";
-static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
-
-
-#ifdef SLOW_DOWN
-static inline void slow_down()
-{
-	int k;
-	for (k = 0; k < 10000; k++);
-}
-#else
-#define slow_down()
-#endif
-
-void putch(const unsigned char c)
-{
-	unsigned char ch;
-	int i = 0;
-
-	do {
-		ch = com1[SER_CMD];
-		slow_down();
-		i++;
-		if (i > TIMEOUT) {
-			break;
-		}
-	} while (0 == (ch & TX_BUSY));
-	com1[SER_DATA] = c;
-}
-
-void puts(unsigned char *cp)
-{
-	unsigned char ch;
-	int i = 0;
-
-	while (*cp) {
-		do {
-			ch = com1[SER_CMD];
-			slow_down();
-			i++;
-			if (i > TIMEOUT) {
-				break;
-			}
-		} while (0 == (ch & TX_BUSY));
-		com1[SER_DATA] = *cp++;
-	}
-	putch('\r');
-	putch('\n');
-}
-
-void fputs(unsigned char *cp)
-{
-	unsigned char ch;
-	int i = 0;
-
-	while (*cp) {
-
-		do {
-			ch = com1[SER_CMD];
-			slow_down();
-			i++;
-			if (i > TIMEOUT) {
-				break;
-			}
-		} while (0 == (ch & TX_BUSY));
-		com1[SER_DATA] = *cp++;
-	}
-}
-
-
-void put64(uint64_t ul)
-{
-	int cnt;
-	unsigned ch;
-
-	cnt = 16;		/* 16 nibbles in a 64 bit long */
-	putch('0');
-	putch('x');
-	do {
-		cnt--;
-		ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
-		putch(digits[ch]);
-	} while (cnt > 0);
-}
-
-void put32(unsigned u)
-{
-	int cnt;
-	unsigned ch;
-
-	cnt = 8;		/* 8 nibbles in a 32 bit long */
-	putch('0');
-	putch('x');
-	do {
-		cnt--;
-		ch = (unsigned char) (u >> cnt * 4) & 0x0F;
-		putch(digits[ch]);
-	} while (cnt > 0);
-}
diff --git a/arch/mips/ite-boards/generic/reset.c b/arch/mips/ite-boards/generic/reset.c
deleted file mode 100644
index 03bd5ba..0000000
--- a/arch/mips/ite-boards/generic/reset.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	ITE 8172 reset routines.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-
-void it8172_restart()
-{
-	set_c0_status(ST0_BEV | ST0_ERL);
-	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-	flush_cache_all();
-	write_c0_wired(0);
-	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-void it8172_halt(void)
-{
-	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
-	while (1)
-		__asm__(".set\tmips3\n\t"
-	                "wait\n\t"
-			".set\tmips0");
-}
-
-void it8172_power_off(void)
-{
-	it8172_halt();
-}
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
deleted file mode 100644
index 3dc5556..0000000
--- a/arch/mips/ite-boards/generic/time.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * Copyright (C) 2003 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.
- *
- * ########################################################################
- *
- * Setting up the clock on the MIPS boards.
- */
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/spinlock.h>
-#include <linux/mc146818rtc.h>
-
-#include <asm/time.h>
-#include <asm/mipsregs.h>
-#include <asm/ptrace.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#include <asm/debug.h>
-
-#define IT8172_RTC_ADR_REG  (IT8172_PCI_IO_BASE + IT_RTC_BASE)
-#define IT8172_RTC_DAT_REG  (IT8172_RTC_ADR_REG + 1)
-#define IT8172_RTC_CENTURY_REG  (IT8172_PCI_IO_BASE + IT_RTC_CENTURY)
-
-static volatile char *rtc_adr_reg = (char*)KSEG1ADDR(IT8172_RTC_ADR_REG);
-static volatile char *rtc_dat_reg = (char*)KSEG1ADDR(IT8172_RTC_DAT_REG);
-static volatile char *rtc_century_reg = (char*)KSEG1ADDR(IT8172_RTC_CENTURY_REG);
-
-unsigned char it8172_rtc_read_data(unsigned long addr)
-{
-	unsigned char retval;
-
-	*rtc_adr_reg = addr;
-	retval =  *rtc_dat_reg;
-	return retval;
-}
-
-void it8172_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	*rtc_adr_reg = addr;
-	*rtc_dat_reg = data;
-}
-
-#undef 	CMOS_READ
-#undef 	CMOS_WRITE
-#define	CMOS_READ(addr)			it8172_rtc_read_data(addr)
-#define CMOS_WRITE(data, addr) 		it8172_rtc_write_data(data, addr)
-
-static unsigned char saved_control;	/* remember rtc control reg */
-static inline int rtc_24h(void) { return saved_control & RTC_24H; }
-static inline int rtc_dm_binary(void) { return saved_control & RTC_DM_BINARY; }
-
-static inline unsigned char
-bin_to_hw(unsigned char c)
-{
-	if (rtc_dm_binary())
-		return c;
-	else
-		return ((c/10) << 4) + (c%10);
-}
-
-static inline unsigned char
-hw_to_bin(unsigned char c)
-{
-	if (rtc_dm_binary())
-		return c;
-	else
-		return (c>>4)*10 + (c &0xf);
-}
-
-/* 0x80 bit indicates pm in 12-hour format */
-static inline unsigned char
-hour_bin_to_hw(unsigned char c)
-{
-	if (rtc_24h())
-		return bin_to_hw(c);
-	if (c >= 12)
-		return 0x80 | bin_to_hw((c==12)?12:c-12);  /* 12 is 12pm */
-	else
-		return bin_to_hw((c==0)?12:c);	/* 0 is 12 AM, not 0 am */
-}
-
-static inline unsigned char
-hour_hw_to_bin(unsigned char c)
-{
-	unsigned char tmp = hw_to_bin(c&0x3f);
-	if (rtc_24h())
-		return tmp;
-	if (c & 0x80)
-		return (tmp==12)?12:tmp+12;  	/* 12pm is 12, not 24 */
-	else
-		return (tmp==12)?0:tmp;		/* 12am is 0 */
-}
-
-static unsigned long r4k_offset; /* Amount to increment compare reg each time */
-static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-extern unsigned int mips_hpt_frequency;
-
-/*
- * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick.
- * Use the RTC to calculate offset.
- */
-static unsigned long __init cal_r4koff(void)
-{
-	unsigned int flags;
-
-	local_irq_save(flags);
-
-	/* Start counter exactly on falling edge of update flag */
-	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-	/* Start r4k counter. */
-	write_c0_count(0);
-
-	/* Read counter exactly on falling edge of update flag */
-	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-	mips_hpt_frequency = read_c0_count();
-
-	/* restore interrupts */
-	local_irq_restore(flags);
-
-	return (mips_hpt_frequency / HZ);
-}
-
-static unsigned long
-it8172_rtc_get_time(void)
-{
-	unsigned int year, mon, day, hour, min, sec;
-	unsigned int flags;
-
-	/* avoid update-in-progress. */
-	for (;;) {
-		local_irq_save(flags);
-		if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
-			break;
-		/* don't hold intr closed all the time */
-		local_irq_restore(flags);
-	}
-
-	/* Read regs. */
-	sec = hw_to_bin(CMOS_READ(RTC_SECONDS));
-	min = hw_to_bin(CMOS_READ(RTC_MINUTES));
-	hour = hour_hw_to_bin(CMOS_READ(RTC_HOURS));
-	day = hw_to_bin(CMOS_READ(RTC_DAY_OF_MONTH));
-	mon = hw_to_bin(CMOS_READ(RTC_MONTH));
-	year = hw_to_bin(CMOS_READ(RTC_YEAR)) +
-		hw_to_bin(*rtc_century_reg) * 100;
-
-	/* restore interrupts */
-	local_irq_restore(flags);
-
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-static int
-it8172_rtc_set_time(unsigned long t)
-{
-	struct rtc_time tm;
-	unsigned int flags;
-
-	/* convert */
-	to_tm(t, &tm);
-
-	/* avoid update-in-progress. */
-	for (;;) {
-		local_irq_save(flags);
-		if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
-			break;
-		/* don't hold intr closed all the time */
-		local_irq_restore(flags);
-	}
-
-	*rtc_century_reg = bin_to_hw(tm.tm_year/100);
-	CMOS_WRITE(bin_to_hw(tm.tm_sec), RTC_SECONDS);
-	CMOS_WRITE(bin_to_hw(tm.tm_min), RTC_MINUTES);
-	CMOS_WRITE(hour_bin_to_hw(tm.tm_hour), RTC_HOURS);
-	CMOS_WRITE(bin_to_hw(tm.tm_mday), RTC_DAY_OF_MONTH);
-	CMOS_WRITE(bin_to_hw(tm.tm_mon+1), RTC_MONTH);	/* tm_mon starts from 0 */
-	CMOS_WRITE(bin_to_hw(tm.tm_year%100), RTC_YEAR);
-
-	/* restore interrupts */
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-void __init it8172_time_init(void)
-{
-        unsigned int est_freq, flags;
-
-	local_irq_save(flags);
-
-	saved_control = CMOS_READ(RTC_CONTROL);
-
-	printk("calculating r4koff... ");
-	r4k_offset = cal_r4koff();
-	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
-
-	est_freq = 2*r4k_offset*HZ;
-	est_freq += 5000;    /* round */
-	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
-	       (est_freq%1000000)*100/1000000);
-
-	local_irq_restore(flags);
-
-	rtc_mips_get_time = it8172_rtc_get_time;
-	rtc_mips_set_time = it8172_rtc_set_time;
-}
-
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	puts("timer_setup\n");
-	put32(NR_IRQS);
-	puts("");
-        /* we are using the cpu counter for timer interrupts */
-	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
-
-        /* to generate the first timer interrupt */
-	r4k_cur = (read_c0_count() + r4k_offset);
-	write_c0_compare(r4k_cur);
-	set_c0_status(ALLINTS);
-}
diff --git a/arch/mips/ite-boards/ivr/Makefile b/arch/mips/ite-boards/ivr/Makefile
deleted file mode 100644
index e4fa604..0000000
--- a/arch/mips/ite-boards/ivr/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
-#
-# Makefile for the Globespan IVR board,
-# board-specific files.
-#
-
-obj-y		+= init.o
diff --git a/arch/mips/ite-boards/ivr/README b/arch/mips/ite-boards/ivr/README
deleted file mode 100644
index aa7d8db..0000000
--- a/arch/mips/ite-boards/ivr/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This is not really a board made by ITE Semi, but it's very
-similar to the ITE QED-4N-S01B board.  The IVR board is made
-by Globespan and it's a reference board for the PVR chip.
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c
deleted file mode 100644
index 05cf921..0000000
--- a/arch/mips/ite-boards/ivr/init.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	IVR board setup.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <asm/sections.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_dbg.h>
-
-int prom_argc;
-char **prom_argv, **prom_envp;
-
-extern void  __init prom_init_cmdline(void);
-extern unsigned long __init prom_get_memsize(void);
-extern void __init it8172_init_ram_resource(unsigned long memsize);
-
-const char *get_system_type(void)
-{
-	return "Globespan IVR";
-}
-
-void __init prom_init(void)
-{
-	unsigned long mem_size;
-	unsigned long pcicr;
-
-	prom_argc = fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (int *) fw_arg3;
-
-	mips_machgroup = MACH_GROUP_GLOBESPAN;
-	mips_machtype = MACH_IVR;  /* Globespan's iTVC15 reference board */
-
-	prom_init_cmdline();
-
-	/* pmon does not set memsize */
-	mem_size = prom_get_memsize();
-	mem_size = mem_size << 20;
-
-	/*
-	 * make the entire physical memory visible to pci bus masters
-	 */
-	IT_READ(IT_MC_PCICR, pcicr);
-	pcicr &= ~0x1f;
-	pcicr |= (mem_size - 1) >> 22;
-	IT_WRITE(IT_MC_PCICR, pcicr);
-
-	it8172_init_ram_resource(mem_size);
-	add_memory_region(0, mem_size, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/ite-boards/qed-4n-s01b/Makefile b/arch/mips/ite-boards/qed-4n-s01b/Makefile
deleted file mode 100644
index bb9972a..0000000
--- a/arch/mips/ite-boards/qed-4n-s01b/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
-#
-# Makefile for the ITE 8172 (qed-4n-s01b) board, board
-# specific files.
-#
-
-obj-y := init.o
diff --git a/arch/mips/ite-boards/qed-4n-s01b/README b/arch/mips/ite-boards/qed-4n-s01b/README
deleted file mode 100644
index fb4b519..0000000
--- a/arch/mips/ite-boards/qed-4n-s01b/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This is an ITE (www.iteusa.com) eval board for the ITE 8172G
-system controller, with a QED 5231 CPU.
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c
deleted file mode 100644
index ea2a754..0000000
--- a/arch/mips/ite-boards/qed-4n-s01b/init.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	IT8172/QED5231 board setup.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <asm/sections.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_dbg.h>
-
-int prom_argc;
-char **prom_argv, **prom_envp;
-
-extern void  __init prom_init_cmdline(void);
-extern unsigned long __init prom_get_memsize(void);
-extern void __init it8172_init_ram_resource(unsigned long memsize);
-
-const char *get_system_type(void)
-{
-	return "ITE QED-4N-S01B";
-}
-
-void __init prom_init(void)
-{
-	unsigned long mem_size;
-	unsigned long pcicr;
-
-	prom_argc = fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (int *) fw_arg3;
-
-	mips_machgroup = MACH_GROUP_ITE;
-	mips_machtype = MACH_QED_4N_S01B;  /* ITE board name/number */
-
-	prom_init_cmdline();
-	mem_size = prom_get_memsize();
-
-	printk("Memory size: %dMB\n", (unsigned)mem_size);
-
-	mem_size <<= 20; /* MB */
-
-	/*
-	 * make the entire physical memory visible to pci bus masters
-	 */
-	IT_READ(IT_MC_PCICR, pcicr);
-	pcicr &= ~0x1f;
-	pcicr |= (mem_size - 1) >> 22;
-	IT_WRITE(IT_MC_PCICR, pcicr);
-
-	it8172_init_ram_resource(mem_size);
-	add_memory_region(0, mem_size, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 881c467..cd9cec9 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -11,6 +11,7 @@
 binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
 			   irix5sys.o sysirix.o
 
+obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_MODULES)		+= mips_ksyms.o module.o
 
 obj-$(CONFIG_APM)		+= apm.o
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 37fda3d..af6ef2f 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -220,8 +220,8 @@
 	CLI
 	TRACE_IRQS_OFF
 	move	a0, sp
-	jalr	v0
-	j	ret_from_irq
+	PTR_LA	ra, ret_from_irq
+	jr	v0
 	END(except_vec_vi_handler)
 
 /*
@@ -349,8 +349,8 @@
 	.set	at
 	__BUILD_\verbose \exception
 	move	a0, sp
-	jal	do_\handler
-	j	ret_from_exception
+	PTR_LA	ra, ret_from_exception
+	j	do_\handler
 	END(handle_\exception)
 	.endm
 
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index ea36c8e..48e3418 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -302,11 +302,11 @@
 };
 
 static struct resource pic1_io_resource = {
-	.name = "pic1", .start = 0x20, .end = 0x3f, .flags = IORESOURCE_BUSY
+	.name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY
 };
 
 static struct resource pic2_io_resource = {
-	.name = "pic2", .start = 0xa0, .end = 0xbf, .flags = IORESOURCE_BUSY
+	.name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY
 };
 
 /*
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 43b1162..53f4171 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -77,6 +77,8 @@
 	memset(&tmp, 0, sizeof(tmp));
 	tmp.st_dev = new_encode_dev(stat->dev);
 	tmp.st_ino = stat->ino;
+	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+		return -EOVERFLOW;
 	tmp.st_mode = stat->mode;
 	tmp.st_nlink = stat->nlink;
 	SET_UID(tmp.st_uid, stat->uid);
@@ -1039,7 +1041,7 @@
 	int ret = 0;
 
 	down_read(&uts_sem);
-	if (copy_to_user(name,&system_utsname,sizeof *name))
+	if (copy_to_user(name, utsname(), sizeof *name))
 		ret = -EFAULT;
 	up_read(&uts_sem);
 
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 2613a0d..045d987 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -40,6 +40,7 @@
 #include <asm/elf.h>
 #include <asm/isadep.h>
 #include <asm/inst.h>
+#include <asm/stacktrace.h>
 #ifdef CONFIG_MIPS_MT_SMTC
 #include <asm/mipsmtregs.h>
 extern void smtc_idle_loop_hook(void);
@@ -398,7 +399,7 @@
 #ifdef CONFIG_KALLSYMS
 /* used by show_backtrace() */
 unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
-			   unsigned long pc, unsigned long ra)
+			   unsigned long pc, unsigned long *ra)
 {
 	unsigned long stack_page;
 	struct mips_frame_info info;
@@ -406,18 +407,42 @@
 	char namebuf[KSYM_NAME_LEN + 1];
 	unsigned long size, ofs;
 	int leaf;
+	extern void ret_from_irq(void);
+	extern void ret_from_exception(void);
 
 	stack_page = (unsigned long)task_stack_page(task);
 	if (!stack_page)
 		return 0;
 
+	/*
+	 * If we reached the bottom of interrupt context,
+	 * return saved pc in pt_regs.
+	 */
+	if (pc == (unsigned long)ret_from_irq ||
+	    pc == (unsigned long)ret_from_exception) {
+		struct pt_regs *regs;
+		if (*sp >= stack_page &&
+		    *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
+			regs = (struct pt_regs *)*sp;
+			pc = regs->cp0_epc;
+			if (__kernel_text_address(pc)) {
+				*sp = regs->regs[29];
+				*ra = regs->regs[31];
+				return pc;
+			}
+		}
+		return 0;
+	}
 	if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf))
 		return 0;
 	/*
 	 * Return ra if an exception occured at the first instruction
 	 */
-	if (unlikely(ofs == 0))
-		return ra;
+	if (unlikely(ofs == 0)) {
+		pc = *ra;
+		*ra = 0;
+		return pc;
+	}
 
 	info.func = (void *)(pc - ofs);
 	info.func_size = ofs;	/* analyze from start to ofs */
@@ -436,11 +461,12 @@
 		 * one. In that cases avoid to return always the
 		 * same value.
 		 */
-		pc = pc != ra ? ra : 0;
+		pc = pc != *ra ? *ra : 0;
 	else
 		pc = ((unsigned long *)(*sp))[info.pc_offset];
 
 	*sp += info.frame_size;
+	*ra = 0;
 	return __kernel_text_address(pc) ? pc : 0;
 }
 #endif
@@ -453,6 +479,7 @@
 	unsigned long pc = 0;
 #ifdef CONFIG_KALLSYMS
 	unsigned long sp;
+	unsigned long ra = 0;
 #endif
 
 	if (!task || task == current || task->state == TASK_RUNNING)
@@ -466,7 +493,7 @@
 	sp = task->thread.reg29 + schedule_mfi.frame_size;
 
 	while (in_sched_functions(pc))
-		pc = unwind_stack(task, &sp, pc, 0);
+		pc = unwind_stack(task, &sp, pc, &ra);
 #endif
 
 out:
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index e717851..61362e6 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -28,18 +28,7 @@
 NESTED(handle_sys, PT_SIZE, sp)
 	.set	noat
 	SAVE_SOME
-#ifdef CONFIG_TRACE_IRQFLAGS
-	TRACE_IRQS_ON
-#ifdef CONFIG_64BIT
-	LONG_L	$8, PT_R8(sp)
-	LONG_L	$9, PT_R9(sp)
-#endif
-	LONG_L	$7, PT_R7(sp)
-	LONG_L	$6, PT_R6(sp)
-	LONG_L	$5, PT_R5(sp)
-	LONG_L	$4, PT_R4(sp)
-	LONG_L	$2, PT_R2(sp)
-#endif
+	TRACE_IRQS_ON_RELOAD
 	STI
 	.set	at
 
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 4c22d0b..6c7b5ed 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -34,7 +34,7 @@
 	 */
 	.set	noat
 	SAVE_SOME
-	TRACE_IRQS_ON
+	TRACE_IRQS_ON_RELOAD
 	STI
 	.set	at
 #endif
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index f25c2a2..6d9f187 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -33,7 +33,7 @@
 #ifndef CONFIG_MIPS32_O32
 	.set	noat
 	SAVE_SOME
-	TRACE_IRQS_ON
+	TRACE_IRQS_ON_RELOAD
 	STI
 	.set	at
 #endif
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 288ee4a..2e6d067 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -28,7 +28,7 @@
 NESTED(handle_sys, PT_SIZE, sp)
 	.set	noat
 	SAVE_SOME
-	TRACE_IRQS_ON
+	TRACE_IRQS_ON_RELOAD
 	STI
 	.set	at
 	ld	t1, PT_EPC(sp)		# skip syscall on return
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 50c17ea..477c533 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -42,8 +42,6 @@
 
 #include "signal-common.h"
 
-extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
-
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
@@ -83,6 +81,8 @@
 #endif
 };
 
+extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
+
 save_static_function(sysn32_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
new file mode 100644
index 0000000..4aabe52
--- /dev/null
+++ b/arch/mips/kernel/stacktrace.c
@@ -0,0 +1,85 @@
+/*
+ * arch/mips/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <asm/stacktrace.h>
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer:
+ */
+static void save_raw_context_stack(struct stack_trace *trace,
+	unsigned long reg29)
+{
+	unsigned long *sp = (unsigned long *)reg29;
+	unsigned long addr;
+
+	while (!kstack_end(sp)) {
+		addr = *sp++;
+		if (__kernel_text_address(addr)) {
+			if (trace->skip > 0)
+				trace->skip--;
+			else
+				trace->entries[trace->nr_entries++] = addr;
+			if (trace->nr_entries >= trace->max_entries)
+				break;
+		}
+	}
+}
+
+static void save_context_stack(struct stack_trace *trace,
+	struct task_struct *task, struct pt_regs *regs)
+{
+	unsigned long sp = regs->regs[29];
+#ifdef CONFIG_KALLSYMS
+	unsigned long ra = regs->regs[31];
+	unsigned long pc = regs->cp0_epc;
+
+	if (raw_show_trace || !__kernel_text_address(pc)) {
+		unsigned long stack_page =
+			(unsigned long)task_stack_page(task);
+		if (stack_page && sp >= stack_page &&
+		    sp <= stack_page + THREAD_SIZE - 32)
+			save_raw_context_stack(trace, sp);
+		return;
+	}
+	do {
+		if (trace->skip > 0)
+			trace->skip--;
+		else
+			trace->entries[trace->nr_entries++] = pc;
+		if (trace->nr_entries >= trace->max_entries)
+			break;
+		pc = unwind_stack(task, &sp, pc, &ra);
+	} while (pc);
+#else
+	save_raw_context_stack(sp);
+#endif
+}
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+	struct pt_regs dummyregs;
+	struct pt_regs *regs = &dummyregs;
+
+	WARN_ON(trace->nr_entries || !trace->max_entries);
+
+	if (task && task != current) {
+		regs->regs[29] = task->thread.reg29;
+		regs->regs[31] = 0;
+		regs->cp0_epc = task->thread.reg31;
+	} else {
+		if (!task)
+			task = current;
+		prepare_frametrace(regs);
+	}
+
+	save_context_stack(trace, task, regs);
+}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 9951240..26e1a7e 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -231,7 +231,7 @@
  */
 asmlinkage int sys_uname(struct old_utsname __user * name)
 {
-	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+	if (name && !copy_to_user(name, utsname(), sizeof (*name)))
 		return 0;
 	return -EFAULT;
 }
@@ -248,16 +248,21 @@
 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 		return -EFAULT;
 
-	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
-	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
-	error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
-	error -= __put_user(0,name->release+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
-	error -= __put_user(0,name->version+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+	error = __copy_to_user(&name->sysname, &utsname()->sysname,
+			       __OLD_UTS_LEN);
+	error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->nodename, &utsname()->nodename,
+				__OLD_UTS_LEN);
+	error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->release, &utsname()->release,
+				__OLD_UTS_LEN);
+	error -= __put_user(0, name->release + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->version, &utsname()->version,
+				__OLD_UTS_LEN);
+	error -= __put_user(0, name->version + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->machine, &utsname()->machine,
+				__OLD_UTS_LEN);
+	error = __put_user(0, name->machine + __OLD_UTS_LEN);
 	error = error ? -EFAULT : 0;
 
 	return error;
@@ -401,3 +406,32 @@
 {
 	do_exit(SIGSEGV);
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register unsigned long __a0 asm("$4") = (unsigned long) filename;
+	register unsigned long __a1 asm("$5") = (unsigned long) argv;
+	register unsigned long __a2 asm("$6") = (unsigned long) envp;
+	register unsigned long __a3 asm("$7");
+	unsigned long __v0;
+
+	__asm__ volatile ("					\n"
+	"	.set	noreorder				\n"
+	"	li	$2, %5		# __NR_execve		\n"
+	"	syscall						\n"
+	"	move	%0, $2					\n"
+	"	.set	reorder					\n"
+	: "=&r" (__v0), "=r" (__a3)
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
+	  "memory");
+
+	if (__a3 == 0)
+		return __v0;
+
+	return -__v0;
+}
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 1137dd6..93c74fe 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -884,7 +884,7 @@
 	down_read(&uts_sem);
 	if (len > __NEW_UTS_LEN)
 		len = __NEW_UTS_LEN;
-	err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
+	err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0;
 	up_read(&uts_sem);
 
 	return err;
@@ -1127,11 +1127,11 @@
 asmlinkage int irix_uname(struct iuname __user *buf)
 {
 	down_read(&uts_sem);
-	if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
-	    || copy_from_user(system_utsname.nodename, buf->nodename, 65)
-	    || copy_from_user(system_utsname.release, buf->release, 65)
-	    || copy_from_user(system_utsname.version, buf->version, 65)
-	    || copy_from_user(system_utsname.machine, buf->machine, 65)) {
+	if (copy_from_user(utsname()->sysname, buf->sysname, 65)
+	    || copy_from_user(utsname()->nodename, buf->nodename, 65)
+	    || copy_from_user(utsname()->release, buf->release, 65)
+	    || copy_from_user(utsname()->version, buf->version, 65)
+	    || copy_from_user(utsname()->machine, buf->machine, 65)) {
 		return -EFAULT;
 	}
 	up_read(&uts_sem);
@@ -1739,12 +1739,13 @@
 #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
 
 static int irix_filldir32(void *__buf, const char *name,
-	int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+	int namlen, loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct irix_dirent32 __user *dirent;
 	struct irix_dirent32_callback *buf = __buf;
 	unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
 	int err = 0;
+	u32 d_ino;
 
 #ifdef DEBUG_GETDENTS
 	printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
@@ -1753,12 +1754,15 @@
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	if (dirent)
 		err = __put_user(offset, &dirent->d_off);
 	dirent = buf->current_dir;
 	err |= __put_user(dirent, &buf->previous);
-	err |= __put_user(ino, &dirent->d_ino);
+	err |= __put_user(d_ino, &dirent->d_ino);
 	err |= __put_user(reclen, &dirent->d_reclen);
 	err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
 	err |= __put_user(0, &dirent->d_name[namlen]);
@@ -1837,7 +1841,7 @@
 #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
 
 static int irix_filldir64(void *__buf, const char *name,
-	int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+	int namlen, loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct irix_dirent64 __user *dirent;
 	struct irix_dirent64_callback * buf = __buf;
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 845c7e5..a834080 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -149,80 +149,6 @@
 unsigned int (*mips_hpt_read)(void);
 void (*mips_hpt_init)(unsigned int);
 
-
-/*
- * This version of gettimeofday has microsecond resolution and better than
- * microsecond precision on fast machines with cycle counter.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long seq;
-	unsigned long usec, sec;
-	unsigned long max_ntp_tick;
-
-	do {
-		seq = read_seqbegin(&xtime_lock);
-
-		usec = do_gettimeoffset();
-
-		/*
-		 * If time_adjust is negative then NTP is slowing the clock
-		 * so make sure not to go into next possible interval.
-		 * Better to lose some accuracy than have time go backwards..
-		 */
-		if (unlikely(time_adjust < 0)) {
-			max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
-			usec = min(usec, max_ntp_tick);
-		}
-
-		sec = xtime.tv_sec;
-		usec += (xtime.tv_nsec / 1000);
-
-	} while (read_seqretry(&xtime_lock, seq));
-
-	while (usec >= 1000000) {
-		usec -= 1000000;
-		sec++;
-	}
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
-	time_t wtm_sec, sec = tv->tv_sec;
-	long wtm_nsec, nsec = tv->tv_nsec;
-
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	write_seqlock_irq(&xtime_lock);
-
-	/*
-	 * This is revolting.  We need to set "xtime" correctly.  However,
-	 * the value in this location is the value at the most recent update
-	 * of wall time.  Discover what correction gettimeofday() would have
-	 * made, and then undo it!
-	 */
-	nsec -= do_gettimeoffset() * NSEC_PER_USEC;
-
-	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-	set_normalized_timespec(&xtime, sec, nsec);
-	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-	ntp_clear();
-	write_sequnlock_irq(&xtime_lock);
-	clock_was_set();
-	return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
 /*
  * Gettimeoffset routines.  These routines returns the time duration
  * since last timer interrupt in usecs.
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index e51d8fd..b7292a5 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -41,6 +41,7 @@
 #include <asm/mmu_context.h>
 #include <asm/watch.h>
 #include <asm/types.h>
+#include <asm/stacktrace.h>
 
 extern asmlinkage void handle_int(void);
 extern asmlinkage void handle_tlbm(void);
@@ -92,16 +93,14 @@
 }
 
 #ifdef CONFIG_KALLSYMS
-static int raw_show_trace;
+int raw_show_trace;
 static int __init set_raw_show_trace(char *str)
 {
 	raw_show_trace = 1;
 	return 1;
 }
 __setup("raw_show_trace", set_raw_show_trace);
-
-extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
-				  unsigned long pc, unsigned long ra);
+#endif
 
 static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
 {
@@ -116,14 +115,10 @@
 	printk("Call Trace:\n");
 	do {
 		print_ip_sym(pc);
-		pc = unwind_stack(task, &sp, pc, ra);
-		ra = 0;
+		pc = unwind_stack(task, &sp, pc, &ra);
 	} while (pc);
 	printk("\n");
 }
-#else
-#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]);
-#endif
 
 /*
  * This routine abuses get_user()/put_user() to reference pointers
@@ -158,28 +153,6 @@
 	show_backtrace(task, regs);
 }
 
-static __always_inline void prepare_frametrace(struct pt_regs *regs)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set noat\n\t"
-#ifdef CONFIG_64BIT
-		"1: dla $1, 1b\n\t"
-		"sd $1, %0\n\t"
-		"sd $29, %1\n\t"
-		"sd $31, %2\n\t"
-#else
-		"1: la $1, 1b\n\t"
-		"sw $1, %0\n\t"
-		"sw $29, %1\n\t"
-		"sw $31, %2\n\t"
-#endif
-		".set pop\n\t"
-		: "=m" (regs->cp0_epc),
-		"=m" (regs->regs[29]), "=m" (regs->regs[31])
-		: : "memory");
-}
-
 void show_stack(struct task_struct *task, unsigned long *sp)
 {
 	struct pt_regs regs;
@@ -206,11 +179,6 @@
 {
 	struct pt_regs regs;
 
-	/*
-	 * Remove any garbage that may be in regs (specially func
-	 * addresses) to avoid show_raw_backtrace() to report them
-	 */
-	memset(&regs, 0, sizeof(regs));
 	prepare_frametrace(&regs);
 	show_backtrace(current, &regs);
 }
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index 0ffc43c..14c5516 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -34,7 +34,6 @@
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
-#include <asm/serial.h>
 #include <asm/lasat/lasat.h>
 #include <asm/lasat/serial.h>
 
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index e1f35ef..d1af42c 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -268,26 +268,6 @@
 {
 }
 
-static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long physpage;
-
-	if (cpu_context(smp_processor_id(), mm) == 0)
-		return;
-
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page);
-#endif
-
-	physpage = (unsigned long) page_address(page);
-	if (physpage)
-		r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
-}
-
 static void r3k_flush_cache_sigtramp(unsigned long addr)
 {
 	unsigned long flags;
@@ -335,7 +315,6 @@
 	flush_cache_mm = r3k_flush_cache_mm;
 	flush_cache_range = r3k_flush_cache_range;
 	flush_cache_page = r3k_flush_cache_page;
-	__flush_icache_page = r3k_flush_icache_page;
 	flush_icache_range = r3k_flush_icache_range;
 
 	flush_cache_sigtramp = r3k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 0b2da53..cc895da 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -551,82 +551,6 @@
 	instruction_hazard();
 }
 
-/*
- * Ok, this seriously sucks.  We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing.  Otoh we at
- * least know the kernel address of the page so we can flush it
- * selectivly.
- */
-
-struct flush_icache_page_args {
-	struct vm_area_struct *vma;
-	struct page *page;
-};
-
-static inline void local_r4k_flush_icache_page(void *args)
-{
-	struct flush_icache_page_args *fip_args = args;
-	struct vm_area_struct *vma = fip_args->vma;
-	struct page *page = fip_args->page;
-
-	/*
-	 * Tricky ...  Because we don't know the virtual address we've got the
-	 * choice of either invalidating the entire primary and secondary
-	 * caches or invalidating the secondary caches also.  With the subset
-	 * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the
-	 * secondary cache will result in any entries in the primary caches
-	 * also getting invalidated which hopefully is a bit more economical.
-	 */
-	if (cpu_has_inclusive_pcaches) {
-		unsigned long addr = (unsigned long) page_address(page);
-
-		r4k_blast_scache_page(addr);
-		ClearPageDcacheDirty(page);
-
-		return;
-	}
-
-	if (!cpu_has_ic_fills_f_dc) {
-		unsigned long addr = (unsigned long) page_address(page);
-		r4k_blast_dcache_page(addr);
-		if (!cpu_icache_snoops_remote_store)
-			r4k_blast_scache_page(addr);
-		ClearPageDcacheDirty(page);
-	}
-
-	/*
-	 * We're not sure of the virtual address(es) involved here, so
-	 * we have to flush the entire I-cache.
-	 */
-	if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) {
-		int cpu = smp_processor_id();
-
-		if (cpu_context(cpu, vma->vm_mm) != 0)
-			drop_mmu_context(vma->vm_mm, cpu);
-	} else
-		r4k_blast_icache();
-}
-
-static void r4k_flush_icache_page(struct vm_area_struct *vma,
-	struct page *page)
-{
-	struct flush_icache_page_args args;
-
-	/*
-	 * If there's no context yet, or the page isn't executable, no I-cache
-	 * flush is needed.
-	 */
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-	args.vma = vma;
-	args.page = page;
-
-	r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
-}
-
-
 #ifdef CONFIG_DMA_NONCOHERENT
 
 static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
@@ -1291,7 +1215,6 @@
 	__flush_cache_all	= r4k___flush_cache_all;
 	flush_cache_mm		= r4k_flush_cache_mm;
 	flush_cache_page	= r4k_flush_cache_page;
-	__flush_icache_page	= r4k_flush_icache_page;
 	flush_cache_range	= r4k_flush_cache_range;
 
 	flush_cache_sigtramp	= r4k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 16bad7c..5537558 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -307,66 +307,6 @@
 #endif
 
 /*
- * Flush the icache for a given physical page.  Need to writeback the
- * dcache first, then invalidate the icache.  If the page isn't
- * executable, nothing is required.
- */
-static void local_sb1_flush_icache_page(struct vm_area_struct *vma,
-	struct page *page)
-{
-	unsigned long start;
-	int cpu = smp_processor_id();
-
-#ifndef CONFIG_SMP
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-#endif
-
-	/* Need to writeback any dirty data for that page, we have the PA */
-	start = (unsigned long)(page-mem_map) << PAGE_SHIFT;
-	__sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE);
-	/*
-	 * If there's a context, bump the ASID (cheaper than a flush,
-	 * since we don't know VAs!)
-	 */
-	if (vma->vm_mm == current->active_mm) {
-		if (cpu_context(cpu, vma->vm_mm) != 0)
-			drop_mmu_context(vma->vm_mm, cpu);
-	} else
-		__sb1_flush_icache_range(start, start + PAGE_SIZE);
-
-}
-
-#ifdef CONFIG_SMP
-struct flush_icache_page_args {
-	struct vm_area_struct *vma;
-	struct page *page;
-};
-
-static void sb1_flush_icache_page_ipi(void *info)
-{
-	struct flush_icache_page_args *args = info;
-	local_sb1_flush_icache_page(args->vma, args->page);
-}
-
-/* Dirty dcache could be on another CPU, so do the IPIs */
-static void sb1_flush_icache_page(struct vm_area_struct *vma,
-	struct page *page)
-{
-	struct flush_icache_page_args args;
-
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-	args.vma = vma;
-	args.page = page;
-	on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1);
-}
-#else
-void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-	__attribute__((alias("local_sb1_flush_icache_page")));
-#endif
-
-/*
  * A signal trampoline must fit into a single cacheline.
  */
 static void local_sb1_flush_cache_sigtramp(unsigned long addr)
@@ -526,7 +466,6 @@
 
 	/* These routines are for Icache coherence with the Dcache */
 	flush_icache_range = sb1_flush_icache_range;
-	__flush_icache_page = sb1_flush_icache_page;
 	flush_icache_all = __sb1_flush_icache_all; /* local only */
 
 	/* This implies an Icache flush too, so can't be nop'ed */
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 932a09d..f32ebde 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -248,33 +248,6 @@
 	}
 }
 
-/*
- * Ok, this seriously sucks.  We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing.  Otoh we at
- * least know the kernel address of the page so we can flush it
- * selectivly.
- */
-static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-	unsigned long addr;
-	/*
-	 * If there's no context yet, or the page isn't executable, no icache
-	 * flush is needed.
-	 */
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-	addr = (unsigned long) page_address(page);
-	tx39_blast_dcache_page(addr);
-
-	/*
-	 * We're not sure of the virtual address(es) involved here, so
-	 * we have to flush the entire I-cache.
-	 */
-	tx39_blast_icache();
-}
-
 static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 {
 	unsigned long end;
@@ -382,7 +355,6 @@
 		flush_cache_mm		= (void *) tx39h_flush_icache_all;
 		flush_cache_range	= (void *) tx39h_flush_icache_all;
 		flush_cache_page	= (void *) tx39h_flush_icache_all;
-		__flush_icache_page	= (void *) tx39h_flush_icache_all;
 		flush_icache_range	= (void *) tx39h_flush_icache_all;
 
 		flush_cache_sigtramp	= (void *) tx39h_flush_icache_all;
@@ -408,7 +380,6 @@
 		flush_cache_mm = tx39_flush_cache_mm;
 		flush_cache_range = tx39_flush_cache_range;
 		flush_cache_page = tx39_flush_cache_page;
-		__flush_icache_page = tx39_flush_icache_page;
 		flush_icache_range = tx39_flush_icache_range;
 
 		flush_cache_sigtramp = tx39_flush_cache_sigtramp;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 40c8b02..caf807d 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -25,7 +25,6 @@
 void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
 	unsigned long pfn);
 void (*flush_icache_range)(unsigned long start, unsigned long end);
-void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 
 /* MIPS specific cache operations */
 void (*flush_cache_sigtramp)(unsigned long addr);
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 5b06349..88b72c9 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -163,10 +163,10 @@
 
 void __init paging_init(void)
 {
-	unsigned long zones_size[] = { 0, };
+	unsigned long zones_size[MAX_NR_ZONES] = { 0, };
 	unsigned long max_dma, high, low;
 #ifndef CONFIG_FLATMEM
-	unsigned long zholes_size[] = { 0, };
+	unsigned long zholes_size[MAX_NR_ZONES] = { 0, };
 	unsigned long i, j, pfn;
 #endif
 
diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S
index 9e7f417..e99eaa1 100644
--- a/arch/mips/mm/tlbex-fault.S
+++ b/arch/mips/mm/tlbex-fault.S
@@ -19,8 +19,8 @@
 	move	a0, sp
 	REG_S	a2, PT_BVADDR(sp)
 	li	a1, \write
-	jal	do_page_fault
-	j	ret_from_exception
+	PTR_LA	ra, ret_from_exception
+	j	do_page_fault
 	END(tlb_do_page_fault_\write)
 	.endm
 
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 375e099..6f8b25c 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -1211,7 +1211,7 @@
 	 * Overflow check: For the 64bit handler, we need at least one
 	 * free instruction slot for the wrap-around branch. In worst
 	 * case, if the intended insertion point is a delay slot, we
-	 * need three, with the the second nop'ed and the third being
+	 * need three, with the second nop'ed and the third being
 	 * unused.
 	 */
 #ifdef CONFIG_32BIT
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index edefa97..3cf0dd4 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -7,7 +7,6 @@
 #
 # PCI bus host bridge specific code
 #
-obj-$(CONFIG_ITE_BOARD_GEN)	+= ops-it8172.o
 obj-$(CONFIG_MIPS_BONITO64)	+= ops-bonito64.o
 obj-$(CONFIG_MIPS_GT64111)	+= ops-gt64111.o
 obj-$(CONFIG_MIPS_GT64120)	+= ops-gt64120.o
@@ -28,8 +27,6 @@
 obj-$(CONFIG_MIPS_ATLAS)	+= fixup-atlas.o
 obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
 obj-$(CONFIG_MIPS_EV64120)	+= fixup-ev64120.o
-obj-$(CONFIG_MIPS_ITE8172)	+= fixup-ite8172g.o
-obj-$(CONFIG_MIPS_IVR)		+= fixup-ivr.o
 obj-$(CONFIG_SOC_AU1500)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)	+= fixup-pnx8550.o ops-pnx8550.o
diff --git a/arch/mips/pci/fixup-ite8172g.c b/arch/mips/pci/fixup-ite8172g.c
deleted file mode 100644
index 2290ea4..0000000
--- a/arch/mips/pci/fixup-ite8172g.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	Board specific pci fixups.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_pci.h>
-#include <asm/it8172/it8172_int.h>
-
-/*
- * Shortcuts
- */
-#define INTA	IT8172_PCI_INTA_IRQ
-#define INTB	IT8172_PCI_INTB_IRQ
-#define INTC	IT8172_PCI_INTC_IRQ
-#define INTD	IT8172_PCI_INTD_IRQ
-
-static const int internal_func_irqs[7] __initdata = {
-	IT8172_AC97_IRQ,
-	IT8172_DMA_IRQ,
-	IT8172_CDMA_IRQ,
-	IT8172_USB_IRQ,
-	IT8172_BRIDGE_MASTER_IRQ,
-	IT8172_IDE_IRQ,
-	IT8172_MC68K_IRQ
-};
-
-static char irq_tab_ite8172g[][5] __initdata = {
- [0x10] = {	0, INTA, INTB, INTC, INTD },
- [0x11] = {	0, INTA, INTB, INTC, INTD },
- [0x12] = {	0, INTB, INTC, INTD, INTA },
- [0x13] = {	0, INTC, INTD, INTA, INTB },
- [0x14] = {	0, INTD, INTA, INTB, INTC },
-};
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-	/*
-	 * Internal device 1 is actually 7 different internal devices on the
-	 * IT8172G (a multifunction device).
-	 */
-	if (slot == 1)
-		return internal_func_irqs[PCI_FUNC(dev->devfn)];
-
-	return irq_tab_ite8172g[slot][pin];
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-	return 0;
-}
diff --git a/arch/mips/pci/fixup-ivr.c b/arch/mips/pci/fixup-ivr.c
deleted file mode 100644
index 0c7c164..0000000
--- a/arch/mips/pci/fixup-ivr.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	Globespan IVR board-specific pci fixups.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_pci.h>
-#include <asm/it8172/it8172_int.h>
-
-/*
- * Shortcuts
- */
-#define INTA	IT8172_PCI_INTA_IRQ
-#define INTB	IT8172_PCI_INTB_IRQ
-#define INTC	IT8172_PCI_INTC_IRQ
-#define INTD	IT8172_PCI_INTD_IRQ
-
-static const int internal_func_irqs[7] __initdata = {
-	IT8172_AC97_IRQ,
-	IT8172_DMA_IRQ,
-	IT8172_CDMA_IRQ,
-	IT8172_USB_IRQ,
-	IT8172_BRIDGE_MASTER_IRQ,
-	IT8172_IDE_IRQ,
-	IT8172_MC68K_IRQ
-};
-
-static char irq_tab_ivr[][5] __initdata = {
- [0x11] = { INTC, INTC, INTD, INTA, INTB },	/* Realtek RTL-8139	*/
- [0x12] = { INTB, INTB, INTB, INTC, INTC },	/* IVR slot		*/
- [0x13] = { INTA, INTA, INTB, INTC, INTD }	/* Expansion slot	*/
-};
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-	if (slot == 1)
-		return internal_func_irqs[PCI_FUNC(dev->devfn)];
-
-	return irq_tab_ivr[slot][pin];
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-	return 0;
-}
diff --git a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c
index 13791b7..7a74448 100644
--- a/arch/mips/pci/fixup-sb1250.c
+++ b/arch/mips/pci/fixup-sb1250.c
@@ -1,7 +1,7 @@
 /*
  *	arch/mips/pci/fixup-sb1250.c
  *
- *	Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
+ *	Copyright (C) 2004, 2006  MIPS Technologies, Inc.  All rights reserved.
  *	    Author:	Maciej W. Rozycki <macro@mips.com>
  *
  *	This program is free software; you can redistribute it and/or
@@ -14,6 +14,17 @@
 #include <linux/pci.h>
 
 /*
+ * Set the the BCM1250, etc. PCI host bridge's TRDY timeout
+ * to the finite max.
+ */
+static void __init quirk_sb1250_pci(struct pci_dev *dev)
+{
+	pci_write_config_byte(dev, 0x40, 0xff);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI,
+			quirk_sb1250_pci);
+
+/*
  * The BCM1250, etc. PCI/HT bridge reports as a host bridge.
  */
 static void __init quirk_sb1250_ht(struct pci_dev *dev)
@@ -22,3 +33,13 @@
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
 			quirk_sb1250_ht);
+
+/*
+ * Set the the SP1011 HT/PCI bridge's TRDY timeout to the finite max.
+ */
+static void __init quirk_sp1011(struct pci_dev *dev)
+{
+	pci_write_config_byte(dev, 0x64, 0xff);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIPACKETS, PCI_DEVICE_ID_SP1011,
+			quirk_sp1011);
diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c
index 8e01d0c..597b897 100644
--- a/arch/mips/pci/fixup-vr4133.c
+++ b/arch/mips/pci/fixup-vr4133.c
@@ -1,5 +1,5 @@
 /*
- * arch/mips/vr41xx/nec-cmbvr4133/pci_fixup.c
+ * arch/mips/pci/fixup-vr4133.c
  *
  * The NEC CMB-VR4133 Board specific PCI fixups.
  *
diff --git a/arch/mips/pci/ops-it8172.c b/arch/mips/pci/ops-it8172.c
deleted file mode 100644
index ba83285..0000000
--- a/arch/mips/pci/ops-it8172.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	IT8172 system controller specific pci support.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_pci.h>
-
-#define PCI_ACCESS_READ  0
-#define PCI_ACCESS_WRITE 1
-
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-static struct resource pci_mem_resource_1;
-
-static struct resource pci_io_resource = {
-	.start	= 0x14018000,
-	.end	= 0x17FFFFFF,
-	.name	= "io pci IO space",
-	.flags	= IORESOURCE_IO
-};
-
-static struct resource pci_mem_resource_0 = {
-	.start	= 0x10101000,
-	.end	= 0x13FFFFFF,
-	.name	= "ext pci memory space 0/1",
-	.flags	= IORESOURCE_MEM,
-	.parent	= &pci_mem_resource_0,
-	.sibling = NULL,
-	.child	= &pci_mem_resource_1
-};
-
-static struct resource pci_mem_resource_1 = {
-	.start	= 0x1A000000,
-	.end	= 0x1FBFFFFF,
-	.name	= "ext pci memory space 2/3",
-	.flags	= IORESOURCE_MEM,
-	.parent	= &pci_mem_resource_0
-};
-
-extern struct pci_ops it8172_pci_ops;
-
-struct pci_controller it8172_controller = {
-	.pci_ops	= &it8172_pci_ops,
-	.io_resource	= &pci_io_resource,
-	.mem_resource	= &pci_mem_resource_0,
-};
-
-static int it8172_pcibios_config_access(unsigned char access_type,
-					struct pci_bus *bus,
-					unsigned int devfn, int where,
-					u32 * data)
-{
-	/*
-	 * config cycles are on 4 byte boundary only
-	 */
-
-	/* Setup address */
-	IT_WRITE(IT_CONFADDR, (bus->number << IT_BUSNUM_SHF) |
-		 (devfn << IT_FUNCNUM_SHF) | (where & ~0x3));
-
-	if (access_type == PCI_ACCESS_WRITE) {
-		IT_WRITE(IT_CONFDATA, *data);
-	} else {
-		IT_READ(IT_CONFDATA, *data);
-	}
-
-	/*
-	 * Revisit: check for master or target abort.
-	 */
-	return 0;
-}
-
-
-/*
- * We can't address 8 and 16 bit words directly.  Instead we have to
- * read/write a 32bit word and mask/modify the data we actually want.
- */
-static write_config(struct pci_bus *bus, unsigned int devfn, int where,
-		    int size, u32 val)
-{
-	u32 data = 0;
-
-	switch (size) {
-	case 1:
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_READ, dev, where, &data))
-			return -1;
-
-		*val = (data >> ((where & 3) << 3)) & 0xff;
-
-		return PCIBIOS_SUCCESSFUL;
-
-	case 2:
-
-		if (where & 1)
-			return PCIBIOS_BAD_REGISTER_NUMBER;
-
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_READ, dev, where, &data))
-			return -1;
-
-		*val = (data >> ((where & 3) << 3)) & 0xffff;
-		DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n",
-		    dev->bus->number, dev->devfn, where, *val);
-
-		return PCIBIOS_SUCCESSFUL;
-
-	case 4:
-
-		if (where & 3)
-			return PCIBIOS_BAD_REGISTER_NUMBER;
-
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_READ, dev, where, &data))
-			return -1;
-
-		*val = data;
-
-		return PCIBIOS_SUCCESSFUL;
-	}
-}
-
-
-static write_config(struct pci_bus *bus, unsigned int devfn, int where,
-		    int size, u32 val)
-{
-	u32 data = 0;
-
-	switch (size) {
-	case 1:
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_READ, dev, where, &data))
-			return -1;
-
-		data = (data & ~(0xff << ((where & 3) << 3))) |
-		    (val << ((where & 3) << 3));
-
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_WRITE, dev, where, &data))
-			return -1;
-
-		return PCIBIOS_SUCCESSFUL;
-
-	case 2:
-		if (where & 1)
-			return PCIBIOS_BAD_REGISTER_NUMBER;
-
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_READ, dev, where, &data))
-			eturn - 1;
-
-		data = (data & ~(0xffff << ((where & 3) << 3))) |
-		    (val << ((where & 3) << 3));
-
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_WRITE, dev, where, &data))
-			return -1;
-
-		return PCIBIOS_SUCCESSFUL;
-
-	case 4:
-		if (where & 3)
-			return PCIBIOS_BAD_REGISTER_NUMBER;
-
-		if (it8172_pcibios_config_access
-		    (PCI_ACCESS_WRITE, dev, where, &val))
-			return -1;
-
-		return PCIBIOS_SUCCESSFUL;
-	}
-}
-
-struct pci_ops it8172_pci_ops = {
-	.read = read_config,
-	.write = write_config,
-};
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 8134220..7a941ec 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -123,7 +123,8 @@
 	if (machine_state & MACHINE_PANICED)
 		return;
 
-	if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) {
+	if ((machine_state & MACHINE_SHUTTING_DOWN) ||
+			kill_cad_pid(SIGINT, 1)) {
 		/* No init process or button pressed twice.  */
 		sgi_machine_power_off();
 	}
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 79ddb46..fd0932b 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -120,7 +120,7 @@
 	if (has_panicked)
 		return;
 
-	if (shuting_down || kill_proc(1, SIGINT, 1)) {
+	if (shuting_down || kill_cad_pid(SIGINT, 1)) {
 		/* No init process or button pressed twice.  */
 		ip32_machine_power_off();
 	}
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index a0222fa..a46b75b 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -482,7 +482,7 @@
 	write_c0_compare(read_c0_count());
 #endif
 
-	pending = read_c0_cause();
+	pending = read_c0_cause() & read_c0_status();
 
 #ifdef CONFIG_SIBYTE_BCM1480_PROF
 	if (pending & CAUSEF_IP7)	/* Cpu performance counter interrupt */
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index a451b4c..f9bd9f0 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -442,7 +442,7 @@
 	 * blasting the high 32 bits.
 	 */
 
-	pending = read_c0_cause();
+	pending = read_c0_cause() & read_c0_status();
 
 #ifdef CONFIG_SIBYTE_SB1250_PROF
 	if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
@@ -476,5 +476,8 @@
 		                              R_IMR_INTERRUPT_STATUS_BASE)));
 		if (mask)
 			do_IRQ(fls64(mask) - 1, regs);
-	}
+		else
+			spurious_interrupt(regs);
+	} else
+		spurious_interrupt(regs);
 }
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c
index dc30d66..cbfb342 100644
--- a/arch/mips/tx4938/common/irq.c
+++ b/arch/mips/tx4938/common/irq.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/mps/tx4938/common/irq.c
+ * linux/arch/mips/tx4938/common/irq.c
  *
  * Common tx4938 irq handler
  * Copyright (C) 2000-2001 Toshiba Corporation
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 6dd0ea8..d210123 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -127,7 +127,7 @@
 
 config PREFETCH
 	def_bool y
-	depends on PA8X00
+	depends on PA8X00 || PA7200
 
 config 64BIT
 	bool "64-bit kernel"
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index d7c80ed..2d58b92 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -77,22 +77,26 @@
 {
 	struct hpux_dirent * dirent;
 	struct getdents_callback * buf = (struct getdents_callback *) __buf;
+	ino_t d_ino;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	if (dirent)
 		put_user(offset, &dirent->d_off);
 	dirent = buf->current_dir;
 	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(reclen, &dirent->d_reclen);
 	put_user(namlen, &dirent->d_namlen);
 	copy_to_user(dirent->d_name, name, namlen);
 	put_user(0, dirent->d_name + namlen);
-	((char *) dirent) += reclen;
+	dirent = (void __user *)dirent + reclen;
 	buf->current_dir = dirent;
 	buf->count -= reclen;
 	return 0;
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index cb69727..2e2dc4f 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -266,16 +266,21 @@
 
 	down_read(&uts_sem);
 
-	error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
-	error |= __put_user(0,name->sysname+HPUX_UTSLEN-1);
-	error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1);
-	error |= __put_user(0,name->nodename+HPUX_UTSLEN-1);
-	error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1);
-	error |= __put_user(0,name->release+HPUX_UTSLEN-1);
-	error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1);
-	error |= __put_user(0,name->version+HPUX_UTSLEN-1);
-	error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1);
-	error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
+	error = __copy_to_user(&name->sysname, &utsname()->sysname,
+			       HPUX_UTSLEN - 1);
+	error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1);
+	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+				HPUX_UTSLEN - 1);
+	error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1);
+	error |= __copy_to_user(&name->release, &utsname()->release,
+				HPUX_UTSLEN - 1);
+	error |= __put_user(0, name->release + HPUX_UTSLEN - 1);
+	error |= __copy_to_user(&name->version, &utsname()->version,
+				HPUX_UTSLEN - 1);
+	error |= __put_user(0, name->version + HPUX_UTSLEN - 1);
+	error |= __copy_to_user(&name->machine, &utsname()->machine,
+				HPUX_UTSLEN - 1);
+	error |= __put_user(0, name->machine + HPUX_UTSLEN - 1);
 
 	up_read(&uts_sem);
 
@@ -373,8 +378,8 @@
 		/*  TODO:  print a warning about using this?  */
 		down_write(&uts_sem);
 		error = -EFAULT;
-		if (!copy_from_user(system_utsname.sysname, ubuf, len)) {
-			system_utsname.sysname[len] = 0;
+		if (!copy_from_user(utsname()->sysname, ubuf, len)) {
+			utsname()->sysname[len] = 0;
 			error = 0;
 		}
 		up_write(&uts_sem);
@@ -400,8 +405,8 @@
 		/*  TODO:  print a warning about this?  */
 		down_write(&uts_sem);
 		error = -EFAULT;
-		if (!copy_from_user(system_utsname.release, ubuf, len)) {
-			system_utsname.release[len] = 0;
+		if (!copy_from_user(utsname()->release, ubuf, len)) {
+			utsname()->release[len] = 0;
 			error = 0;
 		}
 		up_write(&uts_sem);
@@ -422,13 +427,13 @@
  	
  	down_read(&uts_sem);
  	
-	nlen = strlen(system_utsname.domainname) + 1;
+	nlen = strlen(utsname()->domainname) + 1;
 
 	if (nlen < len)
 		len = nlen;
 	if(len > __NEW_UTS_LEN)
 		goto done;
-	if(copy_to_user(name, system_utsname.domainname, len))
+	if(copy_to_user(name, utsname()->domainname, len))
 		goto done;
 	err = 0;
 done:
diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
index d1833f1..1e64e7b 100644
--- a/arch/parisc/kernel/binfmt_elf32.c
+++ b/arch/parisc/kernel/binfmt_elf32.c
@@ -87,7 +87,7 @@
  */
 
 #define SET_PERSONALITY(ex, ibcs2) \
-	current->personality = PER_LINUX32; \
+	set_thread_flag(TIF_32BIT); \
 	current->thread.map_base = DEFAULT_MAP_BASE32; \
 	current->thread.task_size = DEFAULT_TASK_SIZE32 \
 
@@ -102,25 +102,3 @@
 }
 
 #include "../../../fs/binfmt_elf.c"
-
-/* Set up a separate execution domain for ELF32 binaries running
- * on an ELF64 kernel */
-
-static struct exec_domain parisc32_exec_domain = { 
-	.name = "Linux/ELF32",
-	.pers_low = PER_LINUX32,
-	.pers_high = PER_LINUX32,
-};      
-
-static int __init parisc32_exec_init(void)
-{
-	/* steal the identity signal mappings from the default domain */
-	parisc32_exec_domain.signal_map = default_exec_domain.signal_map;
-	parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
-
-	register_exec_domain(&parisc32_exec_domain);
-
-	return 0;
-}
-
-__initcall(parisc32_exec_init);
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index bc7c4a4..0be51e9 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -35,15 +35,12 @@
 EXPORT_SYMBOL(dcache_stride);
 
 
-#if defined(CONFIG_SMP)
 /* On some machines (e.g. ones with the Merced bus), there can be
  * only a single PxTLB broadcast at a time; this must be guaranteed
  * by software.  We put a spinlock around all TLB flushes  to
  * ensure this.
  */
 DEFINE_SPINLOCK(pa_tlb_lock);
-EXPORT_SYMBOL(pa_tlb_lock);
-#endif
 
 struct pdc_cache_info cache_info __read_mostly;
 #ifndef CONFIG_PA20
@@ -91,7 +88,8 @@
 
 		flush_kernel_dcache_page(page);
 		clear_bit(PG_dcache_dirty, &page->flags);
-	}
+	} else if (parisc_requires_coherency())
+		flush_kernel_dcache_page(page);
 }
 
 void
@@ -370,3 +368,45 @@
 
 	printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
 }
+
+extern void purge_kernel_dcache_page(unsigned long);
+extern void clear_user_page_asm(void *page, unsigned long vaddr);
+
+void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
+{
+	purge_kernel_dcache_page((unsigned long)page);
+	purge_tlb_start();
+	pdtlb_kernel(page);
+	purge_tlb_end();
+	clear_user_page_asm(page, vaddr);
+}
+EXPORT_SYMBOL(clear_user_page);
+
+void flush_kernel_dcache_page_addr(void *addr)
+{
+	flush_kernel_dcache_page_asm(addr);
+	purge_tlb_start();
+	pdtlb_kernel(addr);
+	purge_tlb_end();
+}
+EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+		    struct page *pg)
+{
+	/* no coherency needed (all in kmap/kunmap) */
+	copy_user_page_asm(vto, vfrom);
+	if (!parisc_requires_coherency())
+		flush_kernel_dcache_page_asm(vto);
+}
+EXPORT_SYMBOL(copy_user_page);
+
+#ifdef CONFIG_PA8X00
+
+void kunmap_parisc(void *addr)
+{
+	if (parisc_requires_coherency())
+		flush_kernel_dcache_page_addr(addr);
+}
+EXPORT_SYMBOL(kunmap_parisc);
+#endif
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 95c1b8e..340b5e8 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -30,6 +30,7 @@
 
 
 #include <asm/psw.h>
+#include <asm/cache.h>		/* for L1_CACHE_SHIFT */
 #include <asm/assembly.h>	/* for LDREG/STREG defines */
 #include <asm/pgtable.h>
 #include <asm/signal.h>
@@ -478,11 +479,7 @@
 	bb,>=,n		\pmd,_PxD_PRESENT_BIT,\fault
 	DEP		%r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
 	copy		\pmd,%r9
-#ifdef CONFIG_64BIT
-	shld		%r9,PxD_VALUE_SHIFT,\pmd
-#else
-	shlw		%r9,PxD_VALUE_SHIFT,\pmd
-#endif
+	SHLREG		%r9,PxD_VALUE_SHIFT,\pmd
 	EXTR		\va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
 	DEP		%r0,31,PAGE_SHIFT,\pmd  /* clear offset */
 	shladd		\index,BITS_PER_PTE_ENTRY,\pmd,\pmd
@@ -941,8 +938,8 @@
 	 * to "proper" values now (otherwise we'll wind up restoring
 	 * whatever was last stored in the task structure, which might
 	 * be inconsistent if an interrupt occured while on the gateway
-	 * page) Note that we may be "trashing" values the user put in
-	 * them, but we don't support the the user changing them.
+	 * page). Note that we may be "trashing" values the user put in
+	 * them, but we don't support the user changing them.
 	 */
 
 	STREG   %r0,PT_SR2(%r16)
@@ -970,11 +967,7 @@
 	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
 	** irq_stat[] is defined using ____cacheline_aligned.
 	*/
-#ifdef CONFIG_64BIT
-	shld	%r1, 6, %r20
-#else
-	shlw	%r1, 5, %r20
-#endif
+	SHLREG	%r1,L1_CACHE_SHIFT,%r20
 	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
 #endif /* CONFIG_SMP */
 
@@ -1076,7 +1069,7 @@
 	BL	preempt_schedule_irq, %r2
 	nop
 
-	b	intr_restore		/* ssm PSW_SM_I done by intr_restore */
+	b,n	intr_restore		/* ssm PSW_SM_I done by intr_restore */
 #endif /* CONFIG_PREEMPT */
 
 	.import do_signal,code
@@ -2115,11 +2108,7 @@
 	ldw     TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
 
 	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
-#ifdef CONFIG_64BIT
-	shld	%r26, 6, %r20
-#else
-	shlw	%r26, 5, %r20
-#endif
+	SHLREG	%r26,L1_CACHE_SHIFT,%r20
 	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
 #endif /* CONFIG_SMP */
 
diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c
index 3058bff..18ba4cb 100644
--- a/arch/parisc/kernel/hardware.c
+++ b/arch/parisc/kernel/hardware.c
@@ -231,6 +231,7 @@
 	{HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"},
 	{HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"},
 	{HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"},
+	{HPHW_NPROC,0x5EB,0x4,0x91,"Perf/Leone 875 W2+"},
 	{HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"},
 	{HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"},
 	{HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"},
@@ -584,8 +585,10 @@
 	{HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"}, 
 	{HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"}, 
 	{HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"}, 
+	{HPHW_FABRIC, 0x005, 0x000AA, 0x80, "Keystone DNA Central Agent"},
 	{HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"}, 
 	{HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"}, 
+	{HPHW_FABRIC, 0x005, 0x000AB, 0x00, "Keystone TOGO Fabric Crossbar"},
 	{HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"}, 
 	{HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"}, 
 	{HPHW_FIO, 0x004, 0x0004F, 0x0, "8-Port X.25 EISA-ACC (AMSO)"}, 
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 5b8803c..9bdd019 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -45,6 +45,17 @@
 */
 static volatile unsigned long cpu_eiem = 0;
 
+/*
+** ack bitmap ... habitually set to 1, but reset to zero
+** between ->ack() and ->end() of the interrupt to prevent
+** re-interruption of a processing interrupt.
+*/
+static volatile unsigned long global_ack_eiem = ~0UL;
+/*
+** Local bitmap, same as above but for per-cpu interrupts
+*/
+static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
+
 static void cpu_disable_irq(unsigned int irq)
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
@@ -62,13 +73,6 @@
 
 	cpu_eiem |= eirr_bit;
 
-	/* FIXME: while our interrupts aren't nested, we cannot reset
-	 * the eiem mask if we're already in an interrupt.  Once we
-	 * implement nested interrupts, this can go away
-	 */
-	if (!in_interrupt())
-		set_eiem(cpu_eiem);
-
 	/* This is just a simple NOP IPI.  But what it does is cause
 	 * all the other CPUs to do a set_eiem(cpu_eiem) at the end
 	 * of the interrupt handler */
@@ -84,13 +88,45 @@
 void no_ack_irq(unsigned int irq) { }
 void no_end_irq(unsigned int irq) { }
 
+void cpu_ack_irq(unsigned int irq)
+{
+	unsigned long mask = EIEM_MASK(irq);
+	int cpu = smp_processor_id();
+
+	/* Clear in EIEM so we can no longer process */
+	if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
+		per_cpu(local_ack_eiem, cpu) &= ~mask;
+	else
+		global_ack_eiem &= ~mask;
+
+	/* disable the interrupt */
+	set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+	/* and now ack it */
+	mtctl(mask, 23);
+}
+
+void cpu_end_irq(unsigned int irq)
+{
+	unsigned long mask = EIEM_MASK(irq);
+	int cpu = smp_processor_id();
+
+	/* set it in the eiems---it's no longer in process */
+	if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
+		per_cpu(local_ack_eiem, cpu) |= mask;
+	else
+		global_ack_eiem |= mask;
+
+	/* enable the interrupt */
+	set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+}
+
 #ifdef CONFIG_SMP
 int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
 {
 	int cpu_dest;
 
 	/* timer and ipi have to always be received on all CPUs */
-	if (irq == TIMER_IRQ || irq == IPI_IRQ) {
+	if (CHECK_IRQ_PER_CPU(irq)) {
 		/* Bad linux design decision.  The mask has already
 		 * been set; we must reset it */
 		irq_desc[irq].affinity = CPU_MASK_ALL;
@@ -119,8 +155,8 @@
 	.shutdown	= cpu_disable_irq,
 	.enable		= cpu_enable_irq,
 	.disable	= cpu_disable_irq,
-	.ack		= no_ack_irq,
-	.end		= no_end_irq,
+	.ack		= cpu_ack_irq,
+	.end		= cpu_end_irq,
 #ifdef CONFIG_SMP
 	.set_affinity	= cpu_set_affinity_irq,
 #endif
@@ -209,7 +245,7 @@
 ** Then use that to get the Transaction address and data.
 */
 
-int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data)
+int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
 {
 	if (irq_desc[irq].action)
 		return -EBUSY;
@@ -298,82 +334,69 @@
 	return virt_irq - CPU_IRQ_BASE;
 }
 
+static inline int eirr_to_irq(unsigned long eirr)
+{
+#ifdef CONFIG_64BIT
+	int bit = fls64(eirr);
+#else
+	int bit = fls(eirr);
+#endif
+	return (BITS_PER_LONG - bit) + TIMER_IRQ;
+}
+
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
 	unsigned long eirr_val;
+	int irq, cpu = smp_processor_id();
+#ifdef CONFIG_SMP
+	cpumask_t dest;
+#endif
 
+	local_irq_disable();
 	irq_enter();
 
-	/*
-	 * Don't allow TIMER or IPI nested interrupts.
-	 * Allowing any single interrupt to nest can lead to that CPU
-	 * handling interrupts with all enabled interrupts unmasked.
-	 */
-	set_eiem(0UL);
-
-	/* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
-	 * 2) We loop here on EIRR contents in order to avoid
-	 *    nested interrupts or having to take another interrupt
-	 *    when we could have just handled it right away.
-	 */
-	for (;;) {
-		unsigned long bit = (1UL << (BITS_PER_LONG - 1));
-		unsigned int irq;
-		eirr_val = mfctl(23) & cpu_eiem;
-		if (!eirr_val)
-			break;
-
-		mtctl(eirr_val, 23); /* reset bits we are going to process */
-
-		/* Work our way from MSb to LSb...same order we alloc EIRs */
-		for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
-#ifdef CONFIG_SMP
-			cpumask_t dest = irq_desc[irq].affinity;
-#endif
-			if (!(bit & eirr_val))
-				continue;
-
-			/* clear bit in mask - can exit loop sooner */
-			eirr_val &= ~bit;
+	eirr_val = mfctl(23) & cpu_eiem & global_ack_eiem &
+		per_cpu(local_ack_eiem, cpu);
+	if (!eirr_val)
+		goto set_out;
+	irq = eirr_to_irq(eirr_val);
 
 #ifdef CONFIG_SMP
-			/* FIXME: because generic set affinity mucks
-			 * with the affinity before sending it to us
-			 * we can get the situation where the affinity is
-			 * wrong for our CPU type interrupts */
-			if (irq != TIMER_IRQ && irq != IPI_IRQ &&
-			    !cpu_isset(smp_processor_id(), dest)) {
-				int cpu = first_cpu(dest);
+	dest = irq_desc[irq].affinity;
+	if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) &&
+	    !cpu_isset(smp_processor_id(), dest)) {
+		int cpu = first_cpu(dest);
 
-				printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
-				       irq, smp_processor_id(), cpu);
-				gsc_writel(irq + CPU_IRQ_BASE,
-					   cpu_data[cpu].hpa);
-				continue;
-			}
-#endif
-
-			__do_IRQ(irq, regs);
-		}
+		printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
+		       irq, smp_processor_id(), cpu);
+		gsc_writel(irq + CPU_IRQ_BASE,
+			   cpu_data[cpu].hpa);
+		goto set_out;
 	}
+#endif
+	__do_IRQ(irq, regs);
 
-	set_eiem(cpu_eiem);	/* restore original mask */
+ out:
 	irq_exit();
-}
+	return;
 
+ set_out:
+	set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+	goto out;
+}
 
 static struct irqaction timer_action = {
 	.handler = timer_interrupt,
 	.name = "timer",
-	.flags = IRQF_DISABLED,
+	.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU,
 };
 
 #ifdef CONFIG_SMP
 static struct irqaction ipi_action = {
 	.handler = ipi_interrupt,
 	.name = "IPI",
-	.flags = IRQF_DISABLED,
+	.flags = IRQF_DISABLED | IRQF_PERCPU,
 };
 #endif
 
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 0b485ef..2f9f9df 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -368,7 +368,14 @@
 	return error;
 }
 
-unsigned long 
+extern int __execve(const char *filename, char *const argv[],
+		char *const envp[], struct task_struct *task);
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	return __execve(filename, argv, envp, current);
+}
+
+unsigned long
 get_wchan(struct task_struct *p)
 {
 	struct unwind_frame_info info;
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 99d7fca..fb81e56 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -143,8 +143,9 @@
 	p = &cpu_data[cpuid];
 	boot_cpu_data.cpu_count++;
 
-	/* initialize counters */
-	memset(p, 0, sizeof(struct cpuinfo_parisc));
+	/* initialize counters - CPU 0 gets it_value set in time_init() */
+	if (cpuid)
+		memset(p, 0, sizeof(struct cpuinfo_parisc));
 
 	p->loops_per_jiffy = loops_per_jiffy;
 	p->dev = dev;		/* Save IODC data in case we need it */
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index bb83880..ee6653e 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -26,7 +26,6 @@
 #include <linux/stddef.h>
 #include <linux/compat.h>
 #include <linux/elf.h>
-#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/rt_sigframe.h>
 #include <asm/uaccess.h>
@@ -433,13 +432,13 @@
 	if (in_syscall) {
 		regs->gr[31] = haddr;
 #ifdef __LP64__
-		if (personality(current->personality) == PER_LINUX)
+		if (!test_thread_flag(TIF_32BIT))
 			sigframe_size |= 1;
 #endif
 	} else {
 		unsigned long psw = USER_PSW;
 #ifdef __LP64__
-		if (personality(current->personality) == PER_LINUX)
+		if (!test_thread_flag(TIF_32BIT))
 			psw |= PSW_W;
 #endif
 
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 98e4095..faad338 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -262,6 +262,9 @@
 					this_cpu, which);
 				return IRQ_NONE;
 			} /* Switch */
+		/* let in any pending interrupts */
+		local_irq_enable();
+		local_irq_disable();
 		} /* while (ops) */
 	}
 	return IRQ_HANDLED;
@@ -430,8 +433,9 @@
 static void __init
 smp_cpu_init(int cpunum)
 {
-	extern int init_per_cpu(int);  /* arch/parisc/kernel/setup.c */
+	extern int init_per_cpu(int);  /* arch/parisc/kernel/processor.c */
 	extern void init_IRQ(void);    /* arch/parisc/kernel/irq.c */
+	extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */
 
 	/* Set modes and Enable floating point coprocessor */
 	(void) init_per_cpu(cpunum);
@@ -457,6 +461,7 @@
 	enter_lazy_tlb(&init_mm, current);
 
 	init_IRQ();   /* make sure no IRQ's are enabled or pending */
+	start_cpu_itimer();
 }
 
 
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 8b5df98..1db5588 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -31,6 +31,8 @@
 #include <linux/shm.h>
 #include <linux/smp_lock.h>
 #include <linux/syscalls.h>
+#include <linux/utsname.h>
+#include <linux/personality.h>
 
 int sys_pipe(int __user *fildes)
 {
@@ -248,3 +250,46 @@
 {
 	return -EINVAL;
 }
+
+long parisc_personality(unsigned long personality)
+{
+	long err;
+
+	if (personality(current->personality) == PER_LINUX32
+	    && personality == PER_LINUX)
+		personality = PER_LINUX32;
+
+	err = sys_personality(personality);
+	if (err == PER_LINUX32)
+		err = PER_LINUX;
+
+	return err;
+}
+
+static inline int override_machine(char __user *mach) {
+#ifdef CONFIG_COMPAT
+	if (personality(current->personality) == PER_LINUX32) {
+		if (__put_user(0, mach + 6) ||
+		    __put_user(0, mach + 7))
+			return -EFAULT;
+	}
+
+	return 0;
+#else /*!CONFIG_COMPAT*/
+	return 0;
+#endif /*CONFIG_COMPAT*/
+}
+
+long parisc_newuname(struct new_utsname __user *utsname)
+{
+	int err = 0;
+
+	down_read(&uts_sem);
+	if (copy_to_user(utsname, &system_utsname, sizeof(*utsname)))
+		err = -EFAULT;
+	up_read(&uts_sem);
+
+	err = override_machine(utsname->machine);
+
+	return (long)err;
+}
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index b748698..e3b30bc 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -237,14 +237,19 @@
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+	compat_ino_t ino;
 	int err;
 
 	if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
 	    !new_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
+	ino = stat->ino;
+	if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+		return -EOVERFLOW;
+
 	err  = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
-	err |= put_user(stat->ino, &statbuf->st_ino);
+	err |= put_user(ino, &statbuf->st_ino);
 	err |= put_user(stat->mode, &statbuf->st_mode);
 	err |= put_user(stat->nlink, &statbuf->st_nlink);
 	err |= put_user(0, &statbuf->st_reserved1);
@@ -312,16 +317,20 @@
 	struct linux32_dirent __user * dirent;
 	struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
+	u32 d_ino;
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	if (dirent)
 		put_user(offset, &dirent->d_off);
 	dirent = buf->current_dir;
 	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(reclen, &dirent->d_reclen);
 	copy_to_user(dirent->d_name, name, namlen);
 	put_user(0, dirent->d_name + namlen);
@@ -371,12 +380,16 @@
 {
 	struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
 	struct old_linux32_dirent __user * dirent;
+	u32 d_ino;
 
 	if (buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	buf->count++;
 	dirent = buf->dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(offset, &dirent->d_offset);
 	put_user(namlen, &dirent->d_namlen);
 	copy_to_user(dirent->d_name, name, namlen);
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index e27b432..701d66a 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -132,7 +132,7 @@
 	ENTRY_SAME(socketpair)
 	ENTRY_SAME(setpgid)
 	ENTRY_SAME(send)
-	ENTRY_SAME(newuname)
+	ENTRY_OURS(newuname)
 	ENTRY_SAME(umask)		/* 60 */
 	ENTRY_SAME(chroot)
 	ENTRY_SAME(ustat)
@@ -221,7 +221,7 @@
 	ENTRY_SAME(fchdir)
 	ENTRY_SAME(bdflush)
 	ENTRY_SAME(sysfs)		/* 135 */
-	ENTRY_SAME(personality)
+	ENTRY_OURS(personality)
 	ENTRY_SAME(ni_syscall)	/* for afs_syscall */
 	ENTRY_SAME(setfsuid)
 	ENTRY_SAME(setfsgid)
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index ab641d6..b3496b5 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -32,8 +32,7 @@
 
 #include <linux/timex.h>
 
-static long clocktick __read_mostly;	/* timer cycles per tick */
-static long halftick __read_mostly;
+static unsigned long clocktick __read_mostly;	/* timer cycles per tick */
 
 #ifdef CONFIG_SMP
 extern void smp_do_timer(struct pt_regs *regs);
@@ -41,46 +40,106 @@
 
 irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	long now;
-	long next_tick;
-	int nticks;
-	int cpu = smp_processor_id();
+	unsigned long now;
+	unsigned long next_tick;
+	unsigned long cycles_elapsed;
+	unsigned long cycles_remainder;
+	unsigned int cpu = smp_processor_id();
+
+	/* gcc can optimize for "read-only" case with a local clocktick */
+	unsigned long cpt = clocktick;
 
 	profile_tick(CPU_PROFILING, regs);
 
-	now = mfctl(16);
-	/* initialize next_tick to time at last clocktick */
+	/* Initialize next_tick to the expected tick time. */
 	next_tick = cpu_data[cpu].it_value;
 
-	/* since time passes between the interrupt and the mfctl()
-	 * above, it is never true that last_tick + clocktick == now.  If we
-	 * never miss a clocktick, we could set next_tick = last_tick + clocktick
-	 * but maybe we'll miss ticks, hence the loop.
-	 *
-	 * Variables are *signed*.
+	/* Get current interval timer.
+	 * CR16 reads as 64 bits in CPU wide mode.
+	 * CR16 reads as 32 bits in CPU narrow mode.
 	 */
+	now = mfctl(16);
 
-	nticks = 0;
-	while((next_tick - now) < halftick) {
-		next_tick += clocktick;
-		nticks++;
+	cycles_elapsed = now - next_tick;
+
+	if ((cycles_elapsed >> 5) < cpt) {
+		/* use "cheap" math (add/subtract) instead
+		 * of the more expensive div/mul method
+		 */
+		cycles_remainder = cycles_elapsed;
+		while (cycles_remainder > cpt) {
+			cycles_remainder -= cpt;
+		}
+	} else {
+		cycles_remainder = cycles_elapsed % cpt;
 	}
-	mtctl(next_tick, 16);
+
+	/* Can we differentiate between "early CR16" (aka Scenario 1) and
+	 * "long delay" (aka Scenario 3)? I don't think so.
+	 *
+	 * We expected timer_interrupt to be delivered at least a few hundred
+	 * cycles after the IT fires. But it's arbitrary how much time passes
+	 * before we call it "late". I've picked one second.
+	 */
+/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
+#if HZ == 1000
+	if (cycles_elapsed > (cpt << 10) )
+#elif HZ == 250
+	if (cycles_elapsed > (cpt << 8) )
+#elif HZ == 100
+	if (cycles_elapsed > (cpt << 7) )
+#else
+#warn WTF is HZ set to anyway?
+	if (cycles_elapsed > (HZ * cpt) )
+#endif
+	{
+		/* Scenario 3: very long delay?  bad in any case */
+		printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
+			" cycles %lX rem %lX "
+			" next/now %lX/%lX\n",
+			cpu,
+			cycles_elapsed, cycles_remainder,
+			next_tick, now );
+	}
+
+	/* convert from "division remainder" to "remainder of clock tick" */
+	cycles_remainder = cpt - cycles_remainder;
+
+	/* Determine when (in CR16 cycles) next IT interrupt will fire.
+	 * We want IT to fire modulo clocktick even if we miss/skip some.
+	 * But those interrupts don't in fact get delivered that regularly.
+	 */
+	next_tick = now + cycles_remainder;
+
 	cpu_data[cpu].it_value = next_tick;
 
-	while (nticks--) {
+	/* Skip one clocktick on purpose if we are likely to miss next_tick.
+	 * We want to avoid the new next_tick being less than CR16.
+	 * If that happened, itimer wouldn't fire until CR16 wrapped.
+	 * We'll catch the tick we missed on the tick after that.
+	 */
+	if (!(cycles_remainder >> 13))
+		next_tick += cpt;
+
+	/* Program the IT when to deliver the next interrupt. */
+        /* Only bottom 32-bits of next_tick are written to cr16.  */
+	mtctl(next_tick, 16);
+
+
+	/* Done mucking with unreliable delivery of interrupts.
+	 * Go do system house keeping.
+	 */
 #ifdef CONFIG_SMP
-		smp_do_timer(regs);
+	smp_do_timer(regs);
 #else
-		update_process_times(user_mode(regs));
+	update_process_times(user_mode(regs));
 #endif
-		if (cpu == 0) {
-			write_seqlock(&xtime_lock);
-			do_timer(1);
-			write_sequnlock(&xtime_lock);
-		}
+	if (cpu == 0) {
+		write_seqlock(&xtime_lock);
+		do_timer(regs);
+		write_sequnlock(&xtime_lock);
 	}
-    
+
 	/* check soft power switch status */
 	if (cpu == 0 && !atomic_read(&power_tasklet.count))
 		tasklet_schedule(&power_tasklet);
@@ -106,14 +165,12 @@
 EXPORT_SYMBOL(profile_pc);
 
 
-/*** converted from ia64 ***/
 /*
  * Return the number of micro-seconds that elapsed since the last
  * update to wall time (aka xtime).  The xtime_lock
  * must be at least read-locked when calling this routine.
  */
-static inline unsigned long
-gettimeoffset (void)
+static inline unsigned long gettimeoffset (void)
 {
 #ifndef CONFIG_SMP
 	/*
@@ -121,21 +178,44 @@
 	 *    Once parisc-linux learns the cr16 difference between processors,
 	 *    this could be made to work.
 	 */
-	long last_tick;
-	long elapsed_cycles;
+	unsigned long now;
+	unsigned long prev_tick;
+	unsigned long next_tick;
+	unsigned long elapsed_cycles;
+	unsigned long usec;
+	unsigned long cpuid = smp_processor_id();
+	unsigned long cpt = clocktick;
 
-	/* it_value is the intended time of the next tick */
-	last_tick = cpu_data[smp_processor_id()].it_value;
+	next_tick = cpu_data[cpuid].it_value;
+	now = mfctl(16);	/* Read the hardware interval timer.  */
 
-	/* Subtract one tick and account for possible difference between
-	 * when we expected the tick and when it actually arrived.
-	 * (aka wall vs real)
-	 */
-	last_tick -= clocktick * (jiffies - wall_jiffies + 1);
-	elapsed_cycles = mfctl(16) - last_tick;
+	prev_tick = next_tick - cpt;
 
-	/* the precision of this math could be improved */
-	return elapsed_cycles / (PAGE0->mem_10msec / 10000);
+	/* Assume Scenario 1: "now" is later than prev_tick.  */
+	elapsed_cycles = now - prev_tick;
+
+/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
+#if HZ == 1000
+	if (elapsed_cycles > (cpt << 10) )
+#elif HZ == 250
+	if (elapsed_cycles > (cpt << 8) )
+#elif HZ == 100
+	if (elapsed_cycles > (cpt << 7) )
+#else
+#warn WTF is HZ set to anyway?
+	if (elapsed_cycles > (HZ * cpt) )
+#endif
+	{
+		/* Scenario 3: clock ticks are missing. */
+		printk (KERN_CRIT "gettimeoffset(CPU %ld): missing %ld ticks!"
+			" cycles %lX prev/now/next %lX/%lX/%lX  clock %lX\n",
+			cpuid, elapsed_cycles / cpt,
+			elapsed_cycles, prev_tick, now, next_tick, cpt);
+	}
+
+	/* FIXME: Can we improve the precision? Not with PAGE0. */
+	usec = (elapsed_cycles * 10000) / PAGE0->mem_10msec;
+	return usec;
 #else
 	return 0;
 #endif
@@ -146,6 +226,7 @@
 {
 	unsigned long flags, seq, usec, sec;
 
+	/* Hold xtime_lock and adjust timeval.  */
 	do {
 		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 		usec = gettimeoffset();
@@ -153,25 +234,13 @@
 		usec += (xtime.tv_nsec / 1000);
 	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
-	if (unlikely(usec > LONG_MAX)) {
-		/* This can happen if the gettimeoffset adjustment is
-		 * negative and xtime.tv_nsec is smaller than the
-		 * adjustment */
-		printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec);
-		usec += USEC_PER_SEC;
-		--sec;
-		/* This should never happen, it means the negative
-		 * time adjustment was more than a second, so there's
-		 * something seriously wrong */
-		BUG_ON(usec > LONG_MAX);
-	}
-
-
+	/* Move adjusted usec's into sec's.  */
 	while (usec >= USEC_PER_SEC) {
 		usec -= USEC_PER_SEC;
 		++sec;
 	}
 
+	/* Return adjusted result.  */
 	tv->tv_sec = sec;
 	tv->tv_usec = usec;
 }
@@ -223,22 +292,23 @@
 }
 
 
+void __init start_cpu_itimer(void)
+{
+	unsigned int cpu = smp_processor_id();
+	unsigned long next_tick = mfctl(16) + clocktick;
+
+	mtctl(next_tick, 16);		/* kick off Interval Timer (CR16) */
+
+	cpu_data[cpu].it_value = next_tick;
+}
+
 void __init time_init(void)
 {
-	unsigned long next_tick;
 	static struct pdc_tod tod_data;
 
 	clocktick = (100 * PAGE0->mem_10msec) / HZ;
-	halftick = clocktick / 2;
 
-	/* Setup clock interrupt timing */
-
-	next_tick = mfctl(16);
-	next_tick += clocktick;
-	cpu_data[smp_processor_id()].it_value = next_tick;
-
-	/* kick off Itimer (CR16) */
-	mtctl(next_tick, 16);
+	start_cpu_itimer();	/* get CPU 0 started */
 
 	if(pdc_tod_read(&tod_data) == 0) {
 		write_seqlock_irq(&xtime_lock);
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 77b28cb..65cd6ca 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -16,6 +16,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/timer.h>
+#include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/smp.h>
@@ -245,6 +246,15 @@
 		current->comm, current->pid, str, err);
 	show_regs(regs);
 
+	if (in_interrupt())
+		panic("Fatal exception in interrupt");
+
+	if (panic_on_oops) {
+		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+		ssleep(5);
+		panic("Fatal exception");
+	}
+
 	/* Wot's wrong wif bein' racy? */
 	if (current->thread.flags & PARISC_KERNEL_DEATH) {
 		printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 25ad28d..0667f2b 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -31,10 +31,7 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-extern char _text;	/* start of kernel code, defined by linker */
 extern int  data_start;
-extern char _end;	/* end of BSS, defined by linker */
-extern char __init_begin, __init_end;
 
 #ifdef CONFIG_DISCONTIGMEM
 struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
@@ -319,8 +316,8 @@
 
 	reserve_bootmem_node(NODE_DATA(0), 0UL,
 			(unsigned long)(PAGE0->mem_free + PDC_CONSOLE_IO_IODC_SIZE));
-	reserve_bootmem_node(NODE_DATA(0),__pa((unsigned long)&_text),
-			(unsigned long)(&_end - &_text));
+	reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text),
+			(unsigned long)(_end - _text));
 	reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
 			((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT));
 
@@ -355,8 +352,8 @@
 #endif
 
 	data_resource.start =  virt_to_phys(&data_start);
-	data_resource.end = virt_to_phys(&_end)-1;
-	code_resource.start = virt_to_phys(&_text);
+	data_resource.end = virt_to_phys(_end) - 1;
+	code_resource.start = virt_to_phys(_text);
 	code_resource.end = virt_to_phys(&data_start)-1;
 
 	/* We don't know which region the kernel will be in, so try
@@ -385,12 +382,12 @@
 	 */
 	local_irq_disable();
 
-	memset(&__init_begin, 0x00, 
-		(unsigned long)&__init_end - (unsigned long)&__init_begin);
+	memset(__init_begin, 0x00,
+		(unsigned long)__init_end - (unsigned long)__init_begin);
 
 	flush_data_cache();
 	asm volatile("sync" : : );
-	flush_icache_range((unsigned long)&__init_begin, (unsigned long)&__init_end);
+	flush_icache_range((unsigned long)__init_begin, (unsigned long)__init_end);
 	asm volatile("sync" : : );
 
 	local_irq_enable();
@@ -398,8 +395,8 @@
 	
 	/* align __init_begin and __init_end to page size,
 	   ignoring linker script where we might have tried to save RAM */
-	init_begin = PAGE_ALIGN((unsigned long)(&__init_begin));
-	init_end   = PAGE_ALIGN((unsigned long)(&__init_end));
+	init_begin = PAGE_ALIGN((unsigned long)(__init_begin));
+	init_end   = PAGE_ALIGN((unsigned long)(__init_end));
 	for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(addr));
 		init_page_count(virt_to_page(addr));
@@ -578,7 +575,7 @@
 	extern const unsigned long fault_vector_20;
 	extern void * const linux_gateway_page;
 
-	ro_start = __pa((unsigned long)&_text);
+	ro_start = __pa((unsigned long)_text);
 	ro_end   = __pa((unsigned long)&data_start);
 	fv_addr  = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
 	gw_addr  = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 2738456..47a1d2a 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -188,7 +188,7 @@
 }
 EXPORT_SYMBOL(__ioremap);
 
-void iounmap(void __iomem *addr)
+void iounmap(const volatile void __iomem *addr)
 {
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a0dd1b0..8b69104 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -338,10 +338,6 @@
 	  RS/6000 machine, an Apple machine, or a PReP, CHRP,
 	  Maple or Cell-based machine.
 
-config PPC_ISERIES
-	bool "IBM Legacy iSeries"
-	depends on PPC64
-
 config EMBEDDED6xx
 	bool "Embedded 6xx/7xx/7xxx-based board"
 	depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
@@ -355,6 +351,16 @@
 	  <http://linux-apus.sourceforge.net/>.
 endchoice
 
+config QUICC_ENGINE
+	bool
+	depends on PPC_MPC836x || PPC_MPC832x
+	default y
+	help
+	  The QUICC Engine (QE) is a new generation of communications
+	  coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
+	  Selecting this option means that you wish to build a kernel
+	  for a machine with a QE coprocessor.
+
 config PPC_PSERIES
 	depends on PPC_MULTIPLATFORM && PPC64
 	bool "IBM pSeries & new (POWER5-based) iSeries"
@@ -365,6 +371,10 @@
 	select PPC_UDBG_16550
 	default y
 
+config PPC_ISERIES
+	bool "IBM Legacy iSeries"
+	depends on PPC_MULTIPLATFORM && PPC64
+
 config PPC_CHRP
 	bool "Common Hardware Reference Platform (CHRP) based machines"
 	depends on PPC_MULTIPLATFORM && PPC32
@@ -594,6 +604,7 @@
 
 source arch/powerpc/platforms/embedded6xx/Kconfig
 source arch/powerpc/platforms/4xx/Kconfig
+source arch/powerpc/platforms/82xx/Kconfig
 source arch/powerpc/platforms/83xx/Kconfig
 source arch/powerpc/platforms/85xx/Kconfig
 source arch/powerpc/platforms/86xx/Kconfig
@@ -1002,7 +1013,7 @@
 	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
 	help
 	  This option allows you to set the base virtual address
-	  of the the consistent memory pool.  This pool of virtual
+	  of the consistent memory pool.  This pool of virtual
 	  memory is used to make consistent memory allocations.
 
 config CONSISTENT_START
@@ -1013,7 +1024,7 @@
 	bool "Set custom consistent memory pool size"
 	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
 	help
-	  This option allows you to set the size of the the
+	  This option allows you to set the size of the
 	  consistent memory pool.  This pool of virtual memory
 	  is used to make consistent memory allocations.
 
@@ -1058,6 +1069,8 @@
 
 # XXX source "arch/ppc/8260_io/Kconfig"
 
+source "arch/powerpc/sysdev/qe_lib/Kconfig"
+
 source "arch/powerpc/platforms/iseries/Kconfig"
 
 source "lib/Kconfig"
@@ -1069,7 +1082,7 @@
 
 config KPROBES
 	bool "Kprobes (EXPERIMENTAL)"
-	depends on PPC64 && EXPERIMENTAL && MODULES
+	depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES
 	help
 	  Kprobes allows you to trap at almost any kernel address and
 	  execute a callback function.  register_kprobe() establishes
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 01667d1..a00fe72 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -20,6 +20,7 @@
 CROSS32CC		:= $(CROSS32_COMPILE)gcc
 CROSS32AS		:= $(CROSS32_COMPILE)as
 CROSS32LD		:= $(CROSS32_COMPILE)ld
+CROSS32AR		:= $(CROSS32_COMPILE)ar
 CROSS32OBJCOPY		:= $(CROSS32_COMPILE)objcopy
 
 ifeq ($(HAS_BIARCH),y)
@@ -28,10 +29,11 @@
 CROSS32AS	:= $(AS) -a32
 CROSS32LD	:= $(LD) -m elf32ppc
 CROSS32OBJCOPY	:= $(OBJCOPY)
+CROSS32AR	:= $(AR)
 endif
 endif
 
-export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
+export CROSS32CC CROSS32AS CROSS32LD CROSS32AR CROSS32OBJCOPY
 
 KBUILD_DEFCONFIG := $(shell uname -m)_defconfig
 
@@ -146,7 +148,7 @@
 
 CPPFLAGS_vmlinux.lds	:= -Upowerpc
 
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin
+BOOT_TARGETS = zImage zImage.initrd uImage
 
 PHONY += $(BOOT_TARGETS)
 
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index e737741..003520b 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -20,27 +20,12 @@
 #	CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
 #	in the toplevel makefile.
 
+all: $(obj)/zImage
 
 HOSTCC		:= gcc
 BOOTCFLAGS	:= $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \
 		   $(shell $(CROSS32CC) -print-file-name=include) -fPIC
 BOOTAFLAGS	:= -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
-OBJCOPYFLAGS    := contents,alloc,load,readonly,data
-OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
-OBJCOPY_MIB_ARGS  := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
-
-zlib       := inffast.c inflate.c inftrees.c
-zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
-zliblinuxheader := zlib.h zconf.h zutil.h
-
-$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
-#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
-
-src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
-src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
-src-boot += $(zlib)
-src-boot := $(addprefix $(obj)/, $(src-boot))
-obj-boot := $(addsuffix .o, $(basename $(src-boot)))
 
 ifeq ($(call cc-option-yn, -fstack-protector),y)
 BOOTCFLAGS	+= -fno-stack-protector
@@ -48,6 +33,22 @@
 
 BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj)
 
+zlib       := inffast.c inflate.c inftrees.c
+zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
+zliblinuxheader := zlib.h zconf.h zutil.h
+
+$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \
+		$(addprefix $(obj)/,$(zlibheader))
+
+src-wlib := string.S stdio.c main.c div64.S $(zlib)
+src-plat := of.c
+src-boot := crt0.S $(src-wlib) $(src-plat) empty.c
+
+src-boot := $(addprefix $(obj)/, $(src-boot))
+obj-boot := $(addsuffix .o, $(basename $(src-boot)))
+obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
+obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
+
 quiet_cmd_copy_zlib = COPY    $@
       cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
 
@@ -66,8 +67,14 @@
 $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
 	$(call cmd,copy_zliblinuxheader)
 
-clean-files := $(zlib) $(zlibheader) $(zliblinuxheader)
+$(obj)/empty.c:
+	@touch $@
 
+$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
+	@cp $< $@
+
+clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
+		$(obj)/empty.c
 
 quiet_cmd_bootcc = BOOTCC  $@
       cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -75,146 +82,97 @@
 quiet_cmd_bootas = BOOTAS  $@
       cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
 
-quiet_cmd_bootld = BOOTLD  $@
-      cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2)
+quiet_cmd_bootar = BOOTAR  $@
+      cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $^; mv $@.$$$$ $@
 
 $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
 	$(call if_changed_dep,bootcc)
 $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
 	$(call if_changed_dep,bootas)
 
-#-----------------------------------------------------------
-# ELF sections within the zImage bootloader/wrapper
-#-----------------------------------------------------------
-required := vmlinux.strip
-initrd   := initrd
+$(obj)/wrapper.a: $(obj-wlib)
+	$(call cmd,bootar)
 
-obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section)))
-src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
-gz-sec  = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
+hostprogs-y	:= addnote addRamDisk hack-coff
 
-hostprogs-y		:= addnote addRamDisk hack-coff
+extra-y		:= $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
+		   $(obj)/zImage.lds $(obj)/zImage.coff.lds
 
-targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
-	   zImage.coff zImage.initrd.coff miboot.image miboot.initrd.image \
-	   $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
-	   $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
-	   $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
-	   vmlinux.initrd dummy.o
-extra-y			:= initrd.o
+wrapper		:=$(srctree)/$(src)/wrapper
+wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff)
 
-quiet_cmd_ramdisk = RAMDISK $@
-      cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
+#############
+# Bits for building various flavours of zImage
 
-quiet_cmd_stripvm = STRIP   $@
-      cmd_stripvm = $(STRIP) -s -R .comment $< -o $@
+ifneq ($(CROSS32_COMPILE),)
+CROSSWRAP := -C $(CROSS32_COMPILE)
+else
+ifneq ($(CROSS_COMPILE),)
+CROSSWRAP := -C $(CROSS_COMPILE)
+endif
+endif
 
-vmlinux.strip: vmlinux
-	$(call if_changed,stripvm)
-$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz
-	$(call if_changed,ramdisk)
+quiet_cmd_wrap	= WRAP    $@
+      cmd_wrap	=$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux
+quiet_cmd_wrap_initrd = WRAP    $@
+      cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
+				-i $(obj)/ramdisk.image.gz vmlinux
 
-quiet_cmd_addsection = ADDSEC  $@
-      cmd_addsection = $(CROSS32OBJCOPY) $@ \
-		--add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
-		--set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
+$(obj)/zImage.chrp: vmlinux $(wrapperbits)
+	$(call cmd,wrap,chrp)
 
-quiet_cmd_addnote = ADDNOTE $@
-      cmd_addnote = $(obj)/addnote $@
+$(obj)/zImage.initrd.chrp: vmlinux $(wrapperbits)
+	$(call cmd,wrap_initrd,chrp)
 
-quiet_cmd_gen-miboot = GEN     $@
-      cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_MIB_ARGS) \
-		       --add-section=$1=$(word 2, $^) $< $@
+$(obj)/zImage.pseries:	vmlinux $(wrapperbits)
+	$(call cmd,wrap,pseries)
 
-quiet_cmd_gencoff = COFF    $@
-      cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \
-		    $(obj)/hack-coff $@
+$(obj)/zImage.initrd.pseries: vmlinux $(wrapperbits)
+	$(call cmd,wrap_initrd,pseries)
 
-$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
-	$(call if_changed,gzip)
+$(obj)/zImage.pmac: vmlinux $(wrapperbits)
+	$(call cmd,wrap,pmac)
 
-$(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
-	cp -f $(obj)/ramdisk.image.gz $@
+$(obj)/zImage.initrd.pmac: vmlinux $(wrapperbits)
+	$(call cmd,wrap_initrd,pmac)
 
-$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz
-	@touch $@
+$(obj)/zImage.coff: vmlinux $(wrapperbits)
+	$(call cmd,wrap,pmaccoff)
 
-$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
-	$(call if_changed_dep,bootcc)
-	$(call cmd,addsection)
+$(obj)/zImage.initrd.coff: vmlinux $(wrapperbits)
+	$(call cmd,wrap_initrd,pmaccoff)
 
-$(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required))
-$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
-	$(call cmd,bootld,$(obj-boot),zImage.lds)
+$(obj)/zImage.miboot: vmlinux $(wrapperbits)
+	$(call cmd,wrap,miboot)
 
-$(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd))
-$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
-	$(call cmd,bootld,$(obj-boot),zImage.lds)
+$(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
+	$(call cmd,wrap_initrd,miboot)
+
+$(obj)/uImage: vmlinux $(wrapperbits)
+	$(call cmd,wrap,uboot)
+
+image-$(CONFIG_PPC_PSERIES)	+= zImage.pseries
+image-$(CONFIG_PPC_MAPLE)	+= zImage.pseries
+image-$(CONFIG_PPC_CELL)	+= zImage.pseries
+image-$(CONFIG_PPC_CHRP)	+= zImage.chrp
+image-$(CONFIG_PPC_PMAC)	+= zImage.pmac
+image-$(CONFIG_DEFAULT_UIMAGE)	+= uImage
 
 # For 32-bit powermacs, build the COFF and miboot images
 # as well as the ELF images.
-coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff
-coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff
-mibootimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.image
-mibrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32)  := $(obj)/miboot.initrd.image
+ifeq ($(CONFIG_PPC32),y)
+image-$(CONFIG_PPC_PMAC)	+= zImage.coff zImage.miboot
+endif
 
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y) \
-			$(mibootimg-y-y)
-	@cp -f $< $@
-	$(call if_changed,addnote)
+initrd-y := $(patsubst zImage%, zImage.initrd%, $(image-y))
 
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote \
-			$(coffrdimg-y-y) $(mibrdimg-y-y)
-	@cp -f $< $@
-	$(call if_changed,addnote)
+$(obj)/zImage:		$(addprefix $(obj)/, $(image-y))
+	@rm -f $@; ln $< $@
+$(obj)/zImage.initrd:	$(addprefix $(obj)/, $(initrd-y))
+	@rm -f $@; ln $< $@
 
-$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) \
-			$(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
-	$(call cmd,bootld,$(obj-boot),zImage.coff.lds)
-	$(call cmd,gencoff)
+install: $(CONFIGURE) $(image-y)
+	sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
 
-$(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \
-			   $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
-	$(call cmd,bootld,$(obj-boot),zImage.coff.lds)
-	$(call cmd,gencoff)
-
-$(obj)/miboot.image: $(obj)/dummy.o $(obj)/vmlinux.gz
-	$(call cmd,gen-miboot,image)
-
-$(obj)/miboot.initrd.image: $(obj)/miboot.image $(images)/ramdisk.image.gz
-	$(call cmd,gen-miboot,initrd)
-
-#-----------------------------------------------------------
-# build u-boot images
-#-----------------------------------------------------------
-quiet_cmd_mygzip = GZIP $@
-cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@
-
-quiet_cmd_objbin = OBJCOPY $@
-      cmd_objbin = $(OBJCOPY) -O binary $< $@
-
-quiet_cmd_uimage = UIMAGE $@
-      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
-               -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \
-               -d $< $@
-
-MKIMAGE		:= $(srctree)/scripts/mkuboot.sh
-targets		+= uImage
-extra-y		+= vmlinux.bin vmlinux.gz
-
-$(obj)/vmlinux.bin: vmlinux FORCE
-	$(call if_changed,objbin)
-
-$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
-	$(call if_changed,mygzip)
-
-$(obj)/uImage: $(obj)/vmlinux.gz
-	$(Q)rm -f $@
-	$(call cmd,uimage)
-	@echo -n '  Image: $@ '
-	@if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
-
-install: $(CONFIGURE) $(BOOTIMAGE)
-	sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
-
-clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip)
+clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz)
+clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz)
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
new file mode 100644
index 0000000..34efdd0
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -0,0 +1,223 @@
+/*
+ * MPC8272 ADS Device Tree Source
+ *
+ * Copyright 2005 Freescale Semiconductor 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.
+ */
+
+/ {
+       model = "MPC8272ADS";
+       compatible = "MPC8260ADS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8272@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <4000>;          // L1, 16K
+                       i-cache-size = <4000>;          // L1, 16K
+                       timebase-frequency = <0>;
+                       bus-frequency = <0>;
+                       clock-frequency = <0>;
+                       32-bit;
+                       linux,phandle = <201>;
+                       linux,boot-cpu;
+               };
+       };
+
+       interrupt-controller@f8200000 {
+               linux,phandle = <f8200000>;
+               #address-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               reg = <f8200000 f8200004>;
+               built-in;
+               device_type = "pci-pic";
+       };
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 4000000 f4500000 00000020>;
+       };
+
+       soc8272@f0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = < 0 0 2 00000000 f0000000 00053000>;
+               reg = <f0000000 0>;
+
+               mdio@0 {
+                       device_type = "mdio";
+                       compatible = "fs_enet";
+                       reg = <0 0>;
+                       linux,phandle = <24520>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ethernet-phy@0 {
+                               linux,phandle = <2452000>;
+                               interrupt-parent = <10c00>;
+                               interrupts = <19 1>;
+                               reg = <0>;
+                               bitbang = [ 12 12 13 02 02 01 ];
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@1 {
+                               linux,phandle = <2452001>;
+                               interrupt-parent = <10c00>;
+                               interrupts = <19 1>;
+                               bitbang = [ 12 12 13 02 02 01 ];
+                               reg = <3>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       device-id = <2>;
+                       compatible = "fs_enet";
+                       model = "FCC";
+                       reg = <11300 20 8400 100 11380 30>;
+                       mac-address = [ 00 11 2F 99 43 54 ];
+                       interrupts = <20 2>;
+                       interrupt-parent = <10c00>;
+                       phy-handle = <2452000>;
+                       rx-clock = <13>;
+                       tx-clock = <12>;
+               };
+
+               ethernet@25000 {
+                       device_type = "network";
+                       device-id = <3>;
+                       compatible = "fs_enet";
+                       model = "FCC";
+                       reg = <11320 20 8500 100 113b0 30>;
+                       mac-address = [ 00 11 2F 99 44 54 ];
+                       interrupts = <21 2>;
+                       interrupt-parent = <10c00>;
+                       phy-handle = <2452001>;
+                       rx-clock = <17>;
+                       tx-clock = <18>;
+               };
+
+               cpm@f0000000 {
+                       linux,phandle = <f0000000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       #interrupt-cells = <2>;
+                       device_type = "cpm";
+                       model = "CPM2";
+                       ranges = <00000000 00000000 3ffff>;
+                       reg = <10d80 3280>;
+                       command-proc = <119c0>;
+                       brg-frequency = <17D7840>;
+                       cpm_clk = <BEBC200>;
+
+                       scc@11a00 {
+                               device_type = "serial";
+                               compatible = "cpm_uart";
+                               model = "SCC";
+                               device-id = <2>;
+                               reg = <11a00 20 8000 100>;
+                               current-speed = <1c200>;
+                               interrupts = <28 2>;
+                               interrupt-parent = <10c00>;
+                               clock-setup = <0 00ffffff>;
+                               rx-clock = <1>;
+                               tx-clock = <1>;
+                       };
+
+                       scc@11a60 {
+                               device_type = "serial";
+                               compatible = "cpm_uart";
+                               model = "SCC";
+                               device-id = <5>;
+                               reg = <11a60 20 8300 100>;
+                               current-speed = <1c200>;
+                               interrupts = <2b 2>;
+                               interrupt-parent = <10c00>;
+                               clock-setup = <1b ffffff00>;
+                               rx-clock = <4>;
+                               tx-clock = <4>;
+                       };
+
+               };
+               interrupt-controller@10c00 {
+                       linux,phandle = <10c00>;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <10c00 80>;
+                       built-in;
+                       device_type = "cpm-pic";
+		       compatible = "CPM2";
+               };
+               pci@0500 {
+                       linux,phandle = <0500>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "8272";
+                       device_type = "pci";
+                       reg = <10430 4dc>;
+                       clock-frequency = <3f940aa>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                                       /* IDSEL 0x16 */
+                                        b000 0 0 1 f8200000 40 0
+                                        b000 0 0 2 f8200000 41 0
+                                        b000 0 0 3 f8200000 42 0
+                                        b000 0 0 4 f8200000 43 0
+
+                                       /* IDSEL 0x17 */
+                                        b800 0 0 1 f8200000 43 0
+                                        b800 0 0 2 f8200000 40 0
+                                        b800 0 0 3 f8200000 41 0
+                                        b800 0 0 4 f8200000 42 0
+
+                                       /* IDSEL 0x18 */
+                                        c000 0 0 1 f8200000 42 0
+                                        c000 0 0 2 f8200000 43 0
+                                        c000 0 0 3 f8200000 40 0
+                                        c000 0 0 4 f8200000 41 0>;
+                       interrupt-parent = <10c00>;
+                       interrupts = <14 3>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 80000000 80000000 0 40000000
+                                 01000000 0 00000000 f6000000 0 02000000>;
+               };
+
+/* May need to remove if on a part without crypto engine */
+               crypto@30000 {
+                       device_type = "crypto";
+                       model = "SEC2";
+                       compatible = "talitos";
+                       reg = <30000 10000>;
+                       interrupts = <b 0>;
+                       interrupt-parent = <10c00>;
+                       num-channels = <4>;
+                       channel-fifo-len = <18>;
+                       exec-units-mask = <0000007e>;
+/* desc mask is for rev1.x, we need runtime fixup for >=2.x */
+                       descriptor-types-mask = <01010ebf>;
+               };
+
+       };
+};
diff --git a/arch/powerpc/boot/dts/mpc8360emds.dts b/arch/powerpc/boot/dts/mpc8360emds.dts
new file mode 100644
index 0000000..9022192
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8360emds.dts
@@ -0,0 +1,375 @@
+/*
+ * MPC8360E EMDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor 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.
+ */
+
+
+/*
+/memreserve/	00000000 1000000;
+*/
+
+/ {
+	model = "MPC8360EPB";
+	compatible = "MPC83xx";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	linux,phandle = <100>;
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		linux,phandle = <200>;
+
+		PowerPC,8360@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <3EF1480>;
+			bus-frequency = <FBC5200>;
+			clock-frequency = <1F78A400>;
+			32-bit;
+			linux,phandle = <201>;
+			linux,boot-cpu;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		linux,phandle = <300>;
+		reg = <00000000 10000000>;
+	};
+
+	bcsr@f8000000 {
+		device_type = "board-control";
+		reg = <f8000000 8000>;
+	};
+
+	soc8360@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00000200>;
+		bus-frequency = <FBC5200>;
+
+		wdt@200 {
+			device_type = "watchdog";
+			compatible = "mpc83xx_wdt";
+			reg = <200 100>;
+		};
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <e 8>;
+			interrupt-parent = <700>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3100 100>;
+			interrupts = <f 8>;
+			interrupt-parent = <700>;
+			dfsrr;
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>;
+			clock-frequency = <FBC5200>;
+			interrupts = <9 8>;
+			interrupt-parent = <700>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;
+			clock-frequency = <FBC5200>;
+			interrupts = <a 8>;
+			interrupt-parent = <700>;
+		};
+
+		crypto@30000 {
+			device_type = "crypto";
+			model = "SEC2";
+			compatible = "talitos";
+			reg = <30000 10000>;
+			interrupts = <b 8>;
+			interrupt-parent = <700>;
+			num-channels = <4>;
+			channel-fifo-len = <18>;
+			exec-units-mask = <0000007e>;
+			/* desc mask is for rev1.x, we need runtime fixup for >=2.x */
+			descriptor-types-mask = <01010ebf>;
+		};
+
+		pci@8500 {
+			linux,phandle = <8500>;
+			interrupt-map-mask = <f800 0 0 7>;
+			interrupt-map = <
+
+					/* IDSEL 0x11 AD17 */
+					 8800 0 0 1 700 14 8
+					 8800 0 0 2 700 15 8
+					 8800 0 0 3 700 16 8
+					 8800 0 0 4 700 17 8
+
+					/* IDSEL 0x12 AD18 */
+					 9000 0 0 1 700 16 8
+					 9000 0 0 2 700 17 8
+					 9000 0 0 3 700 14 8
+					 9000 0 0 4 700 15 8
+
+					/* IDSEL 0x13 AD19 */
+					 9800 0 0 1 700 17 8
+					 9800 0 0 2 700 14 8
+					 9800 0 0 3 700 15 8
+					 9800 0 0 4 700 16 8
+
+					/* IDSEL 0x15 AD21*/
+					 a800 0 0 1 700 14 8
+					 a800 0 0 2 700 15 8
+					 a800 0 0 3 700 16 8
+					 a800 0 0 4 700 17 8
+
+					/* IDSEL 0x16 AD22*/
+					 b000 0 0 1 700 17 8
+					 b000 0 0 2 700 14 8
+					 b000 0 0 3 700 15 8
+					 b000 0 0 4 700 16 8
+
+					/* IDSEL 0x17 AD23*/
+					 b800 0 0 1 700 16 8
+					 b800 0 0 2 700 17 8
+					 b800 0 0 3 700 14 8
+					 b800 0 0 4 700 15 8
+
+					/* IDSEL 0x18 AD24*/
+					 c000 0 0 1 700 15 8
+					 c000 0 0 2 700 16 8
+					 c000 0 0 3 700 17 8
+					 c000 0 0 4 700 14 8>;
+			interrupt-parent = <700>;
+			interrupts = <42 8>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 a0000000 a0000000 0 10000000
+				  42000000 0 80000000 80000000 0 10000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8500 100>;
+			compatible = "83xx";
+			device_type = "pci";
+		};
+
+		pic@700 {
+			linux,phandle = <700>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <700 100>;
+			built-in;
+			device_type = "ipic";
+		};
+
+		par_io@1400 {
+			reg = <1400 100>;
+			device_type = "par_io";
+			num-ports = <7>;
+
+			ucc_pin@01 {
+				linux,phandle = <140001>;
+				pio-map = <
+			/* port  pin  dir  open_drain  assignment  has_irq */
+					0  3  1  0  1  0 	/* TxD0 */
+					0  4  1  0  1  0 	/* TxD1 */
+					0  5  1  0  1  0 	/* TxD2 */
+					0  6  1  0  1  0 	/* TxD3 */
+					1  6  1  0  3  0 	/* TxD4 */
+					1  7  1  0  1  0 	/* TxD5 */
+					1  9  1  0  2  0 	/* TxD6 */
+					1  a  1  0  2  0 	/* TxD7 */
+					0  9  2  0  1  0 	/* RxD0 */
+					0  a  2  0  1  0 	/* RxD1 */
+					0  b  2  0  1  0 	/* RxD2 */
+					0  c  2  0  1  0 	/* RxD3 */
+					0  d  2  0  1  0 	/* RxD4 */
+					1  1  2  0  2  0 	/* RxD5 */
+					1  0  2  0  2  0 	/* RxD6 */
+					1  4  2  0  2  0 	/* RxD7 */
+					0  7  1  0  1  0 	/* TX_EN */
+					0  8  1  0  1  0 	/* TX_ER */
+					0  f  2  0  1  0 	/* RX_DV */
+					0  10 2  0  1  0 	/* RX_ER */
+					0  0  2  0  1  0 	/* RX_CLK */
+					2  9  1  0  3  0 	/* GTX_CLK - CLK10 */
+					2  8  2  0  1  0>;	/* GTX125 - CLK9 */
+			};
+			ucc_pin@02 {
+				linux,phandle = <140002>;
+				pio-map = <
+			/* port  pin  dir  open_drain  assignment  has_irq */
+					0  11 1  0  1  0   /* TxD0 */
+					0  12 1  0  1  0   /* TxD1 */
+					0  13 1  0  1  0   /* TxD2 */
+					0  14 1  0  1  0   /* TxD3 */
+					1  2  1  0  1  0   /* TxD4 */
+					1  3  1  0  2  0   /* TxD5 */
+					1  5  1  0  3  0   /* TxD6 */
+					1  8  1  0  3  0   /* TxD7 */
+					0  17 2  0  1  0   /* RxD0 */
+					0  18 2  0  1  0   /* RxD1 */
+					0  19 2  0  1  0   /* RxD2 */
+					0  1a 2  0  1  0   /* RxD3 */
+					0  1b 2  0  1  0   /* RxD4 */
+					1  c  2  0  2  0   /* RxD5 */
+					1  d  2  0  3  0   /* RxD6 */
+					1  b  2  0  2  0   /* RxD7 */
+					0  15 1  0  1  0   /* TX_EN */
+					0  16 1  0  1  0   /* TX_ER */
+					0  1d 2  0  1  0   /* RX_DV */
+					0  1e 2  0  1  0   /* RX_ER */
+					0  1f 2  0  1  0   /* RX_CLK */
+					2  2  1  0  2  0   /* GTX_CLK - CLK10 */
+					2  3  2  0  1  0   /* GTX125 - CLK4 */
+					0  1  3  0  2  0   /* MDIO */
+					0  2  1  0  1  0>; /* MDC */
+			};
+
+		};
+	};
+
+	qe@e0100000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "qe";
+		model = "QE";
+		ranges = <0 e0100000 00100000>;
+		reg = <e0100000 480>;
+		brg-frequency = <0>;
+		bus-frequency = <179A7B00>;
+
+		muram@10000 {
+			device_type = "muram";
+			ranges = <0 00010000 0000c000>;
+
+			data-only@0{
+				reg = <0 c000>;
+			};
+		};
+
+		spi@4c0 {
+			device_type = "spi";
+			compatible = "fsl_spi";
+			reg = <4c0 40>;
+			interrupts = <2>;
+			interrupt-parent = <80>;
+			mode = "cpu";
+		};
+
+		spi@500 {
+			device_type = "spi";
+			compatible = "fsl_spi";
+			reg = <500 40>;
+			interrupts = <1>;
+			interrupt-parent = <80>;
+			mode = "cpu";
+		};
+
+		usb@6c0 {
+			device_type = "usb";
+			compatible = "qe_udc";
+			reg = <6c0 40 8B00 100>;
+			interrupts = <b>;
+			interrupt-parent = <80>;
+			mode = "slave";
+		};
+
+		ucc@2000 {
+			device_type = "network";
+			compatible = "ucc_geth";
+			model = "UCC";
+			device-id = <1>;
+			reg = <2000 200>;
+			interrupts = <20>;
+			interrupt-parent = <80>;
+			mac-address = [ 00 04 9f 00 23 23 ];
+			rx-clock = <0>;
+			tx-clock = <19>;
+			phy-handle = <212000>;
+			pio-handle = <140001>;
+		};
+
+		ucc@3000 {
+			device_type = "network";
+			compatible = "ucc_geth";
+			model = "UCC";
+			device-id = <2>;
+			reg = <3000 200>;
+			interrupts = <21>;
+			interrupt-parent = <80>;
+			mac-address = [ 00 11 22 33 44 55 ];
+			rx-clock = <0>;
+			tx-clock = <14>;
+			phy-handle = <212001>;
+			pio-handle = <140002>;
+		};
+
+		mdio@2120 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2120 18>;
+			device_type = "mdio";
+			compatible = "ucc_geth_phy";
+
+			ethernet-phy@00 {
+				linux,phandle = <212000>;
+				interrupt-parent = <700>;
+				interrupts = <11 2>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+				interface = <6>; //ENET_1000_GMII
+			};
+			ethernet-phy@01 {
+				linux,phandle = <212001>;
+				interrupt-parent = <700>;
+				interrupts = <12 2>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+				interface = <6>;
+			};
+		};
+
+		qeic@80 {
+			linux,phandle = <80>;
+			interrupt-controller;
+			device_type = "qeic";
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			reg = <80 80>;
+			built-in;
+			big-endian;
+			interrupts = <20 8 21 8>; //high:32 low:33
+			interrupt-parent = <700>;
+		};
+
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
new file mode 100644
index 0000000..2b16848
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -0,0 +1,302 @@
+/*
+ * MPC8560 ADS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor 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.
+ */
+
+
+/ {
+	model = "MPC8560ADS";
+	compatible = "MPC85xxADS";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	linux,phandle = <100>;
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		linux,phandle = <200>;
+
+		PowerPC,8560@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <04ead9a0>;
+			bus-frequency = <13ab6680>;
+			clock-frequency = <312c8040>;
+			32-bit;
+			linux,phandle = <201>;
+			linux,boot-cpu;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		linux,phandle = <300>;
+		reg = <00000000 10000000>;
+	};
+
+	soc8560@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00000200>;
+		bus-frequency = <13ab6680>;
+
+		mdio@24520 {
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			linux,phandle = <24520>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <40000>;
+				interrupts = <35 1>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <40000>;
+				interrupts = <35 1>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@2 {
+				linux,phandle = <2452002>;
+				interrupt-parent = <40000>;
+				interrupts = <37 1>;
+				reg = <2>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@3 {
+				linux,phandle = <2452003>;
+				interrupt-parent = <40000>;
+				interrupts = <37 1>;
+				reg = <3>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <24000 1000>;
+			address = [ 00 00 0C 00 00 FD ];
+			interrupts = <d 2 e 2 12 2>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452000>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <25000 1000>;
+			address = [ 00 00 0C 00 01 FD ];
+			interrupts = <13 2 14 2 18 2>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452001>;
+		};
+
+		pci@8000 {
+			linux,phandle = <8000>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			compatible = "85xx";
+			device_type = "pci";
+			reg = <8000 400>;
+			clock-frequency = <3f940aa>;
+			interrupt-map-mask = <f800 0 0 7>;
+			interrupt-map = <
+
+					/* IDSEL 0x2 */
+					 1000 0 0 1 40000 31 1
+					 1000 0 0 2 40000 32 1
+					 1000 0 0 3 40000 33 1
+					 1000 0 0 4 40000 34 1
+
+					/* IDSEL 0x3 */
+					 1800 0 0 1 40000 34 1
+					 1800 0 0 2 40000 31 1
+					 1800 0 0 3 40000 32 1
+					 1800 0 0 4 40000 33 1
+
+					/* IDSEL 0x4 */
+					 2000 0 0 1 40000 33 1
+					 2000 0 0 2 40000 34 1
+					 2000 0 0 3 40000 31 1
+					 2000 0 0 4 40000 32 1
+
+					/* IDSEL 0x5  */
+					 2800 0 0 1 40000 32 1
+					 2800 0 0 2 40000 33 1
+					 2800 0 0 3 40000 34 1
+					 2800 0 0 4 40000 31 1
+
+					/* IDSEL 12 */
+					 6000 0 0 1 40000 31 1
+					 6000 0 0 2 40000 32 1
+					 6000 0 0 3 40000 33 1
+					 6000 0 0 4 40000 34 1
+
+					/* IDSEL 13 */
+					 6800 0 0 1 40000 34 1
+					 6800 0 0 2 40000 31 1
+					 6800 0 0 3 40000 32 1
+					 6800 0 0 4 40000 33 1
+
+					/* IDSEL 14*/
+					 7000 0 0 1 40000 33 1
+					 7000 0 0 2 40000 34 1
+					 7000 0 0 3 40000 31 1
+					 7000 0 0 4 40000 32 1
+
+					/* IDSEL 15 */
+					 7800 0 0 1 40000 32 1
+					 7800 0 0 2 40000 33 1
+					 7800 0 0 3 40000 34 1
+					 7800 0 0 4 40000 31 1
+
+					/* IDSEL 18 */
+					 9000 0 0 1 40000 31 1
+					 9000 0 0 2 40000 32 1
+					 9000 0 0 3 40000 33 1
+					 9000 0 0 4 40000 34 1
+
+					/* IDSEL 19 */
+					 9800 0 0 1 40000 34 1
+					 9800 0 0 2 40000 31 1
+					 9800 0 0 3 40000 32 1
+					 9800 0 0 4 40000 33 1
+
+					/* IDSEL 20 */
+					 a000 0 0 1 40000 33 1
+					 a000 0 0 2 40000 34 1
+					 a000 0 0 3 40000 31 1
+					 a000 0 0 4 40000 32 1
+
+					/* IDSEL 21 */
+					 a800 0 0 1 40000 32 1
+					 a800 0 0 2 40000 33 1
+					 a800 0 0 3 40000 34 1
+					 a800 0 0 4 40000 31 1>;
+
+			interrupt-parent = <40000>;
+			interrupts = <42 0>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 80000000 80000000 0 20000000
+				  01000000 0 00000000 e2000000 0 01000000>;
+		};
+
+		pic@40000 {
+			linux,phandle = <40000>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <40000 20100>;
+			built-in;
+			device_type = "open-pic";
+		};
+
+		cpm@e0000000 {
+			linux,phandle = <e0000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			#interrupt-cells = <2>;
+			device_type = "cpm";
+			model = "CPM2";
+			ranges = <0 0 c0000>;
+			reg = <80000 40000>;
+			command-proc = <919c0>;
+			brg-frequency = <9d5b340>;
+
+			pic@90c00 {
+				linux,phandle = <90c00>;
+				interrupt-controller;
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				interrupts = <1e 0>;
+				interrupt-parent = <40000>;
+				reg = <90c00 80>;
+				built-in;
+				device_type = "cpm-pic";
+			};
+
+			scc@91a00 {
+				device_type = "serial";
+				compatible = "cpm_uart";
+				model = "SCC";
+				device-id = <1>;
+				reg = <91a00 20 88000 100>;
+				clock-setup = <00ffffff 0>;
+				rx-clock = <1>;
+				tx-clock = <1>;
+				current-speed = <1c200>;
+				interrupts = <64 1>;
+				interrupt-parent = <90c00>;
+			};
+
+			scc@91a20 {
+				device_type = "serial";
+				compatible = "cpm_uart";
+				model = "SCC";
+				device-id = <2>;
+				reg = <91a20 20 88100 100>;
+				clock-setup = <ff00ffff 90000>;
+				rx-clock = <2>;
+				tx-clock = <2>;
+				current-speed = <1c200>;
+				interrupts = <65 1>;
+				interrupt-parent = <90c00>;
+			};
+
+			fcc@91320 {
+				device_type = "network";
+				compatible = "fs_enet";
+				model = "FCC";
+				device-id = <2>;
+				reg = <91320 20 88500 100 913a0 30>;
+				mac-address = [ 00 00 0C 00 02 FD ];
+				clock-setup = <ff00ffff 250000>;
+				rx-clock = <15>;
+				tx-clock = <16>;
+				interrupts = <5d 1>;
+				interrupt-parent = <90c00>;
+				phy-handle = <2452002>;
+			};
+
+			fcc@91340 {
+				device_type = "network";
+				compatible = "fs_enet";
+				model = "FCC";
+				device-id = <3>;
+				reg = <91340 20 88600 100 913d0 30>;
+				mac-address = [ 00 00 0C 00 03 FD ];
+				clock-setup = <ffff00ff 3700>;
+				rx-clock = <17>;
+				tx-clock = <18>;
+				interrupts = <5e 1>;
+				interrupt-parent = <90c00>;
+				phy-handle = <2452003>;
+			};
+		};
+	};
+};
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
new file mode 100755
index 0000000..eab7318
--- /dev/null
+++ b/arch/powerpc/boot/wrapper
@@ -0,0 +1,204 @@
+#!/bin/sh
+
+# Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus@samba.org>
+# This program may be used under the terms of version 2 of the GNU
+# General Public License.
+
+# This script takes a kernel binary and optionally an initrd image
+# and/or a device-tree blob, and creates a bootable zImage for a
+# given platform.
+
+# Options:
+# -o zImage	specify output file
+# -p platform	specify platform (links in $platform.o)
+# -i initrd	specify initrd file
+# -d devtree	specify device-tree blob
+# -s tree.dts	specify device-tree source file (needs dtc installed)
+# -c		cache $kernel.strip.gz (use if present & newer, else make)
+# -C prefix	specify command prefix for cross-building tools
+#		(strip, objcopy, ld)
+# -D dir	specify directory containing data files used by script
+#		(default ./arch/powerpc/boot)
+# -W dir	specify working directory for temporary files (default .)
+
+# defaults
+kernel=
+ofile=zImage
+platform=of
+initrd=
+dtb=
+dts=
+cacheit=
+
+# cross-compilation prefix
+CROSS=
+
+# directory for object and other files used by this script
+object=arch/powerpc/boot
+
+# directory for working files
+tmpdir=.
+
+usage() {
+    echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2
+    echo '       [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2
+    echo '       [-D datadir] [-W workingdir] [vmlinux]' >&2
+    exit 1
+}
+
+while [ "$#" -gt 0 ]; do
+    case "$1" in
+    -o)
+	shift
+	[ "$#" -gt 0 ] || usage
+	ofile="$1"
+	;;
+    -p)
+	shift
+	[ "$#" -gt 0 ] || usage
+	platform="$1"
+	;;
+    -i)
+	shift
+	[ "$#" -gt 0 ] || usage
+	initrd="$1"
+	;;
+    -d)
+	shift
+	[ "$#" -gt 0 ] || usage
+	dtb="$1"
+	;;
+    -s)
+	shift
+	[ "$#" -gt 0 ] || usage
+	dts="$1"
+	;;
+    -c)
+	cacheit=y
+	;;
+    -C)
+	shift
+	[ "$#" -gt 0 ] || usage
+	CROSS="$1"
+	;;
+    -D)
+	shift
+	[ "$#" -gt 0 ] || usage
+	object="$1"
+	;;
+    -W)
+	shift
+	[ "$#" -gt 0 ] || usage
+	tmpdir="$1"
+	;;
+    -?)
+	usage
+	;;
+    *)
+	[ -z "$kernel" ] || usage
+	kernel="$1"
+	;;
+    esac
+    shift
+done
+
+if [ -n "$dts" ]; then
+    if [ -z "$dtb" ]; then
+	dtb="$platform.dtb"
+    fi
+    dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1
+fi
+
+if [ -z "$kernel" ]; then
+    kernel=vmlinux
+fi
+
+platformo=$object/"$platform".o
+lds=$object/zImage.lds
+ext=strip
+objflags=-S
+tmp=$tmpdir/zImage.$$.o
+ksection=.kernel:vmlinux.strip
+isection=.kernel:initrd
+
+case "$platform" in
+pmac|pseries|chrp)
+    platformo=$object/of.o
+    ;;
+pmaccoff)
+    platformo=$object/of.o
+    lds=$object/zImage.coff.lds
+    ;;
+miboot|uboot)
+    # miboot and U-boot want just the bare bits, not an ELF binary
+    ext=bin
+    objflags="-O binary"
+    tmp="$ofile"
+    ksection=image
+    isection=initrd
+    ;;
+esac
+
+vmz="$tmpdir/`basename \"$kernel\"`.$ext"
+if [ -z "$cacheit" -o ! -f "$vmz.gz" -o "$vmz.gz" -ot "$kernel" ]; then
+    ${CROSS}objcopy $objflags "$kernel" "$vmz.$$"
+    gzip -f -9 "$vmz.$$"
+    if [ -n "$cacheit" ]; then
+	mv -f "$vmz.$$.gz" "$vmz.gz"
+    else
+	vmz="$vmz.$$"
+    fi
+fi
+
+case "$platform" in
+uboot)
+    rm -f "$ofile"
+    version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
+	cut -d' ' -f3`
+    if [ -n "$version" ]; then
+	version="-n Linux-$version"
+    fi
+    mkimage -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \
+	$version -d "$vmz.gz" "$ofile"
+    if [ -z "$cacheit" ]; then
+	rm -f $vmz.gz
+    fi
+    exit 0
+    ;;
+esac
+
+addsec() {
+    ${CROSS}objcopy $4 $1 \
+	--add-section=$3="$2" \
+	--set-section-flags=$3=contents,alloc,load,readonly,data
+}
+
+addsec $tmp "$vmz.gz" $ksection $object/empty.o
+if [ -z "$cacheit" ]; then
+    rm -f "$vmz.gz"
+fi
+
+if [ -n "$initrd" ]; then
+    addsec $tmp "$initrd" initrd
+fi
+
+if [ -n "$dtb" ]; then
+    addsec $tmp "$dtb" dtb
+fi
+
+if [ "$platform" != "miboot" ]; then
+    ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \
+	$object/crt0.o $platformo $tmp $object/wrapper.a
+    rm $tmp
+fi
+
+# post-processing needed for some platforms
+case "$platform" in
+pseries|chrp)
+    $object/addnote "$ofile"
+    ;;
+pmaccoff)
+    ${CROSS}objcopy -O aixcoff-rs6000 --set-start 0x500000 "$ofile"
+    $object/hack-coff "$ofile"
+    ;;
+esac
diff --git a/arch/powerpc/boot/zImage.coff.lds b/arch/powerpc/boot/zImage.coff.lds.S
similarity index 96%
rename from arch/powerpc/boot/zImage.coff.lds
rename to arch/powerpc/boot/zImage.coff.lds.S
index 6016251..05f3238 100644
--- a/arch/powerpc/boot/zImage.coff.lds
+++ b/arch/powerpc/boot/zImage.coff.lds.S
@@ -15,6 +15,7 @@
   {
     *(.rodata*)
     *(.data*)
+    *(__builtin_*)
     *(.sdata*)
     __got2_start = .;
     *(.got2)
diff --git a/arch/powerpc/boot/zImage.lds b/arch/powerpc/boot/zImage.lds.S
similarity index 100%
rename from arch/powerpc/boot/zImage.lds
rename to arch/powerpc/boot/zImage.lds.S
diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig
index bbf2b5f..fee72f8 100644
--- a/arch/powerpc/configs/chrp32_defconfig
+++ b/arch/powerpc/configs/chrp32_defconfig
@@ -492,7 +492,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index 4b9c2ed..92d0a9d 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -490,23 +490,23 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
 # CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
index eb0885e..d58f82f 100644
--- a/arch/powerpc/configs/iseries_defconfig
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -475,7 +475,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig
index 719fba4..d1811e7 100644
--- a/arch/powerpc/configs/mpc7448_hpc2_defconfig
+++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -413,23 +413,23 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
 # CONFIG_SCSI_ATA_PIIX is not set
-CONFIG_SCSI_SATA_MV=y
-# CONFIG_SCSI_SATA_NV is not set
+CONFIG_SATA_MV=y
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig
index 8da6a47..cd3535e 100644
--- a/arch/powerpc/configs/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/mpc834x_itx_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc6
-# Sun Sep 10 10:28:05 2006
+# Linux kernel version: 2.6.18
+# Mon Sep 25 19:41:14 2006
 #
 # CONFIG_PPC64 is not set
 CONFIG_PPC32=y
@@ -21,6 +21,7 @@
 CONFIG_PPC_OF=y
 CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
 CONFIG_DEFAULT_UIMAGE=y
 
 #
@@ -61,25 +62,25 @@
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
 # CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -259,7 +260,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -313,6 +313,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -464,23 +465,23 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
 # CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-CONFIG_SCSI_SATA_SIL=y
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
@@ -1277,11 +1278,11 @@
 #
 # Kernel hacking
 #
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
@@ -1293,15 +1294,15 @@
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUGGER is not set
 # CONFIG_BDI_SWITCH is not set
-CONFIG_BOOTX_TEXT=y
-CONFIG_SERIAL_TEXT_DEBUG=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
 
 #
@@ -1314,6 +1315,8 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+# CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1323,6 +1326,8 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/powerpc/configs/mpc8360emds_defconfig b/arch/powerpc/configs/mpc8360emds_defconfig
new file mode 100644
index 0000000..c070341
--- /dev/null
+++ b/arch/powerpc/configs/mpc8360emds_defconfig
@@ -0,0 +1,1018 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18
+# Thu Sep 21 18:14:27 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+CONFIG_PPC_83xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_QUICC_ENGINE=y
+CONFIG_PPC_GEN550=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC834x_SYS is not set
+# CONFIG_MPC834x_ITX is not set
+CONFIG_MPC8360E_PB=y
+CONFIG_PPC_MPC836x=y
+# CONFIG_MPIC is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# 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_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_GIANFAR is not set
+CONFIG_UCC_GETH=y
+# CONFIG_UGETH_NAPI is not set
+# CONFIG_UGETH_MAGIC_PACKET is not set
+# CONFIG_UGETH_FILTERING is not set
+# CONFIG_UGETH_TX_ON_DEMOND is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_83xx_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# 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_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F 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
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# 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_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# 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
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# QE Options
+#
+# CONFIG_UCC_SLOW is not set
+CONFIG_UCC_FAST=y
+CONFIG_UCC=y
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_FS is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/mpc8560_ads_defconfig b/arch/powerpc/configs/mpc8560_ads_defconfig
new file mode 100644
index 0000000..ddc2a7b
--- /dev/null
+++ b/arch/powerpc/configs/mpc8560_ads_defconfig
@@ -0,0 +1,854 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc4
+# Fri Aug 11 16:45:05 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_85xx=y
+CONFIG_E500=y
+CONFIG_BOOKE=y
+CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_SPE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_MPIC=y
+CONFIG_CPM2=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC8540_ADS is not set
+CONFIG_MPC8560_ADS=y
+# CONFIG_MPC85xx_CDS is not set
+CONFIG_MPC8560=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_PC_KEYBOARD is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_PCI_DEBUG=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+CONFIG_FS_ENET=y
+# CONFIG_FS_ENET_HAS_SCC is not set
+CONFIG_FS_ENET_HAS_FCC=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+CONFIG_SERIAL_CPM_SCC1=y
+CONFIG_SERIAL_CPM_SCC2=y
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# 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
+# CONFIG_BRIQ_PANEL is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# 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
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 6861dde..765c8bb 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -682,7 +682,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -1826,7 +1826,7 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 7517d0c..be11df7 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -520,23 +520,23 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
 # CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index a8cdf31..44175fb 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -506,7 +506,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 190a57e..47a613c 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -763,10 +763,10 @@
 		.cpu_setup		= __setup_cpu_603,
 		.platform		= "ppc603",
 	},
-	{	/* e300 (a 603e core, plus some) on 83xx */
+	{	/* e300c1 (a 603e core, plus some) on 83xx */
 		.pvr_mask		= 0x7fff0000,
 		.pvr_value		= 0x00830000,
-		.cpu_name		= "e300",
+		.cpu_name		= "e300c1",
 		.cpu_features		= CPU_FTRS_E300,
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
@@ -774,6 +774,17 @@
 		.cpu_setup		= __setup_cpu_603,
 		.platform		= "ppc603",
 	},
+	{	/* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */
+		.pvr_mask		= 0x7fff0000,
+		.pvr_value		= 0x00840000,
+		.cpu_name		= "e300c2",
+		.cpu_features		= CPU_FTRS_E300,
+		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_603,
+		.platform		= "ppc603",
+	},
 	{	/* default match, we assume split I/D cache & TB (non-601)... */
 		.pvr_mask		= 0x00000000,
 		.pvr_value		= 0x00000000,
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2cd872b..748e74f 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -27,10 +27,7 @@
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/cputable.h>
-
-#ifdef CONFIG_PPC_ISERIES
-#define DO_SOFT_DISABLE
-#endif
+#include <asm/firmware.h>
 
 /*
  * System calls.
@@ -91,6 +88,7 @@
 	ld	r11,exception_marker@toc(r2)
 	std	r11,-16(r9)		/* "regshere" marker */
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	/* Hack for handling interrupts when soft-enabling on iSeries */
 	cmpdi	cr1,r0,0x5555		/* syscall 0x5555 */
 	andi.	r10,r12,MSR_PR		/* from kernel */
@@ -98,6 +96,7 @@
 	beq	hardware_interrupt_entry
 	lbz	r10,PACAPROCENABLED(r13)
 	std	r10,SOFTE(r1)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 	mfmsr	r11
 	ori	r11,r11,MSR_EE
@@ -462,6 +461,7 @@
 
 restore:
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	ld	r5,SOFTE(r1)
 	cmpdi	0,r5,0
 	beq	4f
@@ -480,6 +480,7 @@
 	b	.ret_from_except_lite		/* loop back and handle more */
 
 4:	stb	r5,PACAPROCENABLED(r13)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 
 	ld	r3,_MSR(r1)
@@ -538,18 +539,23 @@
 	lwz	r8,TI_PREEMPT(r9)
 	cmpwi	cr1,r8,0
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	ld	r0,SOFTE(r1)
 	cmpdi	r0,0
-#else
-	andi.	r0,r3,MSR_EE
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
+BEGIN_FW_FTR_SECTION
+	andi.	r0,r3,MSR_EE
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 	crandc	eq,cr1*4+eq,eq
 	bne	restore
 	/* here we are preempting the current task */
 1:
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	li	r0,1
 	stb	r0,PACAPROCENABLED(r13)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1		/* reenable interrupts */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 3065b47..645c7f1 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -33,6 +33,7 @@
 #include <asm/hvcall.h>
 #include <asm/iseries/lpar_map.h>
 #include <asm/thread_info.h>
+#include <asm/firmware.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
@@ -365,19 +366,28 @@
 
 #ifdef DO_SOFT_DISABLE
 #define DISABLE_INTS				\
+BEGIN_FW_FTR_SECTION;				\
 	lbz	r10,PACAPROCENABLED(r13);	\
 	li	r11,0;				\
 	std	r10,SOFTE(r1);			\
 	mfmsr	r10;				\
 	stb	r11,PACAPROCENABLED(r13);	\
 	ori	r10,r10,MSR_EE;			\
-	mtmsrd	r10,1
+	mtmsrd	r10,1;				\
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 
 #define ENABLE_INTS				\
+BEGIN_FW_FTR_SECTION;				\
 	lbz	r10,PACAPROCENABLED(r13);	\
 	mfmsr	r11;				\
 	std	r10,SOFTE(r1);			\
 	ori	r11,r11,MSR_EE;			\
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES);	\
+BEGIN_FW_FTR_SECTION;				\
+	ld	r12,_MSR(r1);			\
+	mfmsr	r11;				\
+	rlwimi	r11,r12,0,MSR_EE;		\
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);	\
 	mtmsrd	r11,1
 
 #else	/* hard enable/disable interrupts */
@@ -1071,8 +1081,10 @@
 	ld	r3,PACA_EXSLB+EX_R3(r13)
 	lwz	r9,PACA_EXSLB+EX_CCR(r13)	/* get saved CR */
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	ld	r11,PACALPPACAPTR(r13)
 	ld	r11,LPPACASRR0(r11)		/* get SRR0 value */
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
 
 	mtlr	r10
@@ -1087,8 +1099,10 @@
 .machine	pop
 
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	mtspr	SPRN_SRR0,r11
 	mtspr	SPRN_SRR1,r12
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
 	ld	r9,PACA_EXSLB+EX_R9(r13)
 	ld	r10,PACA_EXSLB+EX_R10(r13)
@@ -1301,6 +1315,7 @@
 	cmpdi	r3,0			/* see if hash_page succeeded */
 
 #ifdef DO_SOFT_DISABLE
+BEGIN_FW_FTR_SECTION
 	/*
 	 * If we had interrupts soft-enabled at the point where the
 	 * DSI/ISI occurred, and an interrupt came in during hash_page,
@@ -1321,12 +1336,14 @@
 	ld	r3,SOFTE(r1)
 	bl	.local_irq_restore
 	b	11f
-#else
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif
+BEGIN_FW_FTR_SECTION
 	beq	fast_exception_return   /* Return from exception on success */
 	ble-	12f			/* Failure return from hash_page */
 
 	/* fall through */
-#endif
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
 /* Here we have a page fault that hash_page can't handle. */
 _GLOBAL(handle_page_fault)
@@ -1861,7 +1878,9 @@
 	LOAD_REG_ADDR(r3, .start_secondary_prolog)
 	LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
 #ifdef DO_SOFT_DISABLE
+BEGIN_FW_FTR_SECTION
 	ori	r4,r4,MSR_EE
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 	mtspr	SPRN_SRR0,r3
 	mtspr	SPRN_SRR1,r4
@@ -1986,6 +2005,7 @@
 	 */
 	li	r3,0
 	bl	.do_cpu_ftr_fixups
+	bl	.do_fw_ftr_fixups
 
 	/* ptr to current */
 	LOAD_REG_IMMEDIATE(r4, init_task)
@@ -2000,11 +2020,13 @@
 	/* Load up the kernel context */
 5:
 #ifdef DO_SOFT_DISABLE
+BEGIN_FW_FTR_SECTION
 	li	r5,0
 	stb	r5,PACAPROCENABLED(r13)	/* Soft Disabled */
 	mfmsr	r5
 	ori	r5,r5,MSR_EE		/* Hard Enabled */
 	mtmsrd	r5
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 
 	bl .start_kernel
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index b443233..c3f58f2 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -777,7 +777,6 @@
 {
 	unsigned long flags;
 	unsigned int i, j, found = NO_IRQ;
-	unsigned int limit = irq_virq_count - count;
 
 	if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
 		return NO_IRQ;
@@ -794,14 +793,16 @@
 	/* Look for count consecutive numbers in the allocatable
 	 * (non-legacy) space
 	 */
-	for (i = NUM_ISA_INTERRUPTS; i <= limit; ) {
-		for (j = i; j < (i + count); j++)
-			if (irq_map[j].host != NULL) {
-				i = j + 1;
-				continue;
-			}
-		found = i;
-		break;
+	for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
+		if (irq_map[i].host != NULL)
+			j = 0;
+		else
+			j++;
+
+		if (j == count) {
+			found = i - count + 1;
+			break;
+		}
 	}
 	if (found == NO_IRQ) {
 		spin_unlock_irqrestore(&irq_big_lock, flags);
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index cd65c36..7b8d12b 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -259,14 +259,15 @@
  */
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
-        struct kretprobe_instance *ri = NULL;
-        struct hlist_head *head;
-        struct hlist_node *node, *tmp;
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head, empty_rp;
+	struct hlist_node *node, *tmp;
 	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+	INIT_HLIST_HEAD(&empty_rp);
 	spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
+	head = kretprobe_inst_table_head(current);
 
 	/*
 	 * It is possible to have multiple instances associated with a given
@@ -277,20 +278,20 @@
 	 * We can handle this because:
 	 *     - instances are always inserted at the head of the list
 	 *     - when multiple return probes are registered for the same
-         *       function, the first instance's ret_addr will point to the
+	 *       function, the first instance's ret_addr will point to the
 	 *       real return address, and all the rest will point to
 	 *       kretprobe_trampoline
 	 */
 	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
+		if (ri->task != current)
 			/* another task is sharing our hash bucket */
-                        continue;
+			continue;
 
 		if (ri->rp && ri->rp->handler)
 			ri->rp->handler(ri, regs);
 
 		orig_ret_address = (unsigned long)ri->ret_addr;
-		recycle_rp_inst(ri);
+		recycle_rp_inst(ri, &empty_rp);
 
 		if (orig_ret_address != trampoline_address)
 			/*
@@ -308,12 +309,16 @@
 	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	preempt_enable_no_resched();
 
-        /*
-         * 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;
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
+	/*
+	 * 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;
 }
 
 /*
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 58758d8..88fd73f 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -843,7 +843,7 @@
 	addi	r1,r1,16
 	blr
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
 	li	r0,__NR_execve
 	sc
 	bnslr
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index e3ed21c..41521b3 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -325,6 +325,52 @@
 	isync
 	b	1b
 
+/*
+ * do_fw_ftr_fixups - goes through the list of firmware feature fixups
+ * and writes nop's over sections of code that don't apply for this firmware.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_fw_ftr_fixups)
+	/* Get firmware features */
+	LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
+	sub	r6,r6,r3
+	ld	r4,0(r6)
+	/* Get the fixup table */
+	LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
+	sub	r6,r6,r3
+	LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
+	sub	r7,r7,r3
+	/* Do the fixup */
+1:	cmpld	r6,r7
+	bgelr
+	addi	r6,r6,32
+	ld	r8,-32(r6)	/* mask */
+	and	r8,r8,r4
+	ld	r9,-24(r6)	/* value */
+	cmpld	r8,r9
+	beq	1b
+	ld	r8,-16(r6)	/* section begin */
+	ld	r9,-8(r6)	/* section end */
+	subf.	r9,r8,r9
+	beq	1b
+	/* write nops over the section of code */
+	/* todo: if large section, add a branch at the start of it */
+	srwi	r9,r9,2
+	mtctr	r9
+	sub	r8,r8,r3
+	lis	r0,0x60000000@h	/* nop */
+3:	stw	r0,0(r8)
+BEGIN_FTR_SECTION
+	dcbst	0,r8		/* suboptimal, but simpler */
+	sync
+	icbi	0,r8
+END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE)
+	addi	r8,r8,4
+	bdnz	3b
+	sync			/* additional sync needed on g4 */
+	isync
+	b	1b
+
 #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
 /*
  * Do an IO access in real mode
@@ -556,7 +602,7 @@
 
 #endif /* CONFIG_ALTIVEC */
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
 	li	r0,__NR_execve
 	sc
 	bnslr
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index c1b1e14..78d3c0f 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -30,6 +30,7 @@
 #include <asm/byteorder.h>
 #include <asm/machdep.h>
 #include <asm/ppc-pci.h>
+#include <asm/firmware.h>
 
 #ifdef DEBUG
 #include <asm/udbg.h>
@@ -209,7 +210,6 @@
 		kfree(phb);
 }
 
-#ifndef CONFIG_PPC_ISERIES
 void __devinit pcibios_claim_one_bus(struct pci_bus *b)
 {
 	struct pci_dev *dev;
@@ -238,10 +238,12 @@
 {
 	struct pci_bus *b;
 
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return;
+
 	list_for_each_entry(b, &pci_root_buses, node)
 		pcibios_claim_one_bus(b);
 }
-#endif
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
@@ -554,9 +556,8 @@
 	 */
 	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
 
-#ifdef CONFIG_PPC_ISERIES
-	iSeries_pcibios_init(); 
-#endif
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		iSeries_pcibios_init();
 
 	printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
 
@@ -566,15 +567,15 @@
 		pci_bus_add_devices(hose->bus);
 	}
 
-#ifndef CONFIG_PPC_ISERIES
-	if (pci_probe_only)
-		pcibios_claim_of_setup();
-	else
-		/* FIXME: `else' will be removed when
-		   pci_assign_unassigned_resources() is able to work
-		   correctly with [partially] allocated PCI tree. */
-		pci_assign_unassigned_resources();
-#endif /* !CONFIG_PPC_ISERIES */
+	if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
+		if (pci_probe_only)
+			pcibios_claim_of_setup();
+		else
+			/* FIXME: `else' will be removed when
+			   pci_assign_unassigned_resources() is able to work
+			   correctly with [partially] allocated PCI tree. */
+			pci_assign_unassigned_resources();
+	}
 
 	/* Call machine dependent final fixup */
 	if (ppc_md.pcibios_fixup)
@@ -586,8 +587,9 @@
 		printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-	/* map in PCI I/O space */
-	phbs_remap_io();
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		/* map in PCI I/O space */
+		phbs_remap_io();
 #endif
 
 	printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
@@ -637,13 +639,13 @@
  */
 int pci_domain_nr(struct pci_bus *bus)
 {
-#ifdef CONFIG_PPC_ISERIES
-	return 0;
-#else
-	struct pci_controller *hose = pci_bus_to_host(bus);
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return 0;
+	else {
+		struct pci_controller *hose = pci_bus_to_host(bus);
 
-	return hose->global_number;
-#endif
+		return hose->global_number;
+	}
 }
 
 EXPORT_SYMBOL(pci_domain_nr);
@@ -651,12 +653,12 @@
 /* Decide whether to display the domain number in /proc */
 int pci_proc_domain(struct pci_bus *bus)
 {
-#ifdef CONFIG_PPC_ISERIES
-	return 0;
-#else
-	struct pci_controller *hose = pci_bus_to_host(bus);
-	return hose->buid;
-#endif
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return 0;
+	else {
+		struct pci_controller *hose = pci_bus_to_host(bus);
+		return hose->buid;
+	}
 }
 
 /*
diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c
index bdc3977..e0dcf2b 100644
--- a/arch/powerpc/kernel/perfmon_fsl_booke.c
+++ b/arch/powerpc/kernel/perfmon_fsl_booke.c
@@ -1,4 +1,4 @@
-/* kernel/perfmon_fsl_booke.c
+/* arch/powerpc/kernel/perfmon_fsl_booke.c
  * Freescale Book-E Performance Monitor code
  *
  * Author: Andy Fleming
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index a127a1e..7b2f645 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -424,7 +424,7 @@
 	printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
 	       regs->nip, regs->link, regs->ctr);
 	printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
-	       regs, regs->trap, print_tainted(), system_utsname.release);
+	       regs, regs->trap, print_tainted(), init_utsname()->release);
 	printk("MSR: "REG" ", regs->msr);
 	printbits(regs->msr, msr_bits);
 	printk("  CR: %08lX  XER: %08lX\n", regs->ccr, regs->xer);
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index dea75d7..975102a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -526,9 +526,7 @@
 
 void do_syscall_trace_enter(struct pt_regs *regs)
 {
-#ifdef CONFIG_PPC64
 	secure_computing(regs->gpr[0]);
-#endif
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE)
 	    && (current->ptrace & PT_PTRACED))
@@ -548,12 +546,8 @@
 
 void do_syscall_trace_leave(struct pt_regs *regs)
 {
-#ifdef CONFIG_PPC32
-	secure_computing(regs->gpr[0]);
-#endif
-
 	if (unlikely(current->audit_context))
-		audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+		audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
 				   regs->result);
 
 	if ((test_thread_flag(TIF_SYSCALL_TRACE)
@@ -561,8 +555,3 @@
 	    && (current->ptrace & PT_PTRACED))
 		do_syscall_trace();
 }
-
-#ifdef CONFIG_PPC32
-EXPORT_SYMBOL(do_syscall_trace_enter);
-EXPORT_SYMBOL(do_syscall_trace_leave);
-#endif
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 0af3fc1..89cfaf4 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -442,31 +442,6 @@
 }
 #endif /* CONFIG_SMP */
 
-int __initdata do_early_xmon;
-#ifdef CONFIG_XMON
-extern int xmon_no_auto_backtrace;
-
-static int __init early_xmon(char *p)
-{
-	/* ensure xmon is enabled */
-	if (p) {
-		if (strncmp(p, "on", 2) == 0)
-			xmon_init(1);
-		if (strncmp(p, "off", 3) == 0)
-			xmon_init(0);
-		if (strncmp(p, "nobt", 4) == 0)
-			xmon_no_auto_backtrace = 1;
-		if (strncmp(p, "early", 5) != 0)
-			return 0;
-	}
-	xmon_init(1);
-	do_early_xmon = 1;
-
-	return 0;
-}
-early_param("xmon", early_xmon);
-#endif
-
 static __init int add_pcspkr(void)
 {
 	struct device_node *np;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 79a1779..191d0ab 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -238,12 +238,11 @@
 
 	smp_setup_cpu_maps();
 
-#ifdef CONFIG_XMON_DEFAULT
-	xmon_init(1);
-#endif
 	/* Register early console */
 	register_early_udbg_console();
 
+	xmon_setup();
+
 #if defined(CONFIG_KGDB)
 	if (ppc_md.kgdb_map_scc)
 		ppc_md.kgdb_map_scc();
@@ -280,9 +279,6 @@
 	init_mm.end_data = (unsigned long) _edata;
 	init_mm.brk = klimit;
 
-	if (do_early_xmon)
-		debugger(NULL);
-
 	/* set up the bootmem stuff with available memory */
 	do_init_bootmem();
 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 962ad5e..4b2e32e 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -391,18 +391,14 @@
 	find_legacy_serial_ports();
 
 	/*
-	 * Initialize xmon
-	 */
-#ifdef CONFIG_XMON_DEFAULT
-	xmon_init(1);
-#endif
-	/*
 	 * Register early console
 	 */
 	register_early_udbg_console();
 
-	if (do_early_xmon)
-		debugger(NULL);
+	/*
+	 * Initialize xmon
+	 */
+	xmon_setup();
 
 	check_smt_enabled();
 	smp_setup_cpu_maps();
@@ -414,7 +410,7 @@
 	smp_release_cpus();
 #endif
 
-	printk("Starting Linux PPC64 %s\n", system_utsname.version);
+	printk("Starting Linux PPC64 %s\n", init_utsname()->version);
 
 	printk("-----------------------------------------------------\n");
 	printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 5e391fc..d15c33e 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -69,16 +69,20 @@
 };
 
 static int fillonedir(void * __buf, const char * name, int namlen,
-		                  off_t offset, ino_t ino, unsigned int d_type)
+		                  off_t offset, u64 ino, unsigned int d_type)
 {
 	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
 	struct old_linux_dirent32 __user * dirent;
+	ino_t d_ino;
 
 	if (buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	buf->count++;
 	dirent = buf->dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(offset, &dirent->d_offset);
 	put_user(namlen, &dirent->d_namlen);
 	copy_to_user(dirent->d_name, name, namlen);
@@ -120,15 +124,20 @@
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+	compat_ino_t ino;
 	long err;
 
 	if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
 	    !new_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
+	ino = stat->ino;
+	if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+		return -EOVERFLOW;
+
 	err  = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
 	err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
-	err |= __put_user(stat->ino, &statbuf->st_ino);
+	err |= __put_user(ino, &statbuf->st_ino);
 	err |= __put_user(stat->mode, &statbuf->st_mode);
 	err |= __put_user(stat->nlink, &statbuf->st_nlink);
 	err |= __put_user(stat->uid, &statbuf->st_uid);
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 9b69d99..d358866 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -260,7 +260,7 @@
 	int err = 0;
 
 	down_read(&uts_sem);
-	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+	if (copy_to_user(name, utsname(), sizeof(*name)))
 		err = -EFAULT;
 	up_read(&uts_sem);
 	if (!err)
@@ -273,7 +273,7 @@
 	int err = 0;
 	
 	down_read(&uts_sem);
-	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+	if (copy_to_user(name, utsname(), sizeof(*name)))
 		err = -EFAULT;
 	up_read(&uts_sem);
 	if (!err)
@@ -289,19 +289,19 @@
 		return -EFAULT;
   
 	down_read(&uts_sem);
-	error = __copy_to_user(&name->sysname, &system_utsname.sysname,
+	error = __copy_to_user(&name->sysname, &utsname()->sysname,
 			       __OLD_UTS_LEN);
 	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
+	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
 				__OLD_UTS_LEN);
 	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->release, &system_utsname.release,
+	error |= __copy_to_user(&name->release, &utsname()->release,
 				__OLD_UTS_LEN);
 	error |= __put_user(0, name->release + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->version, &system_utsname.version,
+	error |= __copy_to_user(&name->version, &utsname()->version,
 				__OLD_UTS_LEN);
 	error |= __put_user(0, name->version + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->machine, &system_utsname.machine,
+	error |= __copy_to_user(&name->machine, &utsname()->machine,
 				__OLD_UTS_LEN);
 	error |= override_machine(name->machine);
 	up_read(&uts_sem);
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 406f308..d45a168 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -25,8 +25,8 @@
 /* SMT stuff */
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-/* default to snooze disabled */
-DEFINE_PER_CPU(unsigned long, smt_snooze_delay);
+/* Time in microseconds we delay before sleeping in the idle loop */
+DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
 
 static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
 				      size_t count)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 8b278d8..85b9244 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1041,6 +1041,48 @@
 	set_dec(tb_ticks_per_jiffy);
 }
 
+#ifdef CONFIG_RTC_CLASS
+static int set_rtc_class_time(struct rtc_time *tm)
+{
+	int err;
+	struct class_device *class_dev =
+		rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+
+	if (class_dev == NULL)
+		return -ENODEV;
+
+	err = rtc_set_time(class_dev, tm);
+
+	rtc_class_close(class_dev);
+
+	return 0;
+}
+
+static void get_rtc_class_time(struct rtc_time *tm)
+{
+	int err;
+	struct class_device *class_dev =
+		rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+
+	if (class_dev == NULL)
+		return;
+
+	err = rtc_read_time(class_dev, tm);
+
+	rtc_class_close(class_dev);
+
+	return;
+}
+
+int __init rtc_class_hookup(void)
+{
+	ppc_md.get_rtc_time = get_rtc_class_time;
+	ppc_md.set_rtc_time = set_rtc_class_time;
+
+	return 0;
+}
+#endif /* CONFIG_RTC_CLASS */
+
 
 #define FEBRUARY	2
 #define	STARTOFTIME	1970
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 02665a0..cb0e8d4 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -132,6 +132,14 @@
 		*(__ftr_fixup)
 		__stop___ftr_fixup = .;
 	}
+#ifdef CONFIG_PPC64
+	. = ALIGN(8);
+	__fw_ftr_fixup : {
+		__start___fw_ftr_fixup = .;
+		*(__fw_ftr_fixup)
+		__stop___fw_ftr_fixup = .;
+	}
+#endif
 
 	. = ALIGN(PAGE_SIZE);
 	.init.ramfs : {
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 336dd19..a0360ae 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -14,9 +14,15 @@
 obj-$(CONFIG_PPC64)	+= checksum_64.o copypage_64.o copyuser_64.o \
 			   memcpy_64.o usercopy_64.o mem_64.o string.o \
 			   strcase.o
+obj-$(CONFIG_QUICC_ENGINE) += rheap.o
 obj-$(CONFIG_XMON)	+= sstep.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)	+= locks.o
 obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
 endif
+
+# Temporary hack until we have migrated to asm-powerpc
+ifeq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_CPM2)	+= rheap.o
+endif
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
index 31e5118..57bf991 100644
--- a/arch/powerpc/lib/rheap.c
+++ b/arch/powerpc/lib/rheap.c
@@ -423,17 +423,21 @@
 	return (void *)s;
 }
 
-void *rh_alloc(rh_info_t * info, int size, const char *owner)
+void *rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner)
 {
 	struct list_head *l;
 	rh_block_t *blk;
 	rh_block_t *newblk;
 	void *start;
 
-	/* Validate size */
-	if (size <= 0)
+	/* Validate size, (must be power of two) */
+	if (size <= 0 || (alignment & (alignment - 1)) != 0)
 		return ERR_PTR(-EINVAL);
 
+	/* given alignment larger that default rheap alignment */
+	if (alignment > info->alignment)
+		size += alignment - 1;
+
 	/* Align to configured alignment */
 	size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
 
@@ -476,15 +480,27 @@
 
 	attach_taken_block(info, newblk);
 
+	/* for larger alignment return fixed up pointer  */
+	/* this is no problem with the deallocator since */
+	/* we scan for pointers that lie in the blocks   */
+	if (alignment > info->alignment)
+		start = (void *)(((unsigned long)start + alignment - 1) &
+				~(alignment - 1));
+
 	return start;
 }
 
+void *rh_alloc(rh_info_t * info, int size, const char *owner)
+{
+	return rh_alloc_align(info, size, info->alignment, owner);
+}
+
 /* allocate at precisely the given address */
 void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
 {
 	struct list_head *l;
 	rh_block_t *blk, *newblk1, *newblk2;
-	unsigned long s, e, m, bs, be;
+	unsigned long s, e, m, bs = 0, be = 0;
 
 	/* Validate size */
 	if (size <= 0)
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 754143e..29bc912 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -11,3 +11,6 @@
 					mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
 					mtfsf.o mtfsfi.o stfiwx.o stfs.o \
 					udivmodti4.o
+
+CFLAGS_fabs.o = -fno-builtin-fabs
+CFLAGS_math.o = -fno-builtin-fabs
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index b1da031..ac64f4a 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -63,32 +63,13 @@
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
+#include <asm/firmware.h>
 
 #include "mmu_decl.h"
 
 unsigned long ioremap_bot = IMALLOC_BASE;
 static unsigned long phbs_io_bot = PHBS_IO_BASE;
 
-#ifdef CONFIG_PPC_ISERIES
-
-void __iomem *ioremap(unsigned long addr, unsigned long size)
-{
-	return (void __iomem *)addr;
-}
-
-extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
-		       unsigned long flags)
-{
-	return (void __iomem *)addr;
-}
-
-void iounmap(volatile void __iomem *addr)
-{
-	return;
-}
-
-#else
-
 /*
  * map_io_page currently only called by __ioremap
  * map_io_page adds an entry to the ioremap page table
@@ -161,6 +142,9 @@
 	unsigned long pa, ea;
 	void __iomem *ret;
 
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return (void __iomem *)addr;
+
 	/*
 	 * Choose an address to map it to.
 	 * Once the imalloc system is running, we use it.
@@ -255,6 +239,9 @@
 {
 	void *addr;
 
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return;
+
 	if (!mem_init_done)
 		return;
 	
@@ -315,8 +302,6 @@
 	return 0;
 }
 
-#endif
-
 EXPORT_SYMBOL(ioremap);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index dbc1abb..b10e470 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -21,6 +21,7 @@
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
+#include <asm/firmware.h>
 
 /* void slb_allocate_realmode(unsigned long ea);
  *
@@ -183,6 +184,7 @@
  	 * dont have any LRU information to help us choose a slot.
  	 */
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	/*
 	 * On iSeries, the "bolted" stack segment can be cast out on
 	 * shared processor switch so we need to check for a miss on
@@ -194,6 +196,7 @@
 	li	r10,SLB_NUM_BOLTED-1	/* Stack goes in last bolted slot */
 	cmpld	r9,r3
 	beq	3f
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
 
 	ld	r10,PACASTABRR(r13)
diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c
index 75f57bc..b4278cf 100644
--- a/arch/powerpc/oprofile/backtrace.c
+++ b/arch/powerpc/oprofile/backtrace.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
+#include <asm/compat.h>
 
 #define STACK_SP(STACK)		*(STACK)
 
@@ -26,8 +27,9 @@
 static unsigned int user_getsp32(unsigned int sp, int is_first)
 {
 	unsigned int stack_frame[2];
+	void __user *p = compat_ptr(sp);
 
-	if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+	if (!access_ok(VERIFY_READ, p, sizeof(stack_frame)))
 		return 0;
 
 	/*
@@ -35,8 +37,7 @@
 	 * which means that we've done all that we can do from
 	 * interrupt context.
 	 */
-	if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
-					sizeof(stack_frame)))
+	if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame)))
 		return 0;
 
 	if (!is_first)
@@ -54,10 +55,10 @@
 {
 	unsigned long stack_frame[3];
 
-	if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+	if (!access_ok(VERIFY_READ, (void __user *)sp, sizeof(stack_frame)))
 		return 0;
 
-	if (__copy_from_user_inatomic(stack_frame, (void *)sp,
+	if (__copy_from_user_inatomic(stack_frame, (void __user *)sp,
 					sizeof(stack_frame)))
 		return 0;
 
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
index e0491c3..d8ee3ae 100644
--- a/arch/powerpc/oprofile/op_model_7450.c
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -1,5 +1,5 @@
 /*
- * oprofile/op_model_7450.c
+ * arch/powerpc/oprofile/op_model_7450.c
  *
  * Freescale 745x/744x oprofile support, based on fsl_booke support
  * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index 93d63e6..e29dede 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -1,5 +1,5 @@
 /*
- * oprofile/op_model_e500.c
+ * arch/powerpc/oprofile/op_model_fsl_booke.c
  *
  * Freescale Book-E oprofile support, based on ppc64 oprofile support
  * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
new file mode 100644
index 0000000..47d841e
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -0,0 +1,21 @@
+menu "Platform support"
+       depends on PPC_82xx
+
+choice
+       prompt "Machine Type"
+       default MPC82xx_ADS
+
+config MPC82xx_ADS
+       bool "Freescale MPC82xx ADS"
+       select DEFAULT_UIMAGE
+       select PQ2ADS
+       select 8272
+       select 8260
+       select CPM2
+       select FSL_SOC
+       help
+         This option enables support for the MPC8272 ADS board
+
+endchoice
+
+endmenu
diff --git a/arch/powerpc/platforms/82xx/Makefile b/arch/powerpc/platforms/82xx/Makefile
new file mode 100644
index 0000000..d9fd4c8
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the PowerPC 82xx linux kernel.
+#
+obj-$(CONFIG_PPC_82xx) += mpc82xx.o
+obj-$(CONFIG_MPC82xx_ADS) += mpc82xx_ads.o
diff --git a/arch/powerpc/platforms/82xx/m82xx_pci.h b/arch/powerpc/platforms/82xx/m82xx_pci.h
new file mode 100644
index 0000000..9cd8893
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/m82xx_pci.h
@@ -0,0 +1,19 @@
+#ifndef _PPC_KERNEL_M82XX_PCI_H
+#define _PPC_KERNEL_M82XX_PCI_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/m8260_pci.h>
+
+#define SIU_INT_IRQ1   ((uint)0x13 + CPM_IRQ_OFFSET)
+
+#ifndef _IO_BASE
+#define _IO_BASE isa_io_base
+#endif
+
+#endif				/* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/powerpc/platforms/82xx/mpc82xx.c b/arch/powerpc/platforms/82xx/mpc82xx.c
new file mode 100644
index 0000000..89d702d
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc82xx.c
@@ -0,0 +1,111 @@
+/*
+ * MPC82xx setup and early boot code plus other random bits.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Copyright (c) 2006 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.
+ */
+
+#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/interrupt.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
+#include <linux/fs_uart_pd.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc8260.h>
+#include <asm/irq.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/cpm2.h>
+#include <asm/udbg.h>
+#include <asm/i8259.h>
+#include <linux/fs_enet_pd.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/cpm2_pic.h>
+
+#include "pq2ads_pd.h"
+
+static int __init get_freq(char *name, unsigned long *val)
+{
+	struct device_node *cpu;
+	unsigned int *fp;
+	int found = 0;
+
+	/* The cpu node should have timebase and clock frequency properties */
+	cpu = of_find_node_by_type(NULL, "cpu");
+
+	if (cpu) {
+		fp = (unsigned int *)get_property(cpu, name, NULL);
+		if (fp) {
+			found = 1;
+			*val = *fp++;
+		}
+
+		of_node_put(cpu);
+	}
+
+	return found;
+}
+
+void __init m82xx_calibrate_decr(void)
+{
+	ppc_tb_freq = 125000000;
+	if (!get_freq("bus-frequency", &ppc_tb_freq)) {
+		printk(KERN_ERR "WARNING: Estimating decrementer frequency "
+				"(not found)\n");
+	}
+	ppc_tb_freq /= 4;
+	ppc_proc_freq = 1000000000;
+	if (!get_freq("clock-frequency", &ppc_proc_freq))
+		printk(KERN_ERR "WARNING: Estimating processor frequency"
+				"(not found)\n");
+}
+
+void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
+{
+	uint pvid, svid, phid1;
+	uint memsize = total_memory;
+
+	pvid = mfspr(SPRN_PVR);
+	svid = mfspr(SPRN_SVR);
+
+	seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
+	seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
+	seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
+	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+	/* Display cpu Pll setting */
+	phid1 = mfspr(SPRN_HID1);
+	seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
+
+	/* Display the amount of memory */
+	seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+}
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
new file mode 100644
index 0000000..4276f08
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -0,0 +1,661 @@
+/*
+ * MPC82xx_ads setup and early boot code plus other random bits.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ * m82xx_restart fix by Wade Farnsworth <wfarnsworth@mvista.com>
+ *
+ * Copyright (c) 2006 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.
+ */
+
+
+#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/interrupt.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
+#include <linux/fs_uart_pd.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc8260.h>
+#include <asm/irq.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/cpm2.h>
+#include <asm/udbg.h>
+#include <asm/i8259.h>
+#include <linux/fs_enet_pd.h>
+
+#include <sysdev/fsl_soc.h>
+#include <../sysdev/cpm2_pic.h>
+
+#include "pq2ads_pd.h"
+
+#ifdef CONFIG_PCI
+static uint pci_clk_frq;
+static struct {
+	unsigned long *pci_int_stat_reg;
+	unsigned long *pci_int_mask_reg;
+} pci_regs;
+
+static unsigned long pci_int_base;
+static struct irq_host *pci_pic_host;
+static struct device_node *pci_pic_node;
+#endif
+
+static void __init mpc82xx_ads_pic_init(void)
+{
+	struct device_node *np = of_find_compatible_node(NULL, "cpm-pic", "CPM2");
+	struct resource r;
+	cpm2_map_t *cpm_reg;
+
+	if (np == NULL) {
+		printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
+		return;
+	}
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_ERR "PIC init: invalid resource\n");
+		of_node_put(np);
+		return;
+	}
+	cpm2_pic_init(np);
+	of_node_put(np);
+
+	/* Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	cpm_reg = (cpm2_map_t *) ioremap(get_immrbase(), sizeof(cpm2_map_t));
+	cpm_reg->im_intctl.ic_siprr = 0x05309770;
+	iounmap(cpm_reg);
+#ifdef CONFIG_PCI
+	/* Initialize stuff for the 82xx CPLD IC and install demux  */
+	m82xx_pci_init_irq();
+#endif
+}
+
+static void init_fcc1_ioports(struct fs_platform_info *fpi)
+{
+	struct io_port *io;
+	u32 tempval;
+	cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+	struct device_node *np;
+	struct resource r;
+	u32 *bcsr;
+
+	np = of_find_node_by_type(NULL, "memory");
+	if (!np) {
+		printk(KERN_INFO "No memory node in device tree\n");
+		return;
+	}
+	if (of_address_to_resource(np, 1, &r)) {
+		printk(KERN_INFO "No memory reg property [1] in devicetree\n");
+		return;
+	}
+	of_node_put(np);
+	bcsr = ioremap(r.start + 4, sizeof(u32));
+	io = &immap->im_ioport;
+
+	/* Enable the PHY */
+	clrbits32(bcsr, BCSR1_FETHIEN);
+	setbits32(bcsr, BCSR1_FETH_RST);
+
+	/* FCC1 pins are on port A/C. */
+	/* Configure port A and C pins for FCC1 Ethernet. */
+
+	tempval = in_be32(&io->iop_pdira);
+	tempval &= ~PA1_DIRA0;
+	tempval |= PA1_DIRA1;
+	out_be32(&io->iop_pdira, tempval);
+
+	tempval = in_be32(&io->iop_psora);
+	tempval &= ~PA1_PSORA0;
+	tempval |= PA1_PSORA1;
+	out_be32(&io->iop_psora, tempval);
+
+	setbits32(&io->iop_ppara, PA1_DIRA0 | PA1_DIRA1);
+
+	/* Alter clocks */
+	tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
+
+	clrbits32(&io->iop_psorc, tempval);
+	clrbits32(&io->iop_pdirc, tempval);
+	setbits32(&io->iop_pparc, tempval);
+
+	cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_rx, CPM_CLK_RX);
+	cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_tx, CPM_CLK_TX);
+
+	iounmap(bcsr);
+	iounmap(immap);
+}
+
+static void init_fcc2_ioports(struct fs_platform_info *fpi)
+{
+	cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+	struct device_node *np;
+	struct resource r;
+	u32 *bcsr;
+
+	struct io_port *io;
+	u32 tempval;
+
+	np = of_find_node_by_type(NULL, "memory");
+	if (!np) {
+		printk(KERN_INFO "No memory node in device tree\n");
+		return;
+	}
+	if (of_address_to_resource(np, 1, &r)) {
+		printk(KERN_INFO "No memory reg property [1] in devicetree\n");
+		return;
+	}
+	of_node_put(np);
+	io = &immap->im_ioport;
+	bcsr = ioremap(r.start + 12, sizeof(u32));
+
+	/* Enable the PHY */
+	clrbits32(bcsr, BCSR3_FETHIEN2);
+	setbits32(bcsr, BCSR3_FETH2_RST);
+
+	/* FCC2 are port B/C. */
+	/* Configure port A and C pins for FCC2 Ethernet. */
+
+	tempval = in_be32(&io->iop_pdirb);
+	tempval &= ~PB2_DIRB0;
+	tempval |= PB2_DIRB1;
+	out_be32(&io->iop_pdirb, tempval);
+
+	tempval = in_be32(&io->iop_psorb);
+	tempval &= ~PB2_PSORB0;
+	tempval |= PB2_PSORB1;
+	out_be32(&io->iop_psorb, tempval);
+
+	setbits32(&io->iop_pparb, PB2_DIRB0 | PB2_DIRB1);
+
+	tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
+
+	/* Alter clocks */
+	clrbits32(&io->iop_psorc, tempval);
+	clrbits32(&io->iop_pdirc, tempval);
+	setbits32(&io->iop_pparc, tempval);
+
+	cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_rx, CPM_CLK_RX);
+	cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_tx, CPM_CLK_TX);
+
+	iounmap(bcsr);
+	iounmap(immap);
+}
+
+void init_fcc_ioports(struct fs_platform_info *fpi)
+{
+	int fcc_no = fs_get_fcc_index(fpi->fs_no);
+
+	switch (fcc_no) {
+	case 0:
+		init_fcc1_ioports(fpi);
+		break;
+	case 1:
+		init_fcc2_ioports(fpi);
+		break;
+	default:
+		printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
+		return;
+	}
+}
+
+static void init_scc1_uart_ioports(struct fs_uart_platform_info *data)
+{
+	cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+
+	/* SCC1 is only on port D */
+	setbits32(&immap->im_ioport.iop_ppard, 0x00000003);
+	clrbits32(&immap->im_ioport.iop_psord, 0x00000001);
+	setbits32(&immap->im_ioport.iop_psord, 0x00000002);
+	clrbits32(&immap->im_ioport.iop_pdird, 0x00000001);
+	setbits32(&immap->im_ioport.iop_pdird, 0x00000002);
+
+	clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
+	clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
+	setbits32(&immap->im_cpmux.cmx_scr,
+		  ((data->clk_tx - 1) << (4 - data->clk_tx)));
+	setbits32(&immap->im_cpmux.cmx_scr,
+		  ((data->clk_rx - 1) << (4 - data->clk_rx)));
+
+	iounmap(immap);
+}
+
+static void init_scc4_uart_ioports(struct fs_uart_platform_info *data)
+{
+	cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+
+	setbits32(&immap->im_ioport.iop_ppard, 0x00000600);
+	clrbits32(&immap->im_ioport.iop_psord, 0x00000600);
+	clrbits32(&immap->im_ioport.iop_pdird, 0x00000200);
+	setbits32(&immap->im_ioport.iop_pdird, 0x00000400);
+
+	clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
+	clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
+	setbits32(&immap->im_cpmux.cmx_scr,
+		  ((data->clk_tx - 1) << (4 - data->clk_tx)));
+	setbits32(&immap->im_cpmux.cmx_scr,
+		  ((data->clk_rx - 1) << (4 - data->clk_rx)));
+
+	iounmap(immap);
+}
+
+void init_scc_ioports(struct fs_uart_platform_info *data)
+{
+	int scc_no = fs_get_scc_index(data->fs_no);
+
+	switch (scc_no) {
+	case 0:
+		init_scc1_uart_ioports(data);
+		data->brg = data->clk_rx;
+		break;
+	case 3:
+		init_scc4_uart_ioports(data);
+		data->brg = data->clk_rx;
+		break;
+	default:
+		printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
+		return;
+	}
+}
+
+void __init m82xx_board_setup(void)
+{
+	cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+	struct device_node *np;
+	struct resource r;
+	u32 *bcsr;
+
+	np = of_find_node_by_type(NULL, "memory");
+	if (!np) {
+		printk(KERN_INFO "No memory node in device tree\n");
+		return;
+	}
+	if (of_address_to_resource(np, 1, &r)) {
+		printk(KERN_INFO "No memory reg property [1] in devicetree\n");
+		return;
+	}
+	of_node_put(np);
+	bcsr = ioremap(r.start + 4, sizeof(u32));
+	/* Enable the 2nd UART port */
+	clrbits32(bcsr, BCSR1_RS232_EN2);
+
+#ifdef CONFIG_SERIAL_CPM_SCC1
+	clrbits32((u32 *) & immap->im_scc[0].scc_sccm,
+		  UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32 *) & immap->im_scc[0].scc_gsmrl,
+		  SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC2
+	clrbits32((u32 *) & immap->im_scc[1].scc_sccm,
+		  UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32 *) & immap->im_scc[1].scc_gsmrl,
+		  SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC3
+	clrbits32((u32 *) & immap->im_scc[2].scc_sccm,
+		  UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32 *) & immap->im_scc[2].scc_gsmrl,
+		  SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC4
+	clrbits32((u32 *) & immap->im_scc[3].scc_sccm,
+		  UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32 *) & immap->im_scc[3].scc_gsmrl,
+		  SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+	iounmap(bcsr);
+	iounmap(immap);
+}
+
+#ifdef CONFIG_PCI
+static void m82xx_pci_mask_irq(unsigned int irq)
+{
+	int bit = irq - pci_int_base;
+
+	*pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
+	return;
+}
+
+static void m82xx_pci_unmask_irq(unsigned int irq)
+{
+	int bit = irq - pci_int_base;
+
+	*pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
+	return;
+}
+
+static void m82xx_pci_mask_and_ack(unsigned int irq)
+{
+	int bit = irq - pci_int_base;
+
+	*pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
+	return;
+}
+
+static void m82xx_pci_end_irq(unsigned int irq)
+{
+	int bit = irq - pci_int_base;
+
+	*pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
+	return;
+}
+
+struct hw_interrupt_type m82xx_pci_ic = {
+	.typename = "MPC82xx ADS PCI",
+	.name = "MPC82xx ADS PCI",
+	.enable = m82xx_pci_unmask_irq,
+	.disable = m82xx_pci_mask_irq,
+	.ack = m82xx_pci_mask_and_ack,
+	.end = m82xx_pci_end_irq,
+	.mask = m82xx_pci_mask_irq,
+	.mask_ack = m82xx_pci_mask_and_ack,
+	.unmask = m82xx_pci_unmask_irq,
+	.eoi = m82xx_pci_end_irq,
+};
+
+static void
+m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc,
+		    struct pt_regs *regs)
+{
+	unsigned long stat, mask, pend;
+	int bit;
+
+	for (;;) {
+		stat = *pci_regs.pci_int_stat_reg;
+		mask = *pci_regs.pci_int_mask_reg;
+		pend = stat & ~mask & 0xf0000000;
+		if (!pend)
+			break;
+		for (bit = 0; pend != 0; ++bit, pend <<= 1) {
+			if (pend & 0x80000000)
+				__do_IRQ(pci_int_base + bit, regs);
+		}
+	}
+}
+
+static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
+{
+	return node == pci_pic_node;
+}
+
+static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
+			    irq_hw_number_t hw)
+{
+	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	set_irq_chip(virq, &m82xx_pci_ic);
+	return 0;
+}
+
+static void pci_host_unmap(struct irq_host *h, unsigned int virq)
+{
+	/* remove chip and handler */
+	set_irq_chip(virq, NULL);
+}
+
+static struct irq_host_ops pci_pic_host_ops = {
+	.match = pci_pic_host_match,
+	.map = pci_pic_host_map,
+	.unmap = pci_host_unmap,
+};
+
+void m82xx_pci_init_irq(void)
+{
+	int irq;
+	cpm2_map_t *immap;
+	struct device_node *np;
+	struct resource r;
+	const u32 *regs;
+	unsigned int size;
+	const u32 *irq_map;
+	int i;
+	unsigned int irq_max, irq_min;
+
+	if ((np = of_find_node_by_type(NULL, "soc")) == NULL) {
+		printk(KERN_INFO "No SOC node in device tree\n");
+		return;
+	}
+	memset(&r, 0, sizeof(r));
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_INFO "No SOC reg property in device tree\n");
+		return;
+	}
+	immap = ioremap(r.start, sizeof(*immap));
+	of_node_put(np);
+
+	/* install the demultiplexer for the PCI cascade interrupt */
+	np = of_find_node_by_type(NULL, "pci");
+	if (!np) {
+		printk(KERN_INFO "No pci node on device tree\n");
+		iounmap(immap);
+		return;
+	}
+	irq_map = get_property(np, "interrupt-map", &size);
+	if ((!irq_map) || (size <= 7)) {
+		printk(KERN_INFO "No interrupt-map property of pci node\n");
+		iounmap(immap);
+		return;
+	}
+	size /= sizeof(irq_map[0]);
+	for (i = 0, irq_max = 0, irq_min = 512; i < size; i += 7, irq_map += 7) {
+		if (irq_map[5] < irq_min)
+			irq_min = irq_map[5];
+		if (irq_map[5] > irq_max)
+			irq_max = irq_map[5];
+	}
+	pci_int_base = irq_min;
+	irq = irq_of_parse_and_map(np, 0);
+	set_irq_chained_handler(irq, m82xx_pci_irq_demux);
+	of_node_put(np);
+	np = of_find_node_by_type(NULL, "pci-pic");
+	if (!np) {
+		printk(KERN_INFO "No pci pic node on device tree\n");
+		iounmap(immap);
+		return;
+	}
+	pci_pic_node = of_node_get(np);
+	/* PCI interrupt controller registers: status and mask */
+	regs = get_property(np, "reg", &size);
+	if ((!regs) || (size <= 2)) {
+		printk(KERN_INFO "No reg property in pci pic node\n");
+		iounmap(immap);
+		return;
+	}
+	pci_regs.pci_int_stat_reg =
+	    ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
+	pci_regs.pci_int_mask_reg =
+	    ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
+	of_node_put(np);
+	/* configure chip select for PCI interrupt controller */
+	immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
+	immap->im_memctl.memc_or3 = 0xffff8010;
+	/* make PCI IRQ level sensitive */
+	immap->im_intctl.ic_siexr &= ~(1 << (14 - (irq - SIU_INT_IRQ1)));
+
+	/* mask all PCI interrupts */
+	*pci_regs.pci_int_mask_reg |= 0xfff00000;
+	iounmap(immap);
+	pci_pic_host =
+	    irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
+			   &pci_pic_host_ops, irq_max + 1);
+	return;
+}
+
+static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
+{
+	if (bus == 0 && PCI_SLOT(devfn) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	else
+		return PCIBIOS_SUCCESSFUL;
+}
+
+static void
+__init mpc82xx_pcibios_fixup(void)
+{
+	struct pci_dev *dev = NULL;
+
+	for_each_pci_dev(dev) {
+		pci_read_irq_line(dev);
+	}
+}
+
+void __init add_bridge(struct device_node *np)
+{
+	int len;
+	struct pci_controller *hose;
+	struct resource r;
+	const int *bus_range;
+	const void *ptr;
+
+	memset(&r, 0, sizeof(r));
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_INFO "No PCI reg property in device tree\n");
+		return;
+	}
+	if (!(ptr = get_property(np, "clock-frequency", NULL))) {
+		printk(KERN_INFO "No clock-frequency property in PCI node");
+		return;
+	}
+	pci_clk_frq = *(uint *) ptr;
+	of_node_put(np);
+	bus_range = get_property(np, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int)) {
+		printk(KERN_WARNING "Can't get bus-range for %s, assume"
+		       " bus 0\n", np->full_name);
+	}
+
+	pci_assign_all_buses = 1;
+
+	hose = pcibios_alloc_controller();
+
+	if (!hose)
+		return;
+
+	hose->arch_data = np;
+	hose->set_cfg_type = 1;
+
+	hose->first_busno = bus_range ? bus_range[0] : 0;
+	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+	hose->bus_offset = 0;
+
+	hose->set_cfg_type = 1;
+
+	setup_indirect_pci(hose,
+			   r.start + offsetof(pci_cpm2_t, pci_cfg_addr),
+			   r.start + offsetof(pci_cpm2_t, pci_cfg_data));
+
+	pci_process_bridge_OF_ranges(hose, np, 1);
+}
+#endif
+
+/*
+ * Setup the architecture
+ */
+static void __init mpc82xx_ads_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+	struct device_node *np;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc82xx_ads_setup_arch()", 0);
+	cpm2_reset();
+
+	/* Map I/O region to a 256MB BAT */
+
+	m82xx_board_setup();
+
+#ifdef CONFIG_PCI
+	ppc_md.pci_exclude_device = m82xx_pci_exclude_device;
+	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+		add_bridge(np);
+
+	of_node_put(np);
+	ppc_md.pci_map_irq = NULL;
+	ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
+	ppc_md.pcibios_fixup_bus = NULL;
+#endif
+
+#ifdef  CONFIG_ROOT_NFS
+	ROOT_DEV = Root_NFS;
+#else
+	ROOT_DEV = Root_HDA1;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc82xx_ads_setup_arch(), finish", 0);
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mpc82xx_ads_probe(void)
+{
+	/* We always match for now, eventually we should look at
+	 * the flat dev tree to ensure this is the board we are
+	 * supposed to run on
+	 */
+	return 1;
+}
+
+#define RMR_CSRE 0x00000001
+static void m82xx_restart(char *cmd)
+{
+	__volatile__ unsigned char dummy;
+
+	local_irq_disable();
+	((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
+
+	/* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
+	mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
+	dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
+	printk("Restart failed\n");
+	while (1) ;
+}
+
+static void m82xx_halt(void)
+{
+	local_irq_disable();
+	while (1) ;
+}
+
+define_machine(mpc82xx_ads)
+{
+	.name = "MPC82xx ADS",
+	.probe = mpc82xx_ads_probe,
+	.setup_arch =    mpc82xx_ads_setup_arch,
+	.init_IRQ =    mpc82xx_ads_pic_init,
+	.show_cpuinfo =    mpc82xx_ads_show_cpuinfo,
+	.get_irq =    cpm2_get_irq,
+	.calibrate_decr =    m82xx_calibrate_decr,
+	.restart = m82xx_restart,.halt = m82xx_halt,
+};
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h b/arch/powerpc/platforms/82xx/pq2ads.h
new file mode 100644
index 0000000..a734821
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/pq2ads.h
@@ -0,0 +1,67 @@
+/*
+ * PQ2/mpc8260 board-specific stuff
+ *
+ * A collection of structures, addresses, and values associated with
+ * the Freescale MPC8260ADS/MPC8266ADS-PCI boards.
+ * Copied from the RPX-Classic and SBS8260 stuff.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Originally written by Dan Malek for Motorola MPC8260 family
+ *
+ * Copyright (c) 2001 Dan Malek <dan@embeddedalley.com>
+ * Copyright (c) 2006 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 __MACH_ADS8260_DEFS
+#define __MACH_ADS8260_DEFS
+
+#include <linux/config.h>
+
+#include <asm/ppcboot.h>
+
+/* For our show_cpuinfo hooks. */
+#define CPUINFO_VENDOR		"Freescale Semiconductor"
+#define CPUINFO_MACHINE		"PQ2 ADS PowerPC"
+
+/* Backword-compatibility stuff for the drivers */
+#define CPM_MAP_ADDR		((uint)0xf0000000)
+#define CPM_IRQ_OFFSET 0
+
+/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
+ * only on word boundaries.
+ * Not all are used (yet), or are interesting to us (yet).
+ */
+
+/* Things of interest in the CSR.
+ */
+#define BCSR0_LED0		((uint)0x02000000)      /* 0 == on */
+#define BCSR0_LED1		((uint)0x01000000)      /* 0 == on */
+#define BCSR1_FETHIEN		((uint)0x08000000)      /* 0 == enable*/
+#define BCSR1_FETH_RST		((uint)0x04000000)      /* 0 == reset */
+#define BCSR1_RS232_EN1		((uint)0x02000000)      /* 0 ==enable */
+#define BCSR1_RS232_EN2		((uint)0x01000000)      /* 0 ==enable */
+#define BCSR3_FETHIEN2		((uint)0x10000000)      /* 0 == enable*/
+#define BCSR3_FETH2_RS		((uint)0x80000000)      /* 0 == reset */
+
+/* cpm serial driver works with constants below */
+
+#define SIU_INT_SMC1		((uint)0x04+CPM_IRQ_OFFSET)
+#define SIU_INT_SMC2i		((uint)0x05+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC1		((uint)0x28+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC2		((uint)0x29+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC3		((uint)0x2a+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC4		((uint)0x2b+CPM_IRQ_OFFSET)
+
+void m82xx_pci_init_irq(void);
+void mpc82xx_ads_show_cpuinfo(struct seq_file*);
+void m82xx_calibrate_decr(void);
+
+#endif /* __MACH_ADS8260_DEFS */
+#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 5fe7b7f..0975e94 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -5,6 +5,13 @@
 	prompt "Machine Type"
 	default MPC834x_SYS
 
+config MPC832x_MDS
+	bool "Freescale MPC832x MDS"
+	select DEFAULT_UIMAGE
+	select QUICC_ENGINE
+	help
+	  This option enables support for the MPC832x MDS evaluation board.
+
 config MPC834x_SYS
 	bool "Freescale MPC834x SYS"
 	select DEFAULT_UIMAGE
@@ -27,6 +34,12 @@
 
 endchoice
 
+config PPC_MPC832x
+	bool
+	select PPC_UDBG_16550
+	select PPC_INDIRECT_PCI
+	default y if MPC832x_MDS
+
 config MPC834x
 	bool
 	select PPC_UDBG_16550
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
new file mode 100644
index 0000000..54dea9d4
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Description:
+ * MPC832xE MDS board specific routines.
+ *
+ * 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/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/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/qe.h>
+#include <asm/qe_ic.h>
+
+#include "mpc83xx.h"
+#include "mpc832x_mds.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+static u8 *bcsr_regs = NULL;
+
+u8 *get_bcsr(void)
+{
+	return bcsr_regs;
+}
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init mpc832x_sys_setup_arch(void)
+{
+	struct device_node *np;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc832x_sys_setup_arch()", 0);
+
+	np = of_find_node_by_type(NULL, "cpu");
+	if (np != 0) {
+		unsigned int *fp =
+		    (int *)get_property(np, "clock-frequency", NULL);
+		if (fp != 0)
+			loops_per_jiffy = *fp / HZ;
+		else
+			loops_per_jiffy = 50000000 / HZ;
+		of_node_put(np);
+	}
+
+	/* Map BCSR area */
+	np = of_find_node_by_name(NULL, "bcsr");
+	if (np != 0) {
+		struct resource res;
+
+		of_address_to_resource(np, 0, &res);
+		bcsr_regs = ioremap(res.start, res.end - res.start +1);
+		of_node_put(np);
+	}
+
+#ifdef CONFIG_PCI
+	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+		add_bridge(np);
+
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
+#endif
+
+#ifdef CONFIG_QUICC_ENGINE
+	qe_reset();
+
+	if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
+		par_io_init(np);
+		of_node_put(np);
+
+		for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
+			par_io_of_config(np);
+	}
+
+	if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
+			!= NULL){
+		/* Reset the Ethernet PHY */
+		bcsr_regs[9] &= ~0x20;
+		udelay(1000);
+		bcsr_regs[9] |= 0x20;
+		iounmap(bcsr_regs);
+		of_node_put(np);
+	}
+
+#endif				/* CONFIG_QUICC_ENGINE */
+
+#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
+}
+
+void __init mpc832x_sys_init_IRQ(void)
+{
+
+	struct device_node *np;
+
+	np = of_find_node_by_type(NULL, "ipic");
+	if (!np)
+		return;
+
+	ipic_init(np, 0);
+
+	/* Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	ipic_set_default_priority();
+	of_node_put(np);
+
+#ifdef CONFIG_QUICC_ENGINE
+	np = of_find_node_by_type(NULL, "qeic");
+	if (!np)
+		return;
+
+	qe_ic_init(np, 0);
+	of_node_put(np);
+#endif				/* CONFIG_QUICC_ENGINE */
+}
+
+#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
+extern ulong ds1374_get_rtc_time(void);
+extern int ds1374_set_rtc_time(ulong);
+
+static int __init mpc832x_rtc_hookup(void)
+{
+	struct timespec tv;
+
+	ppc_md.get_rtc_time = ds1374_get_rtc_time;
+	ppc_md.set_rtc_time = ds1374_set_rtc_time;
+
+	tv.tv_nsec = 0;
+	tv.tv_sec = (ppc_md.get_rtc_time) ();
+	do_settimeofday(&tv);
+
+	return 0;
+}
+
+late_initcall(mpc832x_rtc_hookup);
+#endif
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init mpc832x_sys_probe(void)
+{
+	char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
+					  "model", NULL);
+
+	if (model == NULL)
+		return 0;
+	if (strcmp(model, "MPC8323EMDS"))
+		return 0;
+
+	DBG("%s found\n", model);
+
+	return 1;
+}
+
+define_machine(mpc832x_mds) {
+	.name 		= "MPC832x MDS",
+	.probe 		= mpc832x_sys_probe,
+	.setup_arch 	= mpc832x_sys_setup_arch,
+	.init_IRQ 	= mpc832x_sys_init_IRQ,
+	.get_irq 	= ipic_get_irq,
+	.restart 	= mpc83xx_restart,
+	.time_init 	= mpc83xx_time_init,
+	.calibrate_decr	= generic_calibrate_decr,
+	.progress 	= udbg_progress,
+};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.h b/arch/powerpc/platforms/83xx/mpc832x_mds.h
new file mode 100644
index 0000000..a495889
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Description:
+ * MPC832x MDS board specific header.
+ *
+ * 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 __MACH_MPC832x_MDS_H__
+#define __MACH_MPC832x_MDS_H__
+
+extern u8 *get_bcsr(void);
+
+#endif				/* __MACH_MPC832x_MDS_H__ */
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 969fbb6..8c676d7 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -109,6 +109,10 @@
 	return 1;
 }
 
+#ifdef CONFIG_RTC_CLASS
+late_initcall(rtc_class_hookup);
+#endif
+
 define_machine(mpc834x_itx) {
 	.name			= "MPC834x ITX",
 	.probe			= mpc834x_itx_probe,
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.h b/arch/powerpc/platforms/83xx/mpc834x_sys.h
index fedecb7..7d5bbef 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.h
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.h
@@ -1,5 +1,5 @@
 /*
- * arch/powerppc/platforms/83xx/mpc834x_sys.h
+ * arch/powerpc/platforms/83xx/mpc834x_sys.h
  *
  * MPC834X SYS common board definitions
  *
diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
new file mode 100644
index 0000000..c019190
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Li Yang <LeoLi@freescale.com>
+ *	   Yin Olivia <Hong-hua.Yin@freescale.com>
+ *
+ * Description:
+ * MPC8360E MDS PB board specific routines.
+ *
+ * Changelog:
+ * Jun 21, 2006	Initial version
+ *
+ * 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/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/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/qe.h>
+#include <asm/qe_ic.h>
+
+#include "mpc83xx.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+static u8 *bcsr_regs = NULL;
+
+u8 *get_bcsr(void)
+{
+	return bcsr_regs;
+}
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init mpc8360_sys_setup_arch(void)
+{
+	struct device_node *np;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc8360_sys_setup_arch()", 0);
+
+	np = of_find_node_by_type(NULL, "cpu");
+	if (np != 0) {
+		const unsigned int *fp =
+		    get_property(np, "clock-frequency", NULL);
+		if (fp != 0)
+			loops_per_jiffy = *fp / HZ;
+		else
+			loops_per_jiffy = 50000000 / HZ;
+		of_node_put(np);
+	}
+
+	/* Map BCSR area */
+	np = of_find_node_by_name(NULL, "bcsr");
+	if (np != 0) {
+		struct resource res;
+
+		of_address_to_resource(np, 0, &res);
+		bcsr_regs = ioremap(res.start, res.end - res.start +1);
+		of_node_put(np);
+	}
+
+#ifdef CONFIG_PCI
+	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+		add_bridge(np);
+
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
+#endif
+
+#ifdef CONFIG_QUICC_ENGINE
+	qe_reset();
+
+	if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
+		par_io_init(np);
+		of_node_put(np);
+
+		for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
+			par_io_of_config(np);
+	}
+
+	if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
+			!= NULL){
+		/* Reset the Ethernet PHY */
+		bcsr_regs[9] &= ~0x20;
+		udelay(1000);
+		bcsr_regs[9] |= 0x20;
+		iounmap(bcsr_regs);
+		of_node_put(np);
+	}
+
+#endif				/* CONFIG_QUICC_ENGINE */
+
+#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
+}
+
+void __init mpc8360_sys_init_IRQ(void)
+{
+
+	struct device_node *np;
+
+	np = of_find_node_by_type(NULL, "ipic");
+	if (!np)
+		return;
+
+	ipic_init(np, 0);
+
+	/* Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	ipic_set_default_priority();
+	of_node_put(np);
+
+#ifdef CONFIG_QUICC_ENGINE
+	np = of_find_node_by_type(NULL, "qeic");
+	if (!np)
+		return;
+
+	qe_ic_init(np, 0);
+	of_node_put(np);
+#endif				/* CONFIG_QUICC_ENGINE */
+}
+
+#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
+extern ulong ds1374_get_rtc_time(void);
+extern int ds1374_set_rtc_time(ulong);
+
+static int __init mpc8360_rtc_hookup(void)
+{
+	struct timespec tv;
+
+	ppc_md.get_rtc_time = ds1374_get_rtc_time;
+	ppc_md.set_rtc_time = ds1374_set_rtc_time;
+
+	tv.tv_nsec = 0;
+	tv.tv_sec = (ppc_md.get_rtc_time) ();
+	do_settimeofday(&tv);
+
+	return 0;
+}
+
+late_initcall(mpc8360_rtc_hookup);
+#endif
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init mpc8360_sys_probe(void)
+{
+	char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
+					  "model", NULL);
+	if (model == NULL)
+		return 0;
+	if (strcmp(model, "MPC8360EPB"))
+		return 0;
+
+	DBG("MPC8360EMDS-PB found\n");
+
+	return 1;
+}
+
+define_machine(mpc8360_sys) {
+	.name 		= "MPC8360E PB",
+	.probe 		= mpc8360_sys_probe,
+	.setup_arch 	= mpc8360_sys_setup_arch,
+	.init_IRQ 	= mpc8360_sys_init_IRQ,
+	.get_irq 	= ipic_get_irq,
+	.restart 	= mpc83xx_restart,
+	.time_init 	= mpc83xx_time_init,
+	.calibrate_decr	= generic_calibrate_decr,
+	.progress 	= udbg_progress,
+};
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index c3268d9..0584f3c 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -11,6 +11,12 @@
 	help
 	  This option enables support for the MPC 8540 ADS board
 
+config MPC8560_ADS
+	bool "Freescale MPC8560 ADS"
+	select DEFAULT_UIMAGE
+	help
+	  This option enables support for the MPC 8560 ADS board
+
 config MPC85xx_CDS
 	bool "Freescale MPC85xx CDS"
 	select DEFAULT_UIMAGE
@@ -25,6 +31,11 @@
 	select PPC_INDIRECT_PCI
 	default y if MPC8540_ADS || MPC85xx_CDS
 
+config MPC8560
+	bool
+	select PPC_INDIRECT_PCI
+	default y if MPC8560_ADS
+
 config PPC_INDIRECT_PCI_BE
 	bool
 	depends on PPC_85xx
@@ -34,4 +45,14 @@
 	bool
 	default y
 
+config CPM2
+	bool
+	depends on MPC8560
+	default y
+	help
+	  The CPM2 (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 CPM2 coprocessor
+	  on it.
+
 endmenu
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 7615aa5..282f5d0 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -3,4 +3,5 @@
 #
 obj-$(CONFIG_PPC_85xx)	+= misc.o pci.o
 obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
+obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
 obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
diff --git a/arch/powerpc/platforms/85xx/mpc8540_ads.h b/arch/powerpc/platforms/85xx/mpc8540_ads.h
index c0d56d2..da82f4c 100644
--- a/arch/powerpc/platforms/85xx/mpc8540_ads.h
+++ b/arch/powerpc/platforms/85xx/mpc8540_ads.h
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/85xx/mpc8540_ads.h
+ * arch/powerpc/platforms/85xx/mpc8540_ads.h
  *
  * MPC8540ADS board definitions
  *
diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h
index b44db62..83415db 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx.h
+++ b/arch/powerpc/platforms/85xx/mpc85xx.h
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/85xx/mpc85xx.h
+ * arch/powerpc/platforms/85xx/mpc85xx.h
  *
  * MPC85xx soc definitions/function decls
  *
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index cae6b73..28070e7 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -32,6 +32,13 @@
 #include <sysdev/fsl_soc.h>
 #include "mpc85xx.h"
 
+#ifdef CONFIG_CPM2
+#include <linux/fs_enet_pd.h>
+#include <asm/cpm2.h>
+#include <sysdev/cpm2_pic.h>
+#include <asm/fs_pd.h>
+#endif
+
 #ifndef CONFIG_PCI
 unsigned long isa_io_base = 0;
 unsigned long isa_mem_base = 0;
@@ -57,12 +64,29 @@
 }
 #endif /* CONFIG_PCI */
 
+#ifdef CONFIG_CPM2
+
+static void cpm2_cascade(unsigned int irq, struct irq_desc *desc,
+			 struct pt_regs *regs)
+{
+	int cascade_irq;
+
+	while ((cascade_irq = cpm2_get_irq(regs)) >= 0) {
+		generic_handle_irq(cascade_irq, regs);
+	}
+	desc->chip->eoi(irq);
+}
+
+#endif /* CONFIG_CPM2 */
 
 void __init mpc85xx_ads_pic_init(void)
 {
 	struct mpic *mpic;
 	struct resource r;
 	struct device_node *np = NULL;
+#ifdef CONFIG_CPM2
+	int irq;
+#endif
 
 	np = of_find_node_by_type(np, "open-pic");
 
@@ -104,11 +128,103 @@
 	mpic_assign_isu(mpic, 14, r.start + 0x10100);
 
 	mpic_init(mpic);
+
+#ifdef CONFIG_CPM2
+	/* Setup CPM2 PIC */
+	np = of_find_node_by_type(NULL, "cpm-pic");
+	if (np == NULL) {
+		printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
+                return;
+	}
+	irq = irq_of_parse_and_map(np, 0);
+
+	cpm2_pic_init(np);
+	set_irq_chained_handler(irq, cpm2_cascade);
+#endif
 }
 
 /*
  * Setup the architecture
  */
+#ifdef CONFIG_CPM2
+void init_fcc_ioports(struct fs_platform_info *fpi)
+{
+	struct io_port *io = cpm2_map(im_ioport);
+	int fcc_no = fs_get_fcc_index(fpi->fs_no);
+	int target;
+	u32 tempval;
+
+	switch(fcc_no) {
+	case 1:
+		tempval = in_be32(&io->iop_pdirb);
+		tempval &= ~PB2_DIRB0;
+		tempval |= PB2_DIRB1;
+		out_be32(&io->iop_pdirb, tempval);
+
+		tempval = in_be32(&io->iop_psorb);
+		tempval &= ~PB2_PSORB0;
+		tempval |= PB2_PSORB1;
+		out_be32(&io->iop_psorb, tempval);
+
+		tempval = in_be32(&io->iop_pparb);
+		tempval |= (PB2_DIRB0 | PB2_DIRB1);
+		out_be32(&io->iop_pparb, tempval);
+
+		target = CPM_CLK_FCC2;
+		break;
+	case 2:
+		tempval = in_be32(&io->iop_pdirb);
+		tempval &= ~PB3_DIRB0;
+		tempval |= PB3_DIRB1;
+		out_be32(&io->iop_pdirb, tempval);
+
+		tempval = in_be32(&io->iop_psorb);
+		tempval &= ~PB3_PSORB0;
+		tempval |= PB3_PSORB1;
+		out_be32(&io->iop_psorb, tempval);
+
+		tempval = in_be32(&io->iop_pparb);
+		tempval |= (PB3_DIRB0 | PB3_DIRB1);
+		out_be32(&io->iop_pparb, tempval);
+
+		tempval = in_be32(&io->iop_pdirc);
+		tempval |= PC3_DIRC1;
+		out_be32(&io->iop_pdirc, tempval);
+
+		tempval = in_be32(&io->iop_pparc);
+		tempval |= PC3_DIRC1;
+		out_be32(&io->iop_pparc, tempval);
+
+		target = CPM_CLK_FCC3;
+		break;
+	default:
+		printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
+		return;
+	}
+
+	/* Port C has clocks......  */
+	tempval = in_be32(&io->iop_psorc);
+	tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+	out_be32(&io->iop_psorc, tempval);
+
+	tempval = in_be32(&io->iop_pdirc);
+	tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+	out_be32(&io->iop_pdirc, tempval);
+	tempval = in_be32(&io->iop_pparc);
+	tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+	out_be32(&io->iop_pparc, tempval);
+
+	cpm2_unmap(io);
+
+	/* Configure Serial Interface clock routing.
+	 * First,  clear FCC bits to zero,
+	 * then set the ones we want.
+	 */
+	cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX);
+	cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX);
+}
+#endif
+
 static void __init mpc85xx_ads_setup_arch(void)
 {
 	struct device_node *cpu;
@@ -131,6 +247,10 @@
 		of_node_put(cpu);
 	}
 
+#ifdef CONFIG_CPM2
+	cpm2_reset();
+#endif
+
 #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.h b/arch/powerpc/platforms/85xx/mpc85xx_ads.h
new file mode 100644
index 0000000..effcbf7
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.h
@@ -0,0 +1,61 @@
+/*
+ * MPC85xx ADS board definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor Inc.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.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 __MACH_MPC85XXADS_H
+#define __MACH_MPC85XXADS_H
+
+#include <linux/config.h>
+#include <linux/initrd.h>
+#include <sysdev/fsl_soc.h>
+
+#define BCSR_ADDR		((uint)0xf8000000)
+#define BCSR_SIZE		((uint)(32 * 1024))
+
+#ifdef CONFIG_CPM2
+
+#define MPC85xx_CPM_OFFSET	(0x80000)
+
+#define CPM_MAP_ADDR		(get_immrbase() + MPC85xx_CPM_OFFSET)
+#define CPM_IRQ_OFFSET		60
+
+#define SIU_INT_SMC1		((uint)0x04+CPM_IRQ_OFFSET)
+#define SIU_INT_SMC2		((uint)0x05+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC1		((uint)0x28+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC2		((uint)0x29+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC3		((uint)0x2a+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC4		((uint)0x2b+CPM_IRQ_OFFSET)
+
+/* FCC1 Clock Source Configuration.  These can be
+ * redefined in the board specific file.
+ *    Can only choose from CLK9-12 */
+#define F1_RXCLK       12
+#define F1_TXCLK       11
+
+/* FCC2 Clock Source Configuration.  These can be
+ * redefined in the board specific file.
+ *    Can only choose from CLK13-16 */
+#define F2_RXCLK       13
+#define F2_TXCLK       14
+
+/* FCC3 Clock Source Configuration.  These can be
+ * redefined in the board specific file.
+ *    Can only choose from CLK13-16 */
+#define F3_RXCLK       15
+#define F3_TXCLK       16
+
+#endif	/* CONFIG_CPM2 */
+#endif	/* __MACH_MPC85XXADS_H */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.h b/arch/powerpc/platforms/85xx/mpc85xx_cds.h
index 671f54f..b251c9f 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.h
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.h
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+ * arch/powerpc/platforms/85xx/mpc85xx_cds.h
  *
  * MPC85xx CDS board definitions
  *
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 6b57a47..6cc59e0 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -21,6 +21,12 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * TODO:
+ * - Fix various assumptions related to HW CPU numbers vs. linux CPU numbers
+ *   vs node numbers in the setup code
+ * - Implement proper handling of maxcpus=1/2 (that is, routing of irqs from
+ *   a non-active node to the active node)
  */
 
 #include <linux/interrupt.h>
@@ -44,24 +50,25 @@
 	u8 target_id;
 	u8 eoi_stack[16];
 	int eoi_ptr;
-	struct irq_host *host;
+	struct device_node *node;
 };
 
 static DEFINE_PER_CPU(struct iic, iic);
 #define IIC_NODE_COUNT	2
-static struct irq_host *iic_hosts[IIC_NODE_COUNT];
+static struct irq_host *iic_host;
 
 /* Convert between "pending" bits and hw irq number */
 static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
 {
 	unsigned char unit = bits.source & 0xf;
+	unsigned char node = bits.source >> 4;
+	unsigned char class = bits.class & 3;
 
+	/* Decode IPIs */
 	if (bits.flags & CBE_IIC_IRQ_IPI)
-		return IIC_IRQ_IPI0 | (bits.prio >> 4);
-	else if (bits.class <= 3)
-		return (bits.class << 4) | unit;
+		return IIC_IRQ_TYPE_IPI | (bits.prio >> 4);
 	else
-		return IIC_IRQ_INVALID;
+		return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
 }
 
 static void iic_mask(unsigned int irq)
@@ -86,21 +93,70 @@
 	.eoi = iic_eoi,
 };
 
+
+static void iic_ioexc_eoi(unsigned int irq)
+{
+}
+
+static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc,
+			    struct pt_regs *regs)
+{
+	struct cbe_iic_regs *node_iic = desc->handler_data;
+	unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
+	unsigned long bits, ack;
+	int cascade;
+
+	for (;;) {
+		bits = in_be64(&node_iic->iic_is);
+		if (bits == 0)
+			break;
+		/* pre-ack edge interrupts */
+		ack = bits & IIC_ISR_EDGE_MASK;
+		if (ack)
+			out_be64(&node_iic->iic_is, ack);
+		/* handle them */
+		for (cascade = 63; cascade >= 0; cascade--)
+			if (bits & (0x8000000000000000UL >> cascade)) {
+				unsigned int cirq =
+					irq_linear_revmap(iic_host,
+							  base | cascade);
+				if (cirq != NO_IRQ)
+					generic_handle_irq(cirq, regs);
+			}
+		/* post-ack level interrupts */
+		ack = bits & ~IIC_ISR_EDGE_MASK;
+		if (ack)
+			out_be64(&node_iic->iic_is, ack);
+	}
+	desc->chip->eoi(irq);
+}
+
+
+static struct irq_chip iic_ioexc_chip = {
+	.typename = " CELL-IOEX",
+	.mask = iic_mask,
+	.unmask = iic_unmask,
+	.eoi = iic_ioexc_eoi,
+};
+
 /* Get an IRQ number from the pending state register of the IIC */
 static unsigned int iic_get_irq(struct pt_regs *regs)
 {
 	struct cbe_iic_pending_bits pending;
 	struct iic *iic;
+	unsigned int virq;
 
 	iic = &__get_cpu_var(iic);
 	*(unsigned long *) &pending =
 		in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
+	if (!(pending.flags & CBE_IIC_IRQ_VALID))
+		return NO_IRQ;
+	virq = irq_linear_revmap(iic_host, iic_pending_to_hwnum(pending));
+	if (virq == NO_IRQ)
+		return NO_IRQ;
 	iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
 	BUG_ON(iic->eoi_ptr > 15);
-	if (pending.flags & CBE_IIC_IRQ_VALID)
-		return irq_linear_revmap(iic->host,
-					 iic_pending_to_hwnum(pending));
-	return NO_IRQ;
+	return virq;
 }
 
 #ifdef CONFIG_SMP
@@ -108,12 +164,7 @@
 /* Use the highest interrupt priorities for IPI */
 static inline int iic_ipi_to_irq(int ipi)
 {
-	return IIC_IRQ_IPI0 + IIC_NUM_IPIS - 1 - ipi;
-}
-
-static inline int iic_irq_to_ipi(int irq)
-{
-	return IIC_NUM_IPIS - 1 - (irq - IIC_IRQ_IPI0);
+	return IIC_IRQ_TYPE_IPI + 0xf - ipi;
 }
 
 void iic_setup_cpu(void)
@@ -123,7 +174,7 @@
 
 void iic_cause_IPI(int cpu, int mesg)
 {
-	out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4);
+	out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
 }
 
 u8 iic_get_target_id(int cpu)
@@ -134,9 +185,7 @@
 
 struct irq_host *iic_get_irq_host(int node)
 {
-	if (node < 0 || node >= IIC_NODE_COUNT)
-		return NULL;
-	return iic_hosts[node];
+	return iic_host;
 }
 EXPORT_SYMBOL_GPL(iic_get_irq_host);
 
@@ -149,34 +198,20 @@
 
 	return IRQ_HANDLED;
 }
-
 static void iic_request_ipi(int ipi, const char *name)
 {
-	int node, virq;
+	int virq;
 
-	for (node = 0; node < IIC_NODE_COUNT; node++) {
-		char *rname;
-		if (iic_hosts[node] == NULL)
-			continue;
-		virq = irq_create_mapping(iic_hosts[node],
-					  iic_ipi_to_irq(ipi));
-		if (virq == NO_IRQ) {
-			printk(KERN_ERR
-			       "iic: failed to map IPI %s on node %d\n",
-			       name, node);
-			continue;
-		}
-		rname = kzalloc(strlen(name) + 16, GFP_KERNEL);
-		if (rname)
-			sprintf(rname, "%s node %d", name, node);
-		else
-			rname = (char *)name;
-		if (request_irq(virq, iic_ipi_action, IRQF_DISABLED,
-				rname, (void *)(long)ipi))
-			printk(KERN_ERR
-			       "iic: failed to request IPI %s on node %d\n",
-			       name, node);
+	virq = irq_create_mapping(iic_host, iic_ipi_to_irq(ipi));
+	if (virq == NO_IRQ) {
+		printk(KERN_ERR
+		       "iic: failed to map IPI %s\n", name);
+		return;
 	}
+	if (request_irq(virq, iic_ipi_action, IRQF_DISABLED, name,
+			(void *)(long)ipi))
+		printk(KERN_ERR
+		       "iic: failed to request IPI %s\n", name);
 }
 
 void iic_request_IPIs(void)
@@ -193,16 +228,24 @@
 
 static int iic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return h->host_data != NULL && node == h->host_data;
+	return device_is_compatible(node,
+				    "IBM,CBEA-Internal-Interrupt-Controller");
 }
 
 static int iic_host_map(struct irq_host *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
-	if (hw < IIC_IRQ_IPI0)
-		set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
-	else
+	switch (hw & IIC_IRQ_TYPE_MASK) {
+	case IIC_IRQ_TYPE_IPI:
 		set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
+		break;
+	case IIC_IRQ_TYPE_IOEXC:
+		set_irq_chip_and_handler(virq, &iic_ioexc_chip,
+					 handle_fasteoi_irq);
+		break;
+	default:
+		set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
+	}
 	return 0;
 }
 
@@ -211,11 +254,39 @@
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
-	/* Currently, we don't translate anything. That needs to be fixed as
-	 * we get better defined device-trees. iic interrupts have to be
-	 * explicitely mapped by whoever needs them
-	 */
-	return -ENODEV;
+	unsigned int node, ext, unit, class;
+	const u32 *val;
+
+	if (!device_is_compatible(ct,
+				     "IBM,CBEA-Internal-Interrupt-Controller"))
+		return -ENODEV;
+	if (intsize != 1)
+		return -ENODEV;
+	val = get_property(ct, "#interrupt-cells", NULL);
+	if (val == NULL || *val != 1)
+		return -ENODEV;
+
+	node = intspec[0] >> 24;
+	ext = (intspec[0] >> 16) & 0xff;
+	class = (intspec[0] >> 8) & 0xff;
+	unit = intspec[0] & 0xff;
+
+	/* Check if node is in supported range */
+	if (node > 1)
+		return -EINVAL;
+
+	/* Build up interrupt number, special case for IO exceptions */
+	*out_hwirq = (node << IIC_IRQ_NODE_SHIFT);
+	if (unit == IIC_UNIT_IIC && class == 1)
+		*out_hwirq |= IIC_IRQ_TYPE_IOEXC | ext;
+	else
+		*out_hwirq |= IIC_IRQ_TYPE_NORMAL |
+			(class << IIC_IRQ_CLASS_SHIFT) | unit;
+
+	/* Dummy flags, ignored by iic code */
+	*out_flags = IRQ_TYPE_EDGE_RISING;
+
+	return 0;
 }
 
 static struct irq_host_ops iic_host_ops = {
@@ -225,7 +296,7 @@
 };
 
 static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
-				struct irq_host *host)
+				struct device_node *node)
 {
 	/* XXX FIXME: should locate the linux CPU number from the HW cpu
 	 * number properly. We are lucky for now
@@ -237,19 +308,19 @@
 
 	iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe);
 	iic->eoi_stack[0] = 0xff;
-	iic->host = host;
+	iic->node = of_node_get(node);
 	out_be64(&iic->regs->prio, 0);
 
-	printk(KERN_INFO "IIC for CPU %d at %lx mapped to %p, target id 0x%x\n",
-	       hw_cpu, addr, iic->regs, iic->target_id);
+	printk(KERN_INFO "IIC for CPU %d target id 0x%x : %s\n",
+	       hw_cpu, iic->target_id, node->full_name);
 }
 
 static int __init setup_iic(void)
 {
 	struct device_node *dn;
 	struct resource r0, r1;
-	struct irq_host *host;
-	int found = 0;
+	unsigned int node, cascade, found = 0;
+	struct cbe_iic_regs *node_iic;
 	const u32 *np;
 
 	for (dn = NULL;
@@ -269,19 +340,33 @@
 			of_node_put(dn);
 			return -ENODEV;
 		}
-		host = NULL;
-		if (found < IIC_NODE_COUNT) {
-			host = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
-					      IIC_SOURCE_COUNT,
-					      &iic_host_ops,
-					      IIC_IRQ_INVALID);
-			iic_hosts[found] = host;
-			BUG_ON(iic_hosts[found] == NULL);
-			iic_hosts[found]->host_data = of_node_get(dn);
-			found++;
-		}
-		init_one_iic(np[0], r0.start, host);
-		init_one_iic(np[1], r1.start, host);
+		found++;
+		init_one_iic(np[0], r0.start, dn);
+		init_one_iic(np[1], r1.start, dn);
+
+		/* Setup cascade for IO exceptions. XXX cleanup tricks to get
+		 * node vs CPU etc...
+		 * Note that we configure the IIC_IRR here with a hard coded
+		 * priority of 1. We might want to improve that later.
+		 */
+		node = np[0] >> 1;
+		node_iic = cbe_get_cpu_iic_regs(np[0]);
+		cascade = node << IIC_IRQ_NODE_SHIFT;
+		cascade |= 1 << IIC_IRQ_CLASS_SHIFT;
+		cascade |= IIC_UNIT_IIC;
+		cascade = irq_create_mapping(iic_host, cascade);
+		if (cascade == NO_IRQ)
+			continue;
+		set_irq_data(cascade, node_iic);
+		set_irq_chained_handler(cascade , iic_ioexc_cascade);
+		out_be64(&node_iic->iic_ir,
+			 (1 << 12)		/* priority */ |
+			 (node << 4)		/* dest node */ |
+			 IIC_UNIT_THREAD_0	/* route them to thread 0 */);
+		/* Flush pending (make sure it triggers if there is
+		 * anything pending
+		 */
+		out_be64(&node_iic->iic_is, 0xfffffffffffffffful);
 	}
 
 	if (found)
@@ -292,6 +377,12 @@
 
 void __init iic_init_IRQ(void)
 {
+	/* Setup an irq host data structure */
+	iic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
+				  &iic_host_ops, IIC_IRQ_INVALID);
+	BUG_ON(iic_host == NULL);
+	irq_set_default_host(iic_host);
+
 	/* Discover and initialize iics */
 	if (setup_iic() < 0)
 		panic("IIC: Failed to initialize !\n");
diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h
index 5560a92..9ba1d3c 100644
--- a/arch/powerpc/platforms/cell/interrupt.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -2,48 +2,76 @@
 #define ASM_CELL_PIC_H
 #ifdef __KERNEL__
 /*
- * Mapping of IIC pending bits into per-node
- * interrupt numbers.
+ * Mapping of IIC pending bits into per-node interrupt numbers.
  *
- * IRQ     FF CC SS PP   FF CC SS PP	Description
+ * Interrupt numbers are in the range 0...0x1ff where the top bit
+ * (0x100) represent the source node. Only 2 nodes are supported with
+ * the current code though it's trivial to extend that if necessary using
+ * higher level bits
  *
- * 00-3f   80 02 +0 00 - 80 02 +0 3f	South Bridge
- * 00-3f   80 02 +b 00 - 80 02 +b 3f	South Bridge
- * 41-4a   80 00 +1 ** - 80 00 +a **	SPU Class 0
- * 51-5a   80 01 +1 ** - 80 01 +a **	SPU Class 1
- * 61-6a   80 02 +1 ** - 80 02 +a **	SPU Class 2
- * 70-7f   C0 ** ** 00 - C0 ** ** 0f	IPI
+ * The bottom 8 bits are split into 2 type bits and 6 data bits that
+ * depend on the type:
  *
- *    F flags
- *    C class
- *    S source
- *    P Priority
- *    + node number
- *    * don't care
+ * 00 (0x00 | data) : normal interrupt. data is (class << 4) | source
+ * 01 (0x40 | data) : IO exception. data is the exception number as
+ *                    defined by bit numbers in IIC_SR
+ * 10 (0x80 | data) : IPI. data is the IPI number (obtained from the priority)
+ *                    and node is always 0 (IPIs are per-cpu, their source is
+ *                    not relevant)
+ * 11 (0xc0 | data) : reserved
  *
- * A node consists of a Cell Broadband Engine and an optional
- * south bridge device providing a maximum of 64 IRQs.
- * The south bridge may be connected to either IOIF0
- * or IOIF1.
- * Each SPE is represented as three IRQ lines, one per
- * interrupt class.
- * 16 IRQ numbers are reserved for inter processor
- * interruptions, although these are only used in the
- * range of the first node.
+ * In addition, interrupt number 0x80000000 is defined as always invalid
+ * (that is the node field is expected to never extend to move than 23 bits)
  *
- * This scheme needs 128 IRQ numbers per BIF node ID,
- * which means that with the total of 512 lines
- * available, we can have a maximum of four nodes.
  */
 
 enum {
-	IIC_IRQ_INVALID		= 0xff,
-	IIC_IRQ_MAX		= 0x3f,
-	IIC_IRQ_EXT_IOIF0	= 0x20,
-	IIC_IRQ_EXT_IOIF1	= 0x2b,
-	IIC_IRQ_IPI0		= 0x40,
-	IIC_NUM_IPIS    	= 0x10, /* IRQs reserved for IPI */
-	IIC_SOURCE_COUNT	= 0x50,
+	IIC_IRQ_INVALID		= 0x80000000u,
+	IIC_IRQ_NODE_MASK	= 0x100,
+	IIC_IRQ_NODE_SHIFT	= 8,
+	IIC_IRQ_MAX		= 0x1ff,
+	IIC_IRQ_TYPE_MASK	= 0xc0,
+	IIC_IRQ_TYPE_NORMAL	= 0x00,
+	IIC_IRQ_TYPE_IOEXC	= 0x40,
+	IIC_IRQ_TYPE_IPI	= 0x80,
+	IIC_IRQ_CLASS_SHIFT	= 4,
+	IIC_IRQ_CLASS_0		= 0x00,
+	IIC_IRQ_CLASS_1		= 0x10,
+	IIC_IRQ_CLASS_2		= 0x20,
+	IIC_SOURCE_COUNT	= 0x200,
+
+	/* Here are defined the various source/dest units. Avoid using those
+	 * definitions if you can, they are mostly here for reference
+	 */
+	IIC_UNIT_SPU_0		= 0x4,
+	IIC_UNIT_SPU_1		= 0x7,
+	IIC_UNIT_SPU_2		= 0x3,
+	IIC_UNIT_SPU_3		= 0x8,
+	IIC_UNIT_SPU_4		= 0x2,
+	IIC_UNIT_SPU_5		= 0x9,
+	IIC_UNIT_SPU_6		= 0x1,
+	IIC_UNIT_SPU_7		= 0xa,
+	IIC_UNIT_IOC_0		= 0x0,
+	IIC_UNIT_IOC_1		= 0xb,
+	IIC_UNIT_THREAD_0	= 0xe, /* target only */
+	IIC_UNIT_THREAD_1	= 0xf, /* target only */
+	IIC_UNIT_IIC		= 0xe, /* source only (IO exceptions) */
+
+	/* Base numbers for the external interrupts */
+	IIC_IRQ_EXT_IOIF0	=
+		IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_0,
+	IIC_IRQ_EXT_IOIF1	=
+		IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_1,
+
+	/* Base numbers for the IIC_ISR interrupts */
+	IIC_IRQ_IOEX_TMI	= IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 63,
+	IIC_IRQ_IOEX_PMI	= IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 62,
+	IIC_IRQ_IOEX_ATI	= IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 61,
+	IIC_IRQ_IOEX_MATBFI	= IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 60,
+	IIC_IRQ_IOEX_ELDI	= IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 59,
+
+	/* Which bits in IIC_ISR are edge sensitive */
+	IIC_ISR_EDGE_MASK	= 0x4ul,
 };
 
 extern void iic_init_IRQ(void);
@@ -52,7 +80,6 @@
 extern void iic_setup_cpu(void);
 
 extern u8 iic_get_target_id(int cpu);
-extern struct irq_host *iic_get_irq_host(int node);
 
 extern void spider_init_IRQ(void);
 
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 742a032..608b1eb 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -243,7 +243,6 @@
 	const u32 *imap, *tmp;
 	int imaplen, intsize, unit;
 	struct device_node *iic;
-	struct irq_host *iic_host;
 
 #if 0 /* Enable that when we have a way to retreive the node as well */
 	/* First, we check wether we have a real "interrupts" in the device
@@ -289,11 +288,11 @@
 	 * the iic host from the iic OF node, but that way I'm still compatible
 	 * with really really old old firmwares for which we don't have a node
 	 */
-	iic_host = iic_get_irq_host(pic->node_id);
-	if (iic_host == NULL)
-		return NO_IRQ;
 	/* Manufacture an IIC interrupt number of class 2 */
-	virq = irq_create_mapping(iic_host, 0x20 | unit);
+	virq = irq_create_mapping(NULL,
+				  (pic->node_id << IIC_IRQ_NODE_SHIFT) |
+				  (2 << IIC_IRQ_CLASS_SHIFT) |
+				  unit);
 	if (virq == NO_IRQ)
 		printk(KERN_ERR "spider_pic: failed to map cascade !");
 	return virq;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 3bd36d4..f786803 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -538,7 +538,7 @@
 
 	const void *p;
 	int proplen;
-	void* ret = NULL;
+	void __iomem *ret = NULL;
 	int err = 0;
 
 	p = get_property(n, name, &proplen);
@@ -562,30 +562,29 @@
 	iounmap(spu->priv2);
 	iounmap(spu->priv1);
 	iounmap(spu->problem);
-	iounmap((u8 __iomem *)spu->local_store);
+	iounmap((__force u8 __iomem *)spu->local_store);
 }
 
 /* This function shall be abstracted for HV platforms */
 static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
 {
-	struct irq_host *host;
 	unsigned int isrc;
 	const u32 *tmp;
 
-	host = iic_get_irq_host(spu->node);
-	if (host == NULL)
-		return -ENODEV;
-
-	/* Get the interrupt source from the device-tree */
+	/* Get the interrupt source unit from the device-tree */
 	tmp = get_property(np, "isrc", NULL);
 	if (!tmp)
 		return -ENODEV;
-	spu->isrc = isrc = tmp[0];
+	isrc = tmp[0];
+
+	/* Add the node number */
+	isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
+	spu->isrc = isrc;
 
 	/* Now map interrupts of all 3 classes */
-	spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc);
-	spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc);
-	spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc);
+	spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
+	spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc);
+	spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc);
 
 	/* Right now, we only fail if class 2 failed */
 	return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 58e794f..51fd197 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1342,7 +1342,7 @@
 
 	return num;
 }
-DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n")
+DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
 
 struct tree_descr spufs_dir_contents[] = {
 	{ "mem",  &spufs_mem_fops,  0666, },
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index c8670f5..efc452e 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -234,7 +234,7 @@
 
 static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
 {
-	struct spu_problem *prob = ctx->spu->problem;
+	struct spu_problem __iomem *prob = ctx->spu->problem;
 	int ret;
 
 	spin_lock_irq(&ctx->spu->register_lock);
@@ -263,7 +263,7 @@
 					struct mfc_dma_command *cmd)
 {
 	u32 status;
-	struct spu_problem *prob = ctx->spu->problem;
+	struct spu_problem __iomem *prob = ctx->spu->problem;
 
 	spin_lock_irq(&ctx->spu->register_lock);
 	out_be32(&prob->mfc_lsa_W, cmd->lsa);
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 1a2c2a5..1983b64 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -357,7 +357,7 @@
  */
 static int shutdown(void)
 {
-	int rc = kill_proc(1, SIGINT, 1);
+	int rc = kill_cad_pid(SIGINT, 1);
 
 	if (rc) {
 		printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), "
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 3eb1206..4aa165e 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -262,14 +262,6 @@
 	mf_display_src(0xC9000200);
 }
 
-void pcibios_fixup_bus(struct pci_bus *PciBus)
-{
-}
-
-void pcibios_fixup_resources(struct pci_dev *pdev)
-{
-}
-
 /*
  * Look down the chain to find the matching Device Device
  */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 7f19530..a0ff7ba 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -649,15 +649,21 @@
 void __init iSeries_init_IRQ(void) { }
 #endif
 
+/*
+ * iSeries has no legacy IO, anything calling this function has to
+ * fail or bad things will happen
+ */
+static int iseries_check_legacy_ioport(unsigned int baseport)
+{
+	return -ENODEV;
+}
+
 static int __init iseries_probe(void)
 {
 	unsigned long root = of_get_flat_dt_root();
 	if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
 		return 0;
 
-	powerpc_firmware_features |= FW_FEATURE_ISERIES;
-	powerpc_firmware_features |= FW_FEATURE_LPAR;
-
 	hpte_init_iSeries();
 
 	return 1;
@@ -680,6 +686,7 @@
 	.calibrate_decr	= generic_calibrate_decr,
 	.progress	= iSeries_progress,
 	.probe		= iseries_probe,
+	.check_legacy_ioport	= iseries_check_legacy_ioport,
 	/* XXX Implement enable_pmcs for iSeries */
 };
 
@@ -687,6 +694,9 @@
 {
 	unsigned long phys_mem_size;
 
+	powerpc_firmware_features |= FW_FEATURE_ISERIES;
+	powerpc_firmware_features |= FW_FEATURE_LPAR;
+
 	iSeries_fixup_klimit();
 
 	/*
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index c3aa46b..1b82761 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -96,14 +96,14 @@
 		1UL;
 }
 
-static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_agp_cfg_access(struct pci_controller* hose,
 				       u8 bus, u8 dev_fn, u8 offset)
 {
 	unsigned int caddr;
 
 	if (bus == hose->first_busno) {
 		if (dev_fn < (11 << 3))
-			return 0;
+			return NULL;
 		caddr = u3_agp_cfa0(dev_fn, offset);
 	} else
 		caddr = u3_agp_cfa1(bus, dev_fn, offset);
@@ -114,14 +114,14 @@
 	} while (in_le32(hose->cfg_addr) != caddr);
 
 	offset &= 0x07;
-	return ((unsigned long)hose->cfg_data) + offset;
+	return hose->cfg_data + offset;
 }
 
 static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
 			      int offset, int len, u32 *val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -136,13 +136,13 @@
 	 */
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)addr);
+		*val = in_8(addr);
 		break;
 	case 2:
-		*val = in_le16((u16 *)addr);
+		*val = in_le16(addr);
 		break;
 	default:
-		*val = in_le32((u32 *)addr);
+		*val = in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -152,7 +152,7 @@
 			       int offset, int len, u32 val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -167,16 +167,16 @@
 	 */
 	switch (len) {
 	case 1:
-		out_8((u8 *)addr, val);
-		(void) in_8((u8 *)addr);
+		out_8(addr, val);
+		(void) in_8(addr);
 		break;
 	case 2:
-		out_le16((u16 *)addr, val);
-		(void) in_le16((u16 *)addr);
+		out_le16(addr, val);
+		(void) in_le16(addr);
 		break;
 	default:
-		out_le32((u32 *)addr, val);
-		(void) in_le32((u32 *)addr);
+		out_le32(addr, val);
+		(void) in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -198,22 +198,22 @@
 	return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL;
 }
 
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
 				      u8 bus, u8 devfn, u8 offset)
 {
 	if (bus == hose->first_busno) {
 		if (PCI_SLOT(devfn) == 0)
-			return 0;
-		return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset);
+			return NULL;
+		return hose->cfg_data + u3_ht_cfa0(devfn, offset);
 	} else
-		return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset);
+		return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset);
 }
 
 static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
 			     int offset, int len, u32 *val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -232,13 +232,13 @@
 	 */
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)addr);
+		*val = in_8(addr);
 		break;
 	case 2:
-		*val = in_le16((u16 *)addr);
+		*val = in_le16(addr);
 		break;
 	default:
-		*val = in_le32((u32 *)addr);
+		*val = in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -248,7 +248,7 @@
 			      int offset, int len, u32 val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -266,16 +266,16 @@
 	 */
 	switch (len) {
 	case 1:
-		out_8((u8 *)addr, val);
-		(void) in_8((u8 *)addr);
+		out_8(addr, val);
+		(void) in_8(addr);
 		break;
 	case 2:
-		out_le16((u16 *)addr, val);
-		(void) in_le16((u16 *)addr);
+		out_le16(addr, val);
+		(void) in_le16(addr);
 		break;
 	default:
-		out_le32((u32 *)addr, val);
-		(void) in_le32((u32 *)addr);
+		out_le32(addr, val);
+		(void) in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -315,7 +315,7 @@
 	 * the reg address cell, we shall fix that by killing struct
 	 * reg_property and using some accessor functions instead
 	 */
-	hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+	hose->cfg_data = ioremap(0xf2000000, 0x02000000);
 
 	hose->first_busno = 0;
 	hose->last_busno = 0xef;
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index ce1a235..379db05 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -111,8 +111,6 @@
 	pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
 			  PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
 
-
-	/* Setup for 57600 8N1 */
 	if (ch == ch_a)
 		addr += 0x20;
 	sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
@@ -125,9 +123,21 @@
 		x = in_8(sccc);
 	out_8(sccc, 0x09);		/* reset A or B side */
 	out_8(sccc, 0xc0);
+
+	/* If SCC was the OF output port, read the BRG value, else
+	 * Setup for 57600 8N1
+	 */
+	if (ch_def != NULL) {
+		out_8(sccc, 13);
+		scc_inittab[1] = in_8(sccc);
+		out_8(sccc, 12);
+		scc_inittab[3] = in_8(sccc);
+	}
+
 	for (i = 0; i < sizeof(scc_inittab); ++i)
 		out_8(sccc, scc_inittab[i]);
 
+
 	udbg_putc = udbg_scc_putc;
 	udbg_getc = udbg_scc_getc;
 	udbg_getc_poll = udbg_scc_getc_poll;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 84bc8f7..3c2d63e 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -225,6 +225,7 @@
 
 void eeh_mark_slot (struct device_node *dn, int mode_flag)
 {
+	struct pci_dev *dev;
 	dn = find_device_pe (dn);
 
 	/* Back up one, since config addrs might be shared */
@@ -232,6 +233,12 @@
 		dn = dn->parent;
 
 	PCI_DN(dn)->eeh_mode |= mode_flag;
+
+	/* Mark the pci device too */
+	dev = PCI_DN(dn)->pcidev;
+	if (dev)
+		dev->error_state = pci_channel_io_frozen;
+
 	__eeh_mark_slot (dn->child, mode_flag);
 }
 
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8ed3621..f82b13e 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -180,7 +180,7 @@
 
 	cascade_irq = irq_of_parse_and_map(cascade, 0);
 	if (cascade == NO_IRQ) {
-		printk(KERN_ERR "xics: failed to map cascade interrupt");
+		printk(KERN_ERR "mpic: failed to map cascade interrupt");
 		return;
 	}
 
@@ -342,7 +342,7 @@
 {
 	/* Manually leave the kernel version on the panel. */
 	ppc_md.progress("Linux ppc64\n", 0);
-	ppc_md.progress(system_utsname.release, 0);
+	ppc_md.progress(init_utsname()->version, 0);
 
 	return 0;
 }
@@ -415,12 +415,6 @@
 			return -ENODEV;
 		of_node_put(np);
 		break;
-	case PARALLEL_BASE:
-		np = of_find_node_by_type(NULL, "parallel");
-		if (np == NULL)
-			return -ENODEV;
-		of_node_put(np);
-		break;
 	}
 	return 0;
 }
@@ -483,7 +477,6 @@
 { 
 	unsigned int cpu = smp_processor_id();
 	unsigned long start_snooze;
-	unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
 
 	/*
 	 * Indicate to the HV that we are idle. Now would be
@@ -496,9 +489,9 @@
 	 * has been checked recently.  If we should poll for a little
 	 * while, do so.
 	 */
-	if (*smt_snooze_delay) {
+	if (__get_cpu_var(smt_snooze_delay)) {
 		start_snooze = get_tb() +
-			*smt_snooze_delay * tb_ticks_per_usec;
+			__get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec;
 		local_irq_enable();
 		set_thread_flag(TIF_POLLING_NRFLAG);
 
@@ -518,24 +511,7 @@
 			goto out;
 	}
 
-	/*
-	 * If not SMT, cede processor.  If CPU is running SMT
-	 * cede if the other thread is not idle, so that it can
-	 * go single-threaded.  If the other thread is idle,
-	 * we ask the hypervisor if it has pending work it
-	 * wants to do and cede if it does.  Otherwise we keep
-	 * polling in order to reduce interrupt latency.
-	 *
-	 * Doing the cede when the other thread is active will
-	 * result in this thread going dormant, meaning the other
-	 * thread gets to run in single-threaded (ST) mode, which
-	 * is slightly faster than SMT mode with this thread at
-	 * very low priority.  The cede enables interrupts, which
-	 * doesn't matter here.
-	 */
-	if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
-	    || poll_pending() == H_PENDING)
-		cede_processor();
+	cede_processor();
 
 out:
 	HMT_medium();
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index e5e999e..91f052d 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -12,8 +12,14 @@
 obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_PPC_TODC)		+= todc.o
 obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
+obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_I8259)		+= i8259.o
 obj-$(CONFIG_PPC_83xx)		+= ipic.o
 endif
+
+# Temporary hack until we have migrated to asm-powerpc
+ifeq ($(ARCH),powerpc)
+obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
+endif
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c
new file mode 100644
index 0000000..ec26599
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm2_common.c
@@ -0,0 +1,309 @@
+/*
+ * General Purpose functions for the global management of the
+ * 8260 Communication Processor Module.
+ * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
+ * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
+ *	2.3.99 Updates
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ * 	Merged to arch/powerpc from arch/ppc/syslib/cpm2_common.c
+ *
+ * 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.
+ */
+
+/*
+ *
+ * In addition to the individual control of the communication
+ * channels, there are a few functions that globally affect the
+ * communication processor.
+ *
+ * Buffer descriptors must be allocated from the dual ported memory
+ * space.  The allocator for that is here.  When the communication
+ * process is reset, we reclaim the memory available.  There is
+ * currently no deallocator for this memory.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mpc8260.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/cpm2.h>
+#include <asm/rheap.h>
+#include <asm/fs_pd.h>
+
+#include <sysdev/fsl_soc.h>
+
+static void cpm2_dpinit(void);
+cpm_cpm2_t	*cpmp;		/* Pointer to comm processor space */
+
+/* We allocate this here because it is used almost exclusively for
+ * the communication processor devices.
+ */
+cpm2_map_t *cpm2_immr;
+intctl_cpm2_t *cpm2_intctl;
+
+#define CPM_MAP_SIZE	(0x40000)	/* 256k - the PQ3 reserve this amount
+					   of space for CPM as it is larger
+					   than on PQ2 */
+
+void
+cpm2_reset(void)
+{
+	cpm2_immr = (cpm2_map_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
+	cpm2_intctl = cpm2_map(im_intctl);
+
+	/* Reclaim the DP memory for our use.
+	 */
+	cpm2_dpinit();
+
+	/* Tell everyone where the comm processor resides.
+	 */
+	cpmp = &cpm2_immr->im_cpm;
+}
+
+/* Set a baud rate generator.  This needs lots of work.  There are
+ * eight BRGs, which can be connected to the CPM channels or output
+ * as clocks.  The BRGs are in two different block of internal
+ * memory mapped space.
+ * The baud rate clock is the system clock divided by something.
+ * It was set up long ago during the initial boot phase and is
+ * is given to us.
+ * Baud rate clocks are zero-based in the driver code (as that maps
+ * to port numbers).  Documentation uses 1-based numbering.
+ */
+#define BRG_INT_CLK	(get_brgfreq())
+#define BRG_UART_CLK	(BRG_INT_CLK/16)
+
+/* This function is used by UARTS, or anything else that uses a 16x
+ * oversampled clock.
+ */
+void
+cpm_setbrg(uint brg, uint rate)
+{
+	volatile uint	*bp;
+
+	/* This is good enough to get SMCs running.....
+	*/
+	if (brg < 4) {
+		bp = cpm2_map_size(im_brgc1, 16);
+	} else {
+		bp = cpm2_map_size(im_brgc5, 16);
+		brg -= 4;
+	}
+	bp += brg;
+	*bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN;
+
+	cpm2_unmap(bp);
+}
+
+/* This function is used to set high speed synchronous baud rate
+ * clocks.
+ */
+void
+cpm2_fastbrg(uint brg, uint rate, int div16)
+{
+	volatile uint	*bp;
+
+	if (brg < 4) {
+		bp = cpm2_map_size(im_brgc1, 16);
+	}
+	else {
+		bp = cpm2_map_size(im_brgc5, 16);
+		brg -= 4;
+	}
+	bp += brg;
+	*bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
+	if (div16)
+		*bp |= CPM_BRG_DIV16;
+
+	cpm2_unmap(bp);
+}
+
+int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
+{
+	int ret = 0;
+	int shift;
+	int i, bits = 0;
+	cpmux_t *im_cpmux;
+	u32 *reg;
+	u32 mask = 7;
+	u8 clk_map [24][3] = {
+		{CPM_CLK_FCC1, CPM_BRG5, 0},
+		{CPM_CLK_FCC1, CPM_BRG6, 1},
+		{CPM_CLK_FCC1, CPM_BRG7, 2},
+		{CPM_CLK_FCC1, CPM_BRG8, 3},
+		{CPM_CLK_FCC1, CPM_CLK9, 4},
+		{CPM_CLK_FCC1, CPM_CLK10, 5},
+		{CPM_CLK_FCC1, CPM_CLK11, 6},
+		{CPM_CLK_FCC1, CPM_CLK12, 7},
+		{CPM_CLK_FCC2, CPM_BRG5, 0},
+		{CPM_CLK_FCC2, CPM_BRG6, 1},
+		{CPM_CLK_FCC2, CPM_BRG7, 2},
+		{CPM_CLK_FCC2, CPM_BRG8, 3},
+		{CPM_CLK_FCC2, CPM_CLK13, 4},
+		{CPM_CLK_FCC2, CPM_CLK14, 5},
+		{CPM_CLK_FCC2, CPM_CLK15, 6},
+		{CPM_CLK_FCC2, CPM_CLK16, 7},
+		{CPM_CLK_FCC3, CPM_BRG5, 0},
+		{CPM_CLK_FCC3, CPM_BRG6, 1},
+		{CPM_CLK_FCC3, CPM_BRG7, 2},
+		{CPM_CLK_FCC3, CPM_BRG8, 3},
+		{CPM_CLK_FCC3, CPM_CLK13, 4},
+		{CPM_CLK_FCC3, CPM_CLK14, 5},
+		{CPM_CLK_FCC3, CPM_CLK15, 6},
+		{CPM_CLK_FCC3, CPM_CLK16, 7}
+		};
+
+	im_cpmux = cpm2_map(im_cpmux);
+
+	switch (target) {
+	case CPM_CLK_SCC1:
+		reg = &im_cpmux->cmx_scr;
+		shift = 24;
+	case CPM_CLK_SCC2:
+		reg = &im_cpmux->cmx_scr;
+		shift = 16;
+		break;
+	case CPM_CLK_SCC3:
+		reg = &im_cpmux->cmx_scr;
+		shift = 8;
+		break;
+	case CPM_CLK_SCC4:
+		reg = &im_cpmux->cmx_scr;
+		shift = 0;
+		break;
+	case CPM_CLK_FCC1:
+		reg = &im_cpmux->cmx_fcr;
+		shift = 24;
+		break;
+	case CPM_CLK_FCC2:
+		reg = &im_cpmux->cmx_fcr;
+		shift = 16;
+		break;
+	case CPM_CLK_FCC3:
+		reg = &im_cpmux->cmx_fcr;
+		shift = 8;
+		break;
+	default:
+		printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n");
+		return -EINVAL;
+	}
+
+	if (mode == CPM_CLK_RX)
+		shift +=3;
+
+	for (i=0; i<24; i++) {
+		if (clk_map[i][0] == target && clk_map[i][1] == clock) {
+			bits = clk_map[i][2];
+			break;
+		}
+	}
+	if (i == sizeof(clk_map)/3)
+	    ret = -EINVAL;
+
+	bits <<= shift;
+	mask <<= shift;
+	out_be32(reg, (in_be32(reg) & ~mask) | bits);
+
+	cpm2_unmap(im_cpmux);
+	return ret;
+}
+
+/*
+ * dpalloc / dpfree bits.
+ */
+static spinlock_t cpm_dpmem_lock;
+/* 16 blocks should be enough to satisfy all requests
+ * until the memory subsystem goes up... */
+static rh_block_t cpm_boot_dpmem_rh_block[16];
+static rh_info_t cpm_dpmem_info;
+static u8* im_dprambase;
+
+static void cpm2_dpinit(void)
+{
+	spin_lock_init(&cpm_dpmem_lock);
+
+	im_dprambase = ioremap(CPM_MAP_ADDR, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE);
+
+	/* initialize the info header */
+	rh_init(&cpm_dpmem_info, 1,
+			sizeof(cpm_boot_dpmem_rh_block) /
+			sizeof(cpm_boot_dpmem_rh_block[0]),
+			cpm_boot_dpmem_rh_block);
+
+	/* Attach the usable dpmem area */
+	/* XXX: This is actually crap. CPM_DATAONLY_BASE and
+	 * CPM_DATAONLY_SIZE is only a subset of the available dpram. It
+	 * varies with the processor and the microcode patches activated.
+	 * But the following should be at least safe.
+	 */
+	rh_attach_region(&cpm_dpmem_info, (void *)CPM_DATAONLY_BASE,
+			CPM_DATAONLY_SIZE);
+}
+
+/* This function returns an index into the DPRAM area.
+ */
+uint cpm_dpalloc(uint size, uint align)
+{
+	void *start;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm_dpmem_lock, flags);
+	cpm_dpmem_info.alignment = align;
+	start = rh_alloc(&cpm_dpmem_info, size, "commproc");
+	spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+	return (uint)start;
+}
+EXPORT_SYMBOL(cpm_dpalloc);
+
+int cpm_dpfree(uint offset)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm_dpmem_lock, flags);
+	ret = rh_free(&cpm_dpmem_info, (void *)offset);
+	spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(cpm_dpfree);
+
+/* not sure if this is ever needed */
+uint cpm_dpalloc_fixed(uint offset, uint size, uint align)
+{
+	void *start;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm_dpmem_lock, flags);
+	cpm_dpmem_info.alignment = align;
+	start = rh_alloc_fixed(&cpm_dpmem_info, (void *)offset, size, "commproc");
+	spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+	return (uint)start;
+}
+EXPORT_SYMBOL(cpm_dpalloc_fixed);
+
+void cpm_dpdump(void)
+{
+	rh_dump(&cpm_dpmem_info);
+}
+EXPORT_SYMBOL(cpm_dpdump);
+
+void *cpm_dpram_addr(uint offset)
+{
+	return (void *)(im_dprambase + offset);
+}
+EXPORT_SYMBOL(cpm_dpram_addr);
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
new file mode 100644
index 0000000..28b0189
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -0,0 +1,256 @@
+/*
+ * Platform information definitions.
+ *
+ * Copied from arch/ppc/syslib/cpm2_pic.c with minor subsequent updates
+ * to make in work in arch/powerpc/. Original (c) belongs to Dan Malek.
+ *
+ * Author:  Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 1999-2001 (c) Dan Malek <dan@embeddedalley.com>
+ * 2006 (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.
+ */
+
+/* The CPM2 internal interrupt controller.  It is usually
+ * the only interrupt controller.
+ * There are two 32-bit registers (high/low) for up to 64
+ * possible interrupts.
+ *
+ * Now, the fun starts.....Interrupt Numbers DO NOT MAP
+ * in a simple arithmetic fashion to mask or pending registers.
+ * That is, interrupt 4 does not map to bit position 4.
+ * We create two tables, indexed by vector number, to indicate
+ * which register to use and which bit in the register to use.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/irq.h>
+
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+#include "cpm2_pic.h"
+
+static struct device_node *cpm2_pic_node;
+static struct irq_host *cpm2_pic_host;
+#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
+static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+
+static const u_char irq_to_siureg[] = {
+	1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* bit numbers do not match the docs, these are precomputed so the bit for
+ * a given irq is (1 << irq_to_siubit[irq]) */
+static const u_char irq_to_siubit[] = {
+	 0, 15, 14, 13, 12, 11, 10,  9,
+	 8,  7,  6,  5,  4,  3,  2,  1,
+	 2,  1,  0, 14, 13, 12, 11, 10,
+	 9,  8,  7,  6,  5,  4,  3,  0,
+	31, 30, 29, 28, 27, 26, 25, 24,
+	23, 22, 21, 20, 19, 18, 17, 16,
+	16, 17, 18, 19, 20, 21, 22, 23,
+	24, 25, 26, 27, 28, 29, 30, 31,
+};
+
+static void cpm2_mask_irq(unsigned int irq_nr)
+{
+	int	bit, word;
+	volatile uint	*simr;
+
+	irq_nr -= CPM_IRQ_OFFSET;
+
+	bit = irq_to_siubit[irq_nr];
+	word = irq_to_siureg[irq_nr];
+
+	simr = &(cpm2_intctl->ic_simrh);
+	ppc_cached_irq_mask[word] &= ~(1 << bit);
+	simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void cpm2_unmask_irq(unsigned int irq_nr)
+{
+	int	bit, word;
+	volatile uint	*simr;
+
+	irq_nr -= CPM_IRQ_OFFSET;
+
+	bit = irq_to_siubit[irq_nr];
+	word = irq_to_siureg[irq_nr];
+
+	simr = &(cpm2_intctl->ic_simrh);
+	ppc_cached_irq_mask[word] |= 1 << bit;
+	simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void cpm2_mask_and_ack(unsigned int irq_nr)
+{
+	int	bit, word;
+	volatile uint	*simr, *sipnr;
+
+	irq_nr -= CPM_IRQ_OFFSET;
+
+	bit = irq_to_siubit[irq_nr];
+	word = irq_to_siureg[irq_nr];
+
+	simr = &(cpm2_intctl->ic_simrh);
+	sipnr = &(cpm2_intctl->ic_sipnrh);
+	ppc_cached_irq_mask[word] &= ~(1 << bit);
+	simr[word] = ppc_cached_irq_mask[word];
+	sipnr[word] = 1 << bit;
+}
+
+static void cpm2_end_irq(unsigned int irq_nr)
+{
+	int	bit, word;
+	volatile uint	*simr;
+
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+			&& irq_desc[irq_nr].action) {
+
+		irq_nr -= CPM_IRQ_OFFSET;
+		bit = irq_to_siubit[irq_nr];
+		word = irq_to_siureg[irq_nr];
+
+		simr = &(cpm2_intctl->ic_simrh);
+		ppc_cached_irq_mask[word] |= 1 << bit;
+		simr[word] = ppc_cached_irq_mask[word];
+		/*
+		 * Work around large numbers of spurious IRQs on PowerPC 82xx
+		 * systems.
+		 */
+		mb();
+	}
+}
+
+static struct irq_chip cpm2_pic = {
+	.typename = " CPM2 SIU ",
+	.enable = cpm2_unmask_irq,
+	.disable = cpm2_mask_irq,
+	.unmask = cpm2_unmask_irq,
+	.mask_ack = cpm2_mask_and_ack,
+	.end = cpm2_end_irq,
+};
+
+unsigned int cpm2_get_irq(struct pt_regs *regs)
+{
+	int irq;
+	unsigned long bits;
+
+       /* For CPM2, read the SIVEC register and shift the bits down
+         * to get the irq number.         */
+        bits = cpm2_intctl->ic_sivec;
+        irq = bits >> 26;
+
+	if (irq == 0)
+		return(-1);
+	return irq+CPM_IRQ_OFFSET;
+}
+
+static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node)
+{
+	return cpm2_pic_node == NULL || cpm2_pic_node == node;
+}
+
+static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
+			  irq_hw_number_t hw)
+{
+	pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
+
+	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
+	return 0;
+}
+
+static void cpm2_host_unmap(struct irq_host *h, unsigned int virq)
+{
+	/* Make sure irq is masked in hardware */
+	cpm2_mask_irq(virq);
+
+	/* remove chip and handler */
+	set_irq_chip_and_handler(virq, NULL, NULL);
+}
+
+static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+			    u32 *intspec, unsigned int intsize,
+			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+{
+	static const unsigned char map_cpm2_senses[4] = {
+		IRQ_TYPE_LEVEL_LOW,
+		IRQ_TYPE_LEVEL_HIGH,
+		IRQ_TYPE_EDGE_FALLING,
+		IRQ_TYPE_EDGE_RISING,
+	};
+
+	*out_hwirq = intspec[0];
+	if (intsize > 1 && intspec[1] < 4)
+		*out_flags = map_cpm2_senses[intspec[1]];
+	else
+		*out_flags = IRQ_TYPE_NONE;
+
+	return 0;
+}
+
+static struct irq_host_ops cpm2_pic_host_ops = {
+	.match = cpm2_pic_host_match,
+	.map = cpm2_pic_host_map,
+	.unmap = cpm2_host_unmap,
+	.xlate = cpm2_pic_host_xlate,
+};
+
+void cpm2_pic_init(struct device_node *node)
+{
+	int i;
+
+	/* Clear the CPM IRQ controller, in case it has any bits set
+	 * from the bootloader
+	 */
+
+	/* Mask out everything */
+
+	cpm2_intctl->ic_simrh = 0x00000000;
+	cpm2_intctl->ic_simrl = 0x00000000;
+
+	wmb();
+
+	/* Ack everything */
+	cpm2_intctl->ic_sipnrh = 0xffffffff;
+	cpm2_intctl->ic_sipnrl = 0xffffffff;
+	wmb();
+
+	/* Dummy read of the vector */
+	i = cpm2_intctl->ic_sivec;
+	rmb();
+
+	/* Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	cpm2_intctl->ic_sicr = 0;
+	cpm2_intctl->ic_scprrh = 0x05309770;
+	cpm2_intctl->ic_scprrl = 0x05309770;
+
+	/* create a legacy host */
+	if (node)
+		cpm2_pic_node = of_node_get(node);
+
+	cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64);
+	if (cpm2_pic_host == NULL) {
+		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
+		return;
+	}
+}
diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h
new file mode 100644
index 0000000..3c513e5
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm2_pic.h
@@ -0,0 +1,10 @@
+#ifndef _PPC_KERNEL_CPM2_H
+#define _PPC_KERNEL_CPM2_H
+
+extern intctl_cpm2_t *cpm2_intctl;
+
+extern unsigned int cpm2_get_irq(struct pt_regs *regs);
+
+extern void cpm2_pic_init(struct device_node*);
+
+#endif /* _PPC_KERNEL_CPM2_H */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 92ba378..7d759f1 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -3,6 +3,9 @@
  *
  * Maintained by Kumar Gala (see MAINTAINERS for contact information)
  *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.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
@@ -20,15 +23,21 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/fsl_devices.h>
+#include <linux/fs_enet_pd.h>
+#include <linux/fs_uart_pd.h>
 
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/time.h>
 #include <asm/prom.h>
 #include <sysdev/fsl_soc.h>
 #include <mm/mmu_decl.h>
+#include <asm/cpm2.h>
 
+extern void init_fcc_ioports(struct fs_platform_info*);
+extern void init_scc_ioports(struct fs_uart_platform_info*);
 static phys_addr_t immrbase = -1;
 
 phys_addr_t get_immrbase(void)
@@ -42,7 +51,9 @@
 	if (soc) {
 		unsigned int size;
 		const void *prop = get_property(soc, "reg", &size);
-		immrbase = of_translate_address(soc, prop);
+
+		if (prop)
+			immrbase = of_translate_address(soc, prop);
 		of_node_put(soc);
 	};
 
@@ -51,6 +62,59 @@
 
 EXPORT_SYMBOL(get_immrbase);
 
+#ifdef CONFIG_CPM2
+
+static u32 brgfreq = -1;
+
+u32 get_brgfreq(void)
+{
+	struct device_node *node;
+
+	if (brgfreq != -1)
+		return brgfreq;
+
+	node = of_find_node_by_type(NULL, "cpm");
+	if (node) {
+		unsigned int size;
+		const unsigned int *prop = get_property(node, "brg-frequency",
+					&size);
+
+		if (prop)
+			brgfreq = *prop;
+		of_node_put(node);
+	};
+
+	return brgfreq;
+}
+
+EXPORT_SYMBOL(get_brgfreq);
+
+static u32 fs_baudrate = -1;
+
+u32 get_baudrate(void)
+{
+	struct device_node *node;
+
+	if (fs_baudrate != -1)
+		return fs_baudrate;
+
+	node = of_find_node_by_type(NULL, "serial");
+	if (node) {
+		unsigned int size;
+		const unsigned int *prop = get_property(node, "current-speed",
+				&size);
+
+		if (prop)
+			fs_baudrate = *prop;
+		of_node_put(node);
+	};
+
+	return fs_baudrate;
+}
+
+EXPORT_SYMBOL(get_baudrate);
+#endif /* CONFIG_CPM2 */
+
 static int __init gfar_mdio_of_init(void)
 {
 	struct device_node *np;
@@ -85,8 +149,11 @@
 			mdio_data.irq[k] = -1;
 
 		while ((child = of_get_next_child(np, child)) != NULL) {
-			const u32 *id = get_property(child, "reg", NULL);
-			mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
+			int irq = irq_of_parse_and_map(child, 0);
+			if (irq != NO_IRQ) {
+				const u32 *id = get_property(child, "reg", NULL);
+				mdio_data.irq[*id] = irq;
+			}
 		}
 
 		ret =
@@ -128,7 +195,7 @@
 		const char *model;
 		const void *mac_addr;
 		const phandle *ph;
-		int n_res = 1;
+		int n_res = 2;
 
 		memset(r, 0, sizeof(r));
 		memset(&gfar_data, 0, sizeof(gfar_data));
@@ -159,7 +226,7 @@
 
 		gfar_dev =
 		    platform_device_register_simple("fsl-gianfar", i, &r[0],
-						    n_res + 1);
+						    n_res);
 
 		if (IS_ERR(gfar_dev)) {
 			ret = PTR_ERR(gfar_dev);
@@ -478,3 +545,255 @@
 }
 
 arch_initcall(fsl_usb_of_init);
+
+#ifdef CONFIG_CPM2
+
+static const char fcc_regs[] = "fcc_regs";
+static const char fcc_regs_c[] = "fcc_regs_c";
+static const char fcc_pram[] = "fcc_pram";
+static char bus_id[9][BUS_ID_SIZE];
+
+static int __init fs_enet_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+	struct platform_device *fs_enet_dev;
+	struct resource res;
+	int ret;
+
+	for (np = NULL, i = 0;
+	     (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL;
+	     i++) {
+		struct resource r[4];
+		struct device_node *phy, *mdio;
+		struct fs_platform_info fs_enet_data;
+		const unsigned int *id, *phy_addr, phy_irq;
+		const void *mac_addr;
+		const phandle *ph;
+		const char *model;
+
+		memset(r, 0, sizeof(r));
+		memset(&fs_enet_data, 0, sizeof(fs_enet_data));
+
+		ret = of_address_to_resource(np, 0, &r[0]);
+		if (ret)
+			goto err;
+		r[0].name = fcc_regs;
+
+		ret = of_address_to_resource(np, 1, &r[1]);
+		if (ret)
+			goto err;
+		r[1].name = fcc_pram;
+
+		ret = of_address_to_resource(np, 2, &r[2]);
+		if (ret)
+			goto err;
+		r[2].name = fcc_regs_c;
+		fs_enet_data.fcc_regs_c = r[2].start;
+
+		r[3].start = r[3].end = irq_of_parse_and_map(np, 0);
+		r[3].flags = IORESOURCE_IRQ;
+
+		fs_enet_dev =
+		    platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4);
+
+		if (IS_ERR(fs_enet_dev)) {
+			ret = PTR_ERR(fs_enet_dev);
+			goto err;
+		}
+
+		model = get_property(np, "model", NULL);
+		if (model == NULL) {
+			ret = -ENODEV;
+			goto unreg;
+		}
+
+		mac_addr = get_property(np, "mac-address", NULL);
+		memcpy(fs_enet_data.macaddr, mac_addr, 6);
+
+		ph = get_property(np, "phy-handle", NULL);
+		phy = of_find_node_by_phandle(*ph);
+
+		if (phy == NULL) {
+			ret = -ENODEV;
+			goto unreg;
+		}
+
+		phy_addr = get_property(phy, "reg", NULL);
+		fs_enet_data.phy_addr = *phy_addr;
+
+		phy_irq = get_property(phy, "interrupts", NULL);
+
+		id = get_property(np, "device-id", NULL);
+		fs_enet_data.fs_no = *id;
+		strcpy(fs_enet_data.fs_type, model);
+
+		mdio = of_get_parent(phy);
+                ret = of_address_to_resource(mdio, 0, &res);
+                if (ret) {
+                        of_node_put(phy);
+                        of_node_put(mdio);
+                        goto unreg;
+                }
+
+		fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
+		fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
+
+		if (strstr(model, "FCC")) {
+			int fcc_index = *id - 1;
+			unsigned char* mdio_bb_prop;
+
+			fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
+			fs_enet_data.rx_ring = 32;
+			fs_enet_data.tx_ring = 32;
+			fs_enet_data.rx_copybreak = 240;
+			fs_enet_data.use_napi = 0;
+			fs_enet_data.napi_weight = 17;
+			fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
+			fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
+			fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index);
+
+			snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x",
+							(u32)res.start, fs_enet_data.phy_addr);
+			fs_enet_data.bus_id = (char*)&bus_id[(*id)];
+			fs_enet_data.init_ioports = init_fcc_ioports;
+
+			mdio_bb_prop = get_property(phy, "bitbang", NULL);
+			if (mdio_bb_prop) {
+				struct platform_device *fs_enet_mdio_bb_dev;
+				struct fs_mii_bb_platform_info fs_enet_mdio_bb_data;
+
+				fs_enet_mdio_bb_dev =
+					platform_device_register_simple("fsl-bb-mdio",
+							i, NULL, 0);
+				memset(&fs_enet_mdio_bb_data, 0,
+						sizeof(struct fs_mii_bb_platform_info));
+				fs_enet_mdio_bb_data.mdio_dat.bit =
+					mdio_bb_prop[0];
+				fs_enet_mdio_bb_data.mdio_dir.bit =
+					mdio_bb_prop[1];
+				fs_enet_mdio_bb_data.mdc_dat.bit =
+					mdio_bb_prop[2];
+				fs_enet_mdio_bb_data.mdio_port =
+					mdio_bb_prop[3];
+				fs_enet_mdio_bb_data.mdc_port =
+					mdio_bb_prop[4];
+				fs_enet_mdio_bb_data.delay =
+					mdio_bb_prop[5];
+
+				fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
+				fs_enet_mdio_bb_data.irq[1] = -1;
+				fs_enet_mdio_bb_data.irq[2] = -1;
+				fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
+				fs_enet_mdio_bb_data.irq[31] = -1;
+
+				fs_enet_mdio_bb_data.mdio_dat.offset =
+					(u32)&cpm2_immr->im_ioport.iop_pdatc;
+				fs_enet_mdio_bb_data.mdio_dir.offset =
+					(u32)&cpm2_immr->im_ioport.iop_pdirc;
+				fs_enet_mdio_bb_data.mdc_dat.offset =
+					(u32)&cpm2_immr->im_ioport.iop_pdatc;
+
+				ret = platform_device_add_data(
+						fs_enet_mdio_bb_dev,
+						&fs_enet_mdio_bb_data,
+						sizeof(struct fs_mii_bb_platform_info));
+				if (ret)
+					goto unreg;
+			}
+			
+			of_node_put(phy);
+			of_node_put(mdio);
+
+			ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
+						     sizeof(struct
+							    fs_platform_info));
+		if (ret)
+			goto unreg;
+	}
+	return 0;
+
+unreg:
+	platform_device_unregister(fs_enet_dev);
+err:
+	return ret;
+}
+
+arch_initcall(fs_enet_of_init);
+
+static const char scc_regs[] = "regs";
+static const char scc_pram[] = "pram";
+
+static int __init cpm_uart_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+	struct platform_device *cpm_uart_dev;
+	int ret;
+
+	for (np = NULL, i = 0;
+	     (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
+	     i++) {
+		struct resource r[3];
+		struct fs_uart_platform_info cpm_uart_data;
+		const int *id;
+		const char *model;
+
+		memset(r, 0, sizeof(r));
+		memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
+
+		ret = of_address_to_resource(np, 0, &r[0]);
+		if (ret)
+			goto err;
+
+		r[0].name = scc_regs;
+
+		ret = of_address_to_resource(np, 1, &r[1]);
+		if (ret)
+			goto err;
+		r[1].name = scc_pram;
+
+		r[2].start = r[2].end = irq_of_parse_and_map(np, 0);
+		r[2].flags = IORESOURCE_IRQ;
+
+		cpm_uart_dev =
+		    platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);
+
+		if (IS_ERR(cpm_uart_dev)) {
+			ret = PTR_ERR(cpm_uart_dev);
+			goto err;
+		}
+
+		id = get_property(np, "device-id", NULL);
+		cpm_uart_data.fs_no = *id;
+
+		model = (char*)get_property(np, "model", NULL);
+		strcpy(cpm_uart_data.fs_type, model);
+
+		cpm_uart_data.uart_clk = ppc_proc_freq;
+
+		cpm_uart_data.tx_num_fifo = 4;
+		cpm_uart_data.tx_buf_size = 32;
+		cpm_uart_data.rx_num_fifo = 4;
+		cpm_uart_data.rx_buf_size = 32;
+		cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
+		cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
+
+		ret =
+		    platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
+					     sizeof(struct
+						    fs_uart_platform_info));
+		if (ret)
+			goto unreg;
+	}
+
+	return 0;
+
+unreg:
+	platform_device_unregister(cpm_uart_dev);
+err:
+	return ret;
+}
+
+arch_initcall(cpm_uart_of_init);
+#endif /* CONFIG_CPM2 */
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 5a3dd48..04e145b 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -5,6 +5,8 @@
 #include <asm/mmu.h>
 
 extern phys_addr_t get_immrbase(void);
+extern u32 get_brgfreq(void);
+extern u32 get_baudrate(void);
 
 #endif
 #endif
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 0251b7c..6ebdae8 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/ipic.c
+ * arch/powerpc/sysdev/ipic.c
  *
  * IPIC routines implementations.
  *
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 723972b..3ee03a9 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -341,7 +341,7 @@
 		u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
 		if (id == PCI_CAP_ID_HT) {
 			id = readb(devbase + pos + 3);
-			if (id == 0x80)
+			if (id == HT_CAPTYPE_IRQ)
 				break;
 		}
 	}
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig
new file mode 100644
index 0000000..a725e80
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/Kconfig
@@ -0,0 +1,30 @@
+#
+# QE Communication options
+#
+
+menu "QE Options"
+	depends on QUICC_ENGINE
+
+config UCC_SLOW
+	bool "UCC Slow Protocols Support"
+	default n
+	select UCC
+	help
+	  This option provides qe_lib support to UCC slow
+	  protocols: UART, BISYNC, QMC
+
+config UCC_FAST
+	bool "UCC Fast Protocols Support"
+	default n
+	select UCC
+	select UCC_SLOW
+	help
+	  This option provides qe_lib support to UCC fast
+	  protocols: HDLC, Ethernet, ATM, transparent
+
+config UCC
+	bool
+	default y if UCC_FAST || UCC_SLOW
+
+endmenu
+
diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile
new file mode 100644
index 0000000..874fe1a
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux ppc-specific parts of QE
+#
+obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o
+
+obj-$(CONFIG_UCC)	+= ucc.o
+obj-$(CONFIG_UCC_SLOW)	+= ucc_slow.o
+obj-$(CONFIG_UCC_FAST)	+= ucc_fast.o
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
new file mode 100644
index 0000000..2bae632
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.com>
+ * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
+ *
+ * Description:
+ * General Purpose functions for the global management of the
+ * QUICC Engine (QE).
+ *
+ * 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/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+#include <asm/prom.h>
+#include <asm/rheap.h>
+
+static void qe_snums_init(void);
+static void qe_muram_init(void);
+static int qe_sdma_init(void);
+
+static DEFINE_SPINLOCK(qe_lock);
+
+/* QE snum state */
+enum qe_snum_state {
+	QE_SNUM_STATE_USED,
+	QE_SNUM_STATE_FREE
+};
+
+/* QE snum */
+struct qe_snum {
+	u8 num;
+	enum qe_snum_state state;
+};
+
+/* We allocate this here because it is used almost exclusively for
+ * the communication processor devices.
+ */
+struct qe_immap *qe_immr = NULL;
+EXPORT_SYMBOL(qe_immr);
+
+static struct qe_snum snums[QE_NUM_OF_SNUM];	/* Dynamically allocated SNUMs */
+
+static phys_addr_t qebase = -1;
+
+phys_addr_t get_qe_base(void)
+{
+	struct device_node *qe;
+
+	if (qebase != -1)
+		return qebase;
+
+	qe = of_find_node_by_type(NULL, "qe");
+	if (qe) {
+		unsigned int size;
+		const void *prop = get_property(qe, "reg", &size);
+		qebase = of_translate_address(qe, prop);
+		of_node_put(qe);
+	};
+
+	return qebase;
+}
+
+EXPORT_SYMBOL(get_qe_base);
+
+void qe_reset(void)
+{
+	if (qe_immr == NULL)
+		qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
+
+	qe_snums_init();
+
+	qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
+		     QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+	/* Reclaim the MURAM memory for our use. */
+	qe_muram_init();
+
+	if (qe_sdma_init())
+		panic("sdma init failed!");
+}
+
+int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
+{
+	unsigned long flags;
+	u8 mcn_shift = 0, dev_shift = 0;
+
+	spin_lock_irqsave(&qe_lock, flags);
+	if (cmd == QE_RESET) {
+		out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
+	} else {
+		if (cmd == QE_ASSIGN_PAGE) {
+			/* Here device is the SNUM, not sub-block */
+			dev_shift = QE_CR_SNUM_SHIFT;
+		} else if (cmd == QE_ASSIGN_RISC) {
+			/* Here device is the SNUM, and mcnProtocol is
+			 * e_QeCmdRiscAssignment value */
+			dev_shift = QE_CR_SNUM_SHIFT;
+			mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
+		} else {
+			if (device == QE_CR_SUBBLOCK_USB)
+				mcn_shift = QE_CR_MCN_USB_SHIFT;
+			else
+				mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
+		}
+
+		out_be32(&qe_immr->cp.cecdr,
+			 immrbar_virt_to_phys((void *)cmd_input));
+		out_be32(&qe_immr->cp.cecr,
+			 (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
+			  mcn_protocol << mcn_shift));
+	}
+
+	/* wait for the QE_CR_FLG to clear */
+	while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG)
+		cpu_relax();
+	spin_unlock_irqrestore(&qe_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(qe_issue_cmd);
+
+/* Set a baud rate generator. This needs lots of work. There are
+ * 16 BRGs, which can be connected to the QE channels or output
+ * as clocks. The BRGs are in two different block of internal
+ * memory mapped space.
+ * The baud rate clock is the system clock divided by something.
+ * It was set up long ago during the initial boot phase and is
+ * is given to us.
+ * Baud rate clocks are zero-based in the driver code (as that maps
+ * to port numbers). Documentation uses 1-based numbering.
+ */
+static unsigned int brg_clk = 0;
+
+unsigned int get_brg_clk(void)
+{
+	struct device_node *qe;
+	if (brg_clk)
+		return brg_clk;
+
+	qe = of_find_node_by_type(NULL, "qe");
+	if (qe) {
+		unsigned int size;
+		const u32 *prop = get_property(qe, "brg-frequency", &size);
+		brg_clk = *prop;
+		of_node_put(qe);
+	};
+	return brg_clk;
+}
+
+/* This function is used by UARTS, or anything else that uses a 16x
+ * oversampled clock.
+ */
+void qe_setbrg(u32 brg, u32 rate)
+{
+	volatile u32 *bp;
+	u32 divisor, tempval;
+	int div16 = 0;
+
+	bp = &qe_immr->brg.brgc1;
+	bp += brg;
+
+	divisor = (get_brg_clk() / rate);
+	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
+		div16 = 1;
+		divisor /= 16;
+	}
+
+	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
+	if (div16)
+		tempval |= QE_BRGC_DIV16;
+
+	out_be32(bp, tempval);
+}
+
+/* Initialize SNUMs (thread serial numbers) according to
+ * QE Module Control chapter, SNUM table
+ */
+static void qe_snums_init(void)
+{
+	int i;
+	static const u8 snum_init[] = {
+		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
+		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
+		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
+		0xD8, 0xD9, 0xE8, 0xE9,
+	};
+
+	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+		snums[i].num = snum_init[i];
+		snums[i].state = QE_SNUM_STATE_FREE;
+	}
+}
+
+int qe_get_snum(void)
+{
+	unsigned long flags;
+	int snum = -EBUSY;
+	int i;
+
+	spin_lock_irqsave(&qe_lock, flags);
+	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+		if (snums[i].state == QE_SNUM_STATE_FREE) {
+			snums[i].state = QE_SNUM_STATE_USED;
+			snum = snums[i].num;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&qe_lock, flags);
+
+	return snum;
+}
+EXPORT_SYMBOL(qe_get_snum);
+
+void qe_put_snum(u8 snum)
+{
+	int i;
+
+	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+		if (snums[i].num == snum) {
+			snums[i].state = QE_SNUM_STATE_FREE;
+			break;
+		}
+	}
+}
+EXPORT_SYMBOL(qe_put_snum);
+
+static int qe_sdma_init(void)
+{
+	struct sdma *sdma = &qe_immr->sdma;
+	u32 sdma_buf_offset;
+
+	if (!sdma)
+		return -ENODEV;
+
+	/* allocate 2 internal temporary buffers (512 bytes size each) for
+	 * the SDMA */
+	sdma_buf_offset = qe_muram_alloc(512 * 2, 64);
+	if (IS_MURAM_ERR(sdma_buf_offset))
+		return -ENOMEM;
+
+	out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK);
+	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | (0x1 >>
+					QE_SDMR_CEN_SHIFT)));
+
+	return 0;
+}
+
+/*
+ * muram_alloc / muram_free bits.
+ */
+static DEFINE_SPINLOCK(qe_muram_lock);
+
+/* 16 blocks should be enough to satisfy all requests
+ * until the memory subsystem goes up... */
+static rh_block_t qe_boot_muram_rh_block[16];
+static rh_info_t qe_muram_info;
+
+static void qe_muram_init(void)
+{
+	struct device_node *np;
+	u32 address;
+	u64 size;
+	unsigned int flags;
+
+	/* initialize the info header */
+	rh_init(&qe_muram_info, 1,
+		sizeof(qe_boot_muram_rh_block) /
+		sizeof(qe_boot_muram_rh_block[0]), qe_boot_muram_rh_block);
+
+	/* Attach the usable muram area */
+	/* XXX: This is a subset of the available muram. It
+	 * varies with the processor and the microcode patches activated.
+	 */
+	if ((np = of_find_node_by_name(NULL, "data-only")) != NULL) {
+		address = *of_get_address(np, 0, &size, &flags);
+		of_node_put(np);
+		rh_attach_region(&qe_muram_info,
+			(void *)address, (int)size);
+	}
+}
+
+/* This function returns an index into the MURAM area.
+ */
+u32 qe_muram_alloc(u32 size, u32 align)
+{
+	void *start;
+	unsigned long flags;
+
+	spin_lock_irqsave(&qe_muram_lock, flags);
+	start = rh_alloc_align(&qe_muram_info, size, align, "QE");
+	spin_unlock_irqrestore(&qe_muram_lock, flags);
+
+	return (u32) start;
+}
+EXPORT_SYMBOL(qe_muram_alloc);
+
+int qe_muram_free(u32 offset)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&qe_muram_lock, flags);
+	ret = rh_free(&qe_muram_info, (void *)offset);
+	spin_unlock_irqrestore(&qe_muram_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(qe_muram_free);
+
+/* not sure if this is ever needed */
+u32 qe_muram_alloc_fixed(u32 offset, u32 size)
+{
+	void *start;
+	unsigned long flags;
+
+	spin_lock_irqsave(&qe_muram_lock, flags);
+	start = rh_alloc_fixed(&qe_muram_info, (void *)offset, size, "commproc");
+	spin_unlock_irqrestore(&qe_muram_lock, flags);
+
+	return (u32) start;
+}
+EXPORT_SYMBOL(qe_muram_alloc_fixed);
+
+void qe_muram_dump(void)
+{
+	rh_dump(&qe_muram_info);
+}
+EXPORT_SYMBOL(qe_muram_dump);
+
+void *qe_muram_addr(u32 offset)
+{
+	return (void *)&qe_immr->muram[offset];
+}
+EXPORT_SYMBOL(qe_muram_addr);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
new file mode 100644
index 0000000..c229d07
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -0,0 +1,555 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/qe_ic.c
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc.  All rights reserved.
+ *
+ * Author: Li Yang <leoli@freescale.com>
+ * Based on code from Shlomi Gridish <gridish@freescale.com>
+ *
+ * QUICC ENGINE Interrupt Controller
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/sysdev.h>
+#include <linux/device.h>
+#include <linux/bootmem.h>
+#include <linux/spinlock.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/qe_ic.h>
+
+#include "qe_ic.h"
+
+static DEFINE_SPINLOCK(qe_ic_lock);
+
+static struct qe_ic_info qe_ic_info[] = {
+	[1] = {
+	       .mask = 0x00008000,
+	       .mask_reg = QEIC_CIMR,
+	       .pri_code = 0,
+	       .pri_reg = QEIC_CIPWCC,
+	       },
+	[2] = {
+	       .mask = 0x00004000,
+	       .mask_reg = QEIC_CIMR,
+	       .pri_code = 1,
+	       .pri_reg = QEIC_CIPWCC,
+	       },
+	[3] = {
+	       .mask = 0x00002000,
+	       .mask_reg = QEIC_CIMR,
+	       .pri_code = 2,
+	       .pri_reg = QEIC_CIPWCC,
+	       },
+	[10] = {
+		.mask = 0x00000040,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 1,
+		.pri_reg = QEIC_CIPZCC,
+		},
+	[11] = {
+		.mask = 0x00000020,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 2,
+		.pri_reg = QEIC_CIPZCC,
+		},
+	[12] = {
+		.mask = 0x00000010,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 3,
+		.pri_reg = QEIC_CIPZCC,
+		},
+	[13] = {
+		.mask = 0x00000008,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 4,
+		.pri_reg = QEIC_CIPZCC,
+		},
+	[14] = {
+		.mask = 0x00000004,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 5,
+		.pri_reg = QEIC_CIPZCC,
+		},
+	[15] = {
+		.mask = 0x00000002,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 6,
+		.pri_reg = QEIC_CIPZCC,
+		},
+	[20] = {
+		.mask = 0x10000000,
+		.mask_reg = QEIC_CRIMR,
+		.pri_code = 3,
+		.pri_reg = QEIC_CIPRTA,
+		},
+	[25] = {
+		.mask = 0x00800000,
+		.mask_reg = QEIC_CRIMR,
+		.pri_code = 0,
+		.pri_reg = QEIC_CIPRTB,
+		},
+	[26] = {
+		.mask = 0x00400000,
+		.mask_reg = QEIC_CRIMR,
+		.pri_code = 1,
+		.pri_reg = QEIC_CIPRTB,
+		},
+	[27] = {
+		.mask = 0x00200000,
+		.mask_reg = QEIC_CRIMR,
+		.pri_code = 2,
+		.pri_reg = QEIC_CIPRTB,
+		},
+	[28] = {
+		.mask = 0x00100000,
+		.mask_reg = QEIC_CRIMR,
+		.pri_code = 3,
+		.pri_reg = QEIC_CIPRTB,
+		},
+	[32] = {
+		.mask = 0x80000000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 0,
+		.pri_reg = QEIC_CIPXCC,
+		},
+	[33] = {
+		.mask = 0x40000000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 1,
+		.pri_reg = QEIC_CIPXCC,
+		},
+	[34] = {
+		.mask = 0x20000000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 2,
+		.pri_reg = QEIC_CIPXCC,
+		},
+	[35] = {
+		.mask = 0x10000000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 3,
+		.pri_reg = QEIC_CIPXCC,
+		},
+	[36] = {
+		.mask = 0x08000000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 4,
+		.pri_reg = QEIC_CIPXCC,
+		},
+	[40] = {
+		.mask = 0x00800000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 0,
+		.pri_reg = QEIC_CIPYCC,
+		},
+	[41] = {
+		.mask = 0x00400000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 1,
+		.pri_reg = QEIC_CIPYCC,
+		},
+	[42] = {
+		.mask = 0x00200000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 2,
+		.pri_reg = QEIC_CIPYCC,
+		},
+	[43] = {
+		.mask = 0x00100000,
+		.mask_reg = QEIC_CIMR,
+		.pri_code = 3,
+		.pri_reg = QEIC_CIPYCC,
+		},
+};
+
+static inline u32 qe_ic_read(volatile __be32  __iomem * base, unsigned int reg)
+{
+	return in_be32(base + (reg >> 2));
+}
+
+static inline void qe_ic_write(volatile __be32  __iomem * base, unsigned int reg,
+			       u32 value)
+{
+	out_be32(base + (reg >> 2), value);
+}
+
+static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
+{
+	return irq_desc[virq].chip_data;
+}
+
+#define virq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
+
+static void qe_ic_unmask_irq(unsigned int virq)
+{
+	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+	unsigned int src = virq_to_hw(virq);
+	unsigned long flags;
+	u32 temp;
+
+	spin_lock_irqsave(&qe_ic_lock, flags);
+
+	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+	qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+		    temp | qe_ic_info[src].mask);
+
+	spin_unlock_irqrestore(&qe_ic_lock, flags);
+}
+
+static void qe_ic_mask_irq(unsigned int virq)
+{
+	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+	unsigned int src = virq_to_hw(virq);
+	unsigned long flags;
+	u32 temp;
+
+	spin_lock_irqsave(&qe_ic_lock, flags);
+
+	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+	qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+		    temp & ~qe_ic_info[src].mask);
+
+	spin_unlock_irqrestore(&qe_ic_lock, flags);
+}
+
+static void qe_ic_mask_irq_and_ack(unsigned int virq)
+{
+	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+	unsigned int src = virq_to_hw(virq);
+	unsigned long flags;
+	u32 temp;
+
+	spin_lock_irqsave(&qe_ic_lock, flags);
+
+	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+	qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+		    temp & ~qe_ic_info[src].mask);
+
+	/* There is nothing to do for ack here, ack is handled in ISR */
+
+	spin_unlock_irqrestore(&qe_ic_lock, flags);
+}
+
+static struct irq_chip qe_ic_irq_chip = {
+	.typename = " QEIC  ",
+	.unmask = qe_ic_unmask_irq,
+	.mask = qe_ic_mask_irq,
+	.mask_ack = qe_ic_mask_irq_and_ack,
+};
+
+static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
+{
+	struct qe_ic *qe_ic = h->host_data;
+
+	/* Exact match, unless qe_ic node is NULL */
+	return qe_ic->of_node == NULL || qe_ic->of_node == node;
+}
+
+static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
+			  irq_hw_number_t hw)
+{
+	struct qe_ic *qe_ic = h->host_data;
+	struct irq_chip *chip;
+
+	if (qe_ic_info[hw].mask == 0) {
+		printk(KERN_ERR "Can't map reserved IRQ \n");
+		return -EINVAL;
+	}
+	/* Default chip */
+	chip = &qe_ic->hc_irq;
+
+	set_irq_chip_data(virq, qe_ic);
+	get_irq_desc(virq)->status |= IRQ_LEVEL;
+
+	set_irq_chip_and_handler(virq, chip, handle_level_irq);
+
+	return 0;
+}
+
+static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
+			    u32 * intspec, unsigned int intsize,
+			    irq_hw_number_t * out_hwirq,
+			    unsigned int *out_flags)
+{
+	*out_hwirq = intspec[0];
+	if (intsize > 1)
+		*out_flags = intspec[1];
+	else
+		*out_flags = IRQ_TYPE_NONE;
+	return 0;
+}
+
+static struct irq_host_ops qe_ic_host_ops = {
+	.match = qe_ic_host_match,
+	.map = qe_ic_host_map,
+	.xlate = qe_ic_host_xlate,
+};
+
+/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
+unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
+{
+	int irq;
+
+	BUG_ON(qe_ic == NULL);
+
+	/* get the interrupt source vector. */
+	irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
+
+	if (irq == 0)
+		return NO_IRQ;
+
+	return irq_linear_revmap(qe_ic->irqhost, irq);
+}
+
+/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
+unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
+{
+	int irq;
+
+	BUG_ON(qe_ic == NULL);
+
+	/* get the interrupt source vector. */
+	irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
+
+	if (irq == 0)
+		return NO_IRQ;
+
+	return irq_linear_revmap(qe_ic->irqhost, irq);
+}
+
+/* FIXME: We mask all the QE Low interrupts while handling.  We should
+ * let other interrupt come in, but BAD interrupts are generated */
+void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc,
+				struct pt_regs *regs)
+{
+	struct qe_ic *qe_ic = desc->handler_data;
+	struct irq_chip *chip = irq_desc[irq].chip;
+
+	unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic, regs);
+
+	chip->mask_ack(irq);
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq, regs);
+	chip->unmask(irq);
+}
+
+/* FIXME: We mask all the QE High interrupts while handling.  We should
+ * let other interrupt come in, but BAD interrupts are generated */
+void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc,
+				 struct pt_regs *regs)
+{
+	struct qe_ic *qe_ic = desc->handler_data;
+	struct irq_chip *chip = irq_desc[irq].chip;
+
+	unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic, regs);
+
+	chip->mask_ack(irq);
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq, regs);
+	chip->unmask(irq);
+}
+
+void __init qe_ic_init(struct device_node *node, unsigned int flags)
+{
+	struct qe_ic *qe_ic;
+	struct resource res;
+	u32 temp = 0, ret, high_active = 0;
+
+	qe_ic = alloc_bootmem(sizeof(struct qe_ic));
+	if (qe_ic == NULL)
+		return;
+
+	memset(qe_ic, 0, sizeof(struct qe_ic));
+	qe_ic->of_node = node ? of_node_get(node) : NULL;
+
+	qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+					NR_QE_IC_INTS, &qe_ic_host_ops, 0);
+	if (qe_ic->irqhost == NULL) {
+		of_node_put(node);
+		return;
+	}
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret)
+		return;
+
+	qe_ic->regs = ioremap(res.start, res.end - res.start + 1);
+
+	qe_ic->irqhost->host_data = qe_ic;
+	qe_ic->hc_irq = qe_ic_irq_chip;
+
+	qe_ic->virq_high = irq_of_parse_and_map(node, 0);
+	qe_ic->virq_low = irq_of_parse_and_map(node, 1);
+
+	if (qe_ic->virq_low == NO_IRQ) {
+		printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
+		return;
+	}
+
+	/* default priority scheme is grouped. If spread mode is    */
+	/* required, configure cicr accordingly.                    */
+	if (flags & QE_IC_SPREADMODE_GRP_W)
+		temp |= CICR_GWCC;
+	if (flags & QE_IC_SPREADMODE_GRP_X)
+		temp |= CICR_GXCC;
+	if (flags & QE_IC_SPREADMODE_GRP_Y)
+		temp |= CICR_GYCC;
+	if (flags & QE_IC_SPREADMODE_GRP_Z)
+		temp |= CICR_GZCC;
+	if (flags & QE_IC_SPREADMODE_GRP_RISCA)
+		temp |= CICR_GRTA;
+	if (flags & QE_IC_SPREADMODE_GRP_RISCB)
+		temp |= CICR_GRTB;
+
+	/* choose destination signal for highest priority interrupt */
+	if (flags & QE_IC_HIGH_SIGNAL) {
+		temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
+		high_active = 1;
+	}
+
+	qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
+
+	set_irq_data(qe_ic->virq_low, qe_ic);
+	set_irq_chained_handler(qe_ic->virq_low, qe_ic_cascade_low);
+
+	if (qe_ic->virq_high != NO_IRQ) {
+		set_irq_data(qe_ic->virq_high, qe_ic);
+		set_irq_chained_handler(qe_ic->virq_high, qe_ic_cascade_high);
+	}
+
+	printk("QEIC (%d IRQ sources) at %p\n", NR_QE_IC_INTS, qe_ic->regs);
+}
+
+void qe_ic_set_highest_priority(unsigned int virq, int high)
+{
+	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+	unsigned int src = virq_to_hw(virq);
+	u32 temp = 0;
+
+	temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
+
+	temp &= ~CICR_HP_MASK;
+	temp |= src << CICR_HP_SHIFT;
+
+	temp &= ~CICR_HPIT_MASK;
+	temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
+
+	qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
+}
+
+/* Set Priority level within its group, from 1 to 8 */
+int qe_ic_set_priority(unsigned int virq, unsigned int priority)
+{
+	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+	unsigned int src = virq_to_hw(virq);
+	u32 temp;
+
+	if (priority > 8 || priority == 0)
+		return -EINVAL;
+	if (src > 127)
+		return -EINVAL;
+	if (qe_ic_info[src].pri_reg == 0)
+		return -EINVAL;
+
+	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
+
+	if (priority < 4) {
+		temp &= ~(0x7 << (32 - priority * 3));
+		temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
+	} else {
+		temp &= ~(0x7 << (24 - priority * 3));
+		temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
+	}
+
+	qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
+
+	return 0;
+}
+
+/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
+int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
+{
+	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+	unsigned int src = virq_to_hw(virq);
+	u32 temp, control_reg = QEIC_CICNR, shift = 0;
+
+	if (priority > 2 || priority == 0)
+		return -EINVAL;
+
+	switch (qe_ic_info[src].pri_reg) {
+	case QEIC_CIPZCC:
+		shift = CICNR_ZCC1T_SHIFT;
+		break;
+	case QEIC_CIPWCC:
+		shift = CICNR_WCC1T_SHIFT;
+		break;
+	case QEIC_CIPYCC:
+		shift = CICNR_YCC1T_SHIFT;
+		break;
+	case QEIC_CIPXCC:
+		shift = CICNR_XCC1T_SHIFT;
+		break;
+	case QEIC_CIPRTA:
+		shift = CRICR_RTA1T_SHIFT;
+		control_reg = QEIC_CRICR;
+		break;
+	case QEIC_CIPRTB:
+		shift = CRICR_RTB1T_SHIFT;
+		control_reg = QEIC_CRICR;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	shift += (2 - priority) * 2;
+	temp = qe_ic_read(qe_ic->regs, control_reg);
+	temp &= ~(SIGNAL_MASK << shift);
+	temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
+	qe_ic_write(qe_ic->regs, control_reg, temp);
+
+	return 0;
+}
+
+static struct sysdev_class qe_ic_sysclass = {
+	set_kset_name("qe_ic"),
+};
+
+static struct sys_device device_qe_ic = {
+	.id = 0,
+	.cls = &qe_ic_sysclass,
+};
+
+static int __init init_qe_ic_sysfs(void)
+{
+	int rc;
+
+	printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
+
+	rc = sysdev_class_register(&qe_ic_sysclass);
+	if (rc) {
+		printk(KERN_ERR "Failed registering qe_ic sys class\n");
+		return -ENODEV;
+	}
+	rc = sysdev_register(&device_qe_ic);
+	if (rc) {
+		printk(KERN_ERR "Failed registering qe_ic sys device\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+subsys_initcall(init_qe_ic_sysfs);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
new file mode 100644
index 0000000..9a631ad
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -0,0 +1,106 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/qe_ic.h
+ *
+ * QUICC ENGINE Interrupt Controller Header
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Author: Li Yang <leoli@freescale.com>
+ * Based on code from Shlomi Gridish <gridish@freescale.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 _POWERPC_SYSDEV_QE_IC_H
+#define _POWERPC_SYSDEV_QE_IC_H
+
+#include <asm/qe_ic.h>
+
+#define NR_QE_IC_INTS		64
+
+/* QE IC registers offset */
+#define QEIC_CICR		0x00
+#define QEIC_CIVEC		0x04
+#define QEIC_CRIPNR		0x08
+#define QEIC_CIPNR		0x0c
+#define QEIC_CIPXCC		0x10
+#define QEIC_CIPYCC		0x14
+#define QEIC_CIPWCC		0x18
+#define QEIC_CIPZCC		0x1c
+#define QEIC_CIMR		0x20
+#define QEIC_CRIMR		0x24
+#define QEIC_CICNR		0x28
+#define QEIC_CIPRTA		0x30
+#define QEIC_CIPRTB		0x34
+#define QEIC_CRICR		0x3c
+#define QEIC_CHIVEC		0x60
+
+/* Interrupt priority registers */
+#define CIPCC_SHIFT_PRI0	29
+#define CIPCC_SHIFT_PRI1	26
+#define CIPCC_SHIFT_PRI2	23
+#define CIPCC_SHIFT_PRI3	20
+#define CIPCC_SHIFT_PRI4	13
+#define CIPCC_SHIFT_PRI5	10
+#define CIPCC_SHIFT_PRI6	7
+#define CIPCC_SHIFT_PRI7	4
+
+/* CICR priority modes */
+#define CICR_GWCC		0x00040000
+#define CICR_GXCC		0x00020000
+#define CICR_GYCC		0x00010000
+#define CICR_GZCC		0x00080000
+#define CICR_GRTA		0x00200000
+#define CICR_GRTB		0x00400000
+#define CICR_HPIT_SHIFT		8
+#define CICR_HPIT_MASK		0x00000300
+#define CICR_HP_SHIFT		24
+#define CICR_HP_MASK		0x3f000000
+
+/* CICNR */
+#define CICNR_WCC1T_SHIFT	20
+#define CICNR_ZCC1T_SHIFT	28
+#define CICNR_YCC1T_SHIFT	12
+#define CICNR_XCC1T_SHIFT	4
+
+/* CRICR */
+#define CRICR_RTA1T_SHIFT	20
+#define CRICR_RTB1T_SHIFT	28
+
+/* Signal indicator */
+#define SIGNAL_MASK		3
+#define SIGNAL_HIGH		2
+#define SIGNAL_LOW		0
+
+struct qe_ic {
+	/* Control registers offset */
+	volatile u32 __iomem *regs;
+
+	/* The remapper for this QEIC */
+	struct irq_host *irqhost;
+
+	/* The "linux" controller struct */
+	struct irq_chip hc_irq;
+
+	/* The device node of the interrupt controller */
+	struct device_node *of_node;
+
+	/* VIRQ numbers of QE high/low irqs */
+	unsigned int virq_high;
+	unsigned int virq_low;
+};
+
+/*
+ * QE interrupt controller internal structure
+ */
+struct qe_ic_info {
+	u32	mask;	  /* location of this source at the QIMR register. */
+	u32	mask_reg; /* Mask register offset */
+	u8	pri_code; /* for grouped interrupts sources - the interrupt
+			     code as appears at the group priority register */
+	u32	pri_reg;  /* Group priority register offset */
+};
+
+#endif /* _POWERPC_SYSDEV_QE_IC_H */
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
new file mode 100644
index 0000000..aea4359
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -0,0 +1,226 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/qe_io.c
+ *
+ * QE Parallel I/O ports configuration routines
+ *
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Li Yang <LeoLi@freescale.com>
+ * Based on code from Shlomi Gridish <gridish@freescale.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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <sysdev/fsl_soc.h>
+
+#undef DEBUG
+
+#define NUM_OF_PINS	32
+
+struct port_regs {
+	__be32	cpodr;		/* Open drain register */
+	__be32	cpdata;		/* Data register */
+	__be32	cpdir1;		/* Direction register */
+	__be32	cpdir2;		/* Direction register */
+	__be32	cppar1;		/* Pin assignment register */
+	__be32	cppar2;		/* Pin assignment register */
+};
+
+static struct port_regs *par_io = NULL;
+static int num_par_io_ports = 0;
+
+int par_io_init(struct device_node *np)
+{
+	struct resource res;
+	int ret;
+	const u32 *num_ports;
+
+	/* Map Parallel I/O ports registers */
+	ret = of_address_to_resource(np, 0, &res);
+	if (ret)
+		return ret;
+	par_io = ioremap(res.start, res.end - res.start + 1);
+
+	num_ports = get_property(np, "num-ports", NULL);
+	if (num_ports)
+		num_par_io_ports = *num_ports;
+
+	return 0;
+}
+
+int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
+		      int assignment, int has_irq)
+{
+	u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val;
+
+	if (!par_io)
+		return -1;
+
+	/* calculate pin location for single and 2 bits information */
+	pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin + 1)));
+
+	/* Set open drain, if required */
+	tmp_val = in_be32(&par_io[port].cpodr);
+	if (open_drain)
+		out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val);
+	else
+		out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val);
+
+	/* define direction */
+	tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ?
+		in_be32(&par_io[port].cpdir2) :
+		in_be32(&par_io[port].cpdir1);
+
+	/* get all bits mask for 2 bit per port */
+	pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS -
+				(pin % (NUM_OF_PINS / 2) + 1) * 2));
+
+	/* Get the final mask we need for the right definition */
+	new_mask2bits = (u32) (dir << (NUM_OF_PINS -
+				(pin % (NUM_OF_PINS / 2) + 1) * 2));
+
+	/* clear and set 2 bits mask */
+	if (pin > (NUM_OF_PINS / 2) - 1) {
+		out_be32(&par_io[port].cpdir2,
+			 ~pin_mask2bits & tmp_val);
+		tmp_val &= ~pin_mask2bits;
+		out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val);
+	} else {
+		out_be32(&par_io[port].cpdir1,
+			 ~pin_mask2bits & tmp_val);
+		tmp_val &= ~pin_mask2bits;
+		out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val);
+	}
+	/* define pin assignment */
+	tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ?
+		in_be32(&par_io[port].cppar2) :
+		in_be32(&par_io[port].cppar1);
+
+	new_mask2bits = (u32) (assignment << (NUM_OF_PINS -
+			(pin % (NUM_OF_PINS / 2) + 1) * 2));
+	/* clear and set 2 bits mask */
+	if (pin > (NUM_OF_PINS / 2) - 1) {
+		out_be32(&par_io[port].cppar2,
+			 ~pin_mask2bits & tmp_val);
+		tmp_val &= ~pin_mask2bits;
+		out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val);
+	} else {
+		out_be32(&par_io[port].cppar1,
+			 ~pin_mask2bits & tmp_val);
+		tmp_val &= ~pin_mask2bits;
+		out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(par_io_config_pin);
+
+int par_io_data_set(u8 port, u8 pin, u8 val)
+{
+	u32 pin_mask, tmp_val;
+
+	if (port >= num_par_io_ports)
+		return -EINVAL;
+	if (pin >= NUM_OF_PINS)
+		return -EINVAL;
+	/* calculate pin location */
+	pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin));
+
+	tmp_val = in_be32(&par_io[port].cpdata);
+
+	if (val == 0)		/* clear */
+		out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val);
+	else			/* set */
+		out_be32(&par_io[port].cpdata, pin_mask | tmp_val);
+
+	return 0;
+}
+EXPORT_SYMBOL(par_io_data_set);
+
+int par_io_of_config(struct device_node *np)
+{
+	struct device_node *pio;
+	const phandle *ph;
+	int pio_map_len;
+	const unsigned int *pio_map;
+
+	if (par_io == NULL) {
+		printk(KERN_ERR "par_io not initialized \n");
+		return -1;
+	}
+
+	ph = get_property(np, "pio-handle", NULL);
+	if (ph == 0) {
+		printk(KERN_ERR "pio-handle not available \n");
+		return -1;
+	}
+
+	pio = of_find_node_by_phandle(*ph);
+
+	pio_map = get_property(pio, "pio-map", &pio_map_len);
+	if (pio_map == NULL) {
+		printk(KERN_ERR "pio-map is not set! \n");
+		return -1;
+	}
+	pio_map_len /= sizeof(unsigned int);
+	if ((pio_map_len % 6) != 0) {
+		printk(KERN_ERR "pio-map format wrong! \n");
+		return -1;
+	}
+
+	while (pio_map_len > 0) {
+		par_io_config_pin((u8) pio_map[0], (u8) pio_map[1],
+				(int) pio_map[2], (int) pio_map[3],
+				(int) pio_map[4], (int) pio_map[5]);
+		pio_map += 6;
+		pio_map_len -= 6;
+	}
+	of_node_put(pio);
+	return 0;
+}
+EXPORT_SYMBOL(par_io_of_config);
+
+#ifdef DEBUG
+static void dump_par_io(void)
+{
+	int i;
+
+	printk(KERN_INFO "PAR IO registars:\n");
+	printk(KERN_INFO "Base address: 0x%08x\n", (u32) par_io);
+	for (i = 0; i < num_par_io_ports; i++) {
+		printk(KERN_INFO "cpodr[%d] : addr - 0x%08x, val - 0x%08x\n",
+		       i, (u32) & par_io[i].cpodr,
+		       in_be32(&par_io[i].cpodr));
+		printk(KERN_INFO "cpdata[%d]: addr - 0x%08x, val - 0x%08x\n",
+		       i, (u32) & par_io[i].cpdata,
+		       in_be32(&par_io[i].cpdata));
+		printk(KERN_INFO "cpdir1[%d]: addr - 0x%08x, val - 0x%08x\n",
+		       i, (u32) & par_io[i].cpdir1,
+		       in_be32(&par_io[i].cpdir1));
+		printk(KERN_INFO "cpdir2[%d]: addr - 0x%08x, val - 0x%08x\n",
+		       i, (u32) & par_io[i].cpdir2,
+		       in_be32(&par_io[i].cpdir2));
+		printk(KERN_INFO "cppar1[%d]: addr - 0x%08x, val - 0x%08x\n",
+		       i, (u32) & par_io[i].cppar1,
+		       in_be32(&par_io[i].cppar1));
+		printk(KERN_INFO "cppar2[%d]: addr - 0x%08x, val - 0x%08x\n",
+		       i, (u32) & par_io[i].cppar2,
+		       in_be32(&par_io[i].cppar2));
+	}
+
+}
+EXPORT_SYMBOL(dump_par_io);
+#endif /* DEBUG */
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
new file mode 100644
index 0000000..916c9e5
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -0,0 +1,251 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/ucc.c
+ *
+ * QE UCC API Set - UCC specific routines implementations.
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.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/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+#include <asm/ucc.h>
+
+static DEFINE_SPINLOCK(ucc_lock);
+
+int ucc_set_qe_mux_mii_mng(int ucc_num)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ucc_lock, flags);
+	out_be32(&qe_immr->qmx.cmxgcr,
+		 ((in_be32(&qe_immr->qmx.cmxgcr) &
+		   ~QE_CMXGCR_MII_ENET_MNG) |
+		  (ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT)));
+	spin_unlock_irqrestore(&ucc_lock, flags);
+
+	return 0;
+}
+
+int ucc_set_type(int ucc_num, struct ucc_common *regs,
+		 enum ucc_speed_type speed)
+{
+	u8 guemr = 0;
+
+	/* check if the UCC number is in range. */
+	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
+		return -EINVAL;
+
+	guemr = regs->guemr;
+	guemr &= ~(UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX);
+	switch (speed) {
+	case UCC_SPEED_TYPE_SLOW:
+		guemr |= (UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX);
+		break;
+	case UCC_SPEED_TYPE_FAST:
+		guemr |= (UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX);
+		break;
+	default:
+		return -EINVAL;
+	}
+	regs->guemr = guemr;
+
+	return 0;
+}
+
+int ucc_init_guemr(struct ucc_common *regs)
+{
+	u8 guemr = 0;
+
+	if (!regs)
+		return -EINVAL;
+
+	/* Set bit 3 (which is reserved in the GUEMR register) to 1 */
+	guemr = UCC_GUEMR_SET_RESERVED3;
+
+	regs->guemr = guemr;
+
+	return 0;
+}
+
+static void get_cmxucr_reg(int ucc_num, volatile u32 ** p_cmxucr, u8 * reg_num,
+			   u8 * shift)
+{
+	switch (ucc_num) {
+	case 0: *p_cmxucr = &(qe_immr->qmx.cmxucr1);
+		*reg_num = 1;
+		*shift = 16;
+		break;
+	case 2: *p_cmxucr = &(qe_immr->qmx.cmxucr1);
+		*reg_num = 1;
+		*shift = 0;
+		break;
+	case 4: *p_cmxucr = &(qe_immr->qmx.cmxucr2);
+		*reg_num = 2;
+		*shift = 16;
+		break;
+	case 6: *p_cmxucr = &(qe_immr->qmx.cmxucr2);
+		*reg_num = 2;
+		*shift = 0;
+		break;
+	case 1: *p_cmxucr = &(qe_immr->qmx.cmxucr3);
+		*reg_num = 3;
+		*shift = 16;
+		break;
+	case 3: *p_cmxucr = &(qe_immr->qmx.cmxucr3);
+		*reg_num = 3;
+		*shift = 0;
+		break;
+	case 5: *p_cmxucr = &(qe_immr->qmx.cmxucr4);
+		*reg_num = 4;
+		*shift = 16;
+		break;
+	case 7: *p_cmxucr = &(qe_immr->qmx.cmxucr4);
+		*reg_num = 4;
+		*shift = 0;
+		break;
+	default:
+		break;
+	}
+}
+
+int ucc_mux_set_grant_tsa_bkpt(int ucc_num, int set, u32 mask)
+{
+	volatile u32 *p_cmxucr;
+	u8 reg_num;
+	u8 shift;
+
+	/* check if the UCC number is in range. */
+	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
+		return -EINVAL;
+
+	get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);
+
+	if (set)
+		out_be32(p_cmxucr, in_be32(p_cmxucr) | (mask << shift));
+	else
+		out_be32(p_cmxucr, in_be32(p_cmxucr) & ~(mask << shift));
+
+	return 0;
+}
+
+int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode)
+{
+	volatile u32 *p_cmxucr;
+	u8 reg_num;
+	u8 shift;
+	u32 clock_bits;
+	u32 clock_mask;
+	int source = -1;
+
+	/* check if the UCC number is in range. */
+	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
+		return -EINVAL;
+
+	if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) {
+		printk(KERN_ERR
+		       "ucc_set_qe_mux_rxtx: bad comm mode type passed.");
+		return -EINVAL;
+	}
+
+	get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);
+
+	switch (reg_num) {
+	case 1:
+		switch (clock) {
+		case QE_BRG1:	source = 1; break;
+		case QE_BRG2:	source = 2; break;
+		case QE_BRG7:	source = 3; break;
+		case QE_BRG8:	source = 4; break;
+		case QE_CLK9:	source = 5; break;
+		case QE_CLK10:	source = 6; break;
+		case QE_CLK11:	source = 7; break;
+		case QE_CLK12:	source = 8; break;
+		case QE_CLK15:	source = 9; break;
+		case QE_CLK16:	source = 10; break;
+		default: 	source = -1; break;
+		}
+		break;
+	case 2:
+		switch (clock) {
+		case QE_BRG5:	source = 1; break;
+		case QE_BRG6:	source = 2; break;
+		case QE_BRG7:	source = 3; break;
+		case QE_BRG8:	source = 4; break;
+		case QE_CLK13:	source = 5; break;
+		case QE_CLK14:	source = 6; break;
+		case QE_CLK19:	source = 7; break;
+		case QE_CLK20:	source = 8; break;
+		case QE_CLK15:	source = 9; break;
+		case QE_CLK16:	source = 10; break;
+		default: 	source = -1; break;
+		}
+		break;
+	case 3:
+		switch (clock) {
+		case QE_BRG9:	source = 1; break;
+		case QE_BRG10:	source = 2; break;
+		case QE_BRG15:	source = 3; break;
+		case QE_BRG16:	source = 4; break;
+		case QE_CLK3:	source = 5; break;
+		case QE_CLK4:	source = 6; break;
+		case QE_CLK17:	source = 7; break;
+		case QE_CLK18:	source = 8; break;
+		case QE_CLK7:	source = 9; break;
+		case QE_CLK8:	source = 10; break;
+		default:	source = -1; break;
+		}
+		break;
+	case 4:
+		switch (clock) {
+		case QE_BRG13:	source = 1; break;
+		case QE_BRG14:	source = 2; break;
+		case QE_BRG15:	source = 3; break;
+		case QE_BRG16:	source = 4; break;
+		case QE_CLK5:	source = 5; break;
+		case QE_CLK6:	source = 6; break;
+		case QE_CLK21:	source = 7; break;
+		case QE_CLK22:	source = 8; break;
+		case QE_CLK7:	source = 9; break;
+		case QE_CLK8:	source = 10; break;
+		default: 	source = -1; break;
+		}
+		break;
+	default:
+		source = -1;
+		break;
+	}
+
+	if (source == -1) {
+		printk(KERN_ERR
+		     "ucc_set_qe_mux_rxtx: Bad combination of clock and UCC.");
+		return -ENOENT;
+	}
+
+	clock_bits = (u32) source;
+	clock_mask = QE_CMXUCR_TX_CLK_SRC_MASK;
+	if (mode == COMM_DIR_RX) {
+		clock_bits <<= 4;  /* Rx field is 4 bits to left of Tx field */
+		clock_mask <<= 4;  /* Rx field is 4 bits to left of Tx field */
+	}
+	clock_bits <<= shift;
+	clock_mask <<= shift;
+
+	out_be32(p_cmxucr, (in_be32(p_cmxucr) & ~clock_mask) | clock_bits);
+
+	return 0;
+}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
new file mode 100644
index 0000000..c2be734
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -0,0 +1,396 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/ucc_fast.c
+ *
+ * QE UCC Fast API Set - UCC Fast specific routines implementations.
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.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/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include <asm/ucc.h>
+#include <asm/ucc_fast.h>
+
+#define uccf_printk(level, format, arg...) \
+	printk(level format "\n", ## arg)
+
+#define uccf_dbg(format, arg...) \
+	uccf_printk(KERN_DEBUG , format , ## arg)
+#define uccf_err(format, arg...) \
+	uccf_printk(KERN_ERR , format , ## arg)
+#define uccf_info(format, arg...) \
+	uccf_printk(KERN_INFO , format , ## arg)
+#define uccf_warn(format, arg...) \
+	uccf_printk(KERN_WARNING , format , ## arg)
+
+#ifdef UCCF_VERBOSE_DEBUG
+#define uccf_vdbg uccf_dbg
+#else
+#define uccf_vdbg(fmt, args...) do { } while (0)
+#endif				/* UCCF_VERBOSE_DEBUG */
+
+void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
+{
+	uccf_info("UCC%d Fast registers:", uccf->uf_info->ucc_num);
+	uccf_info("Base address: 0x%08x", (u32) uccf->uf_regs);
+
+	uccf_info("gumr  : addr - 0x%08x, val - 0x%08x",
+		  (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
+	uccf_info("upsmr : addr - 0x%08x, val - 0x%08x",
+		  (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
+	uccf_info("utodr : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
+	uccf_info("udsr  : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
+	uccf_info("ucce  : addr - 0x%08x, val - 0x%08x",
+		  (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
+	uccf_info("uccm  : addr - 0x%08x, val - 0x%08x",
+		  (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
+	uccf_info("uccs  : addr - 0x%08x, val - 0x%02x",
+		  (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs);
+	uccf_info("urfb  : addr - 0x%08x, val - 0x%08x",
+		  (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
+	uccf_info("urfs  : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
+	uccf_info("urfet : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
+	uccf_info("urfset: addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->urfset,
+		  in_be16(&uccf->uf_regs->urfset));
+	uccf_info("utfb  : addr - 0x%08x, val - 0x%08x",
+		  (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
+	uccf_info("utfs  : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
+	uccf_info("utfet : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
+	uccf_info("utftt : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
+	uccf_info("utpt  : addr - 0x%08x, val - 0x%04x",
+		  (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
+	uccf_info("urtry : addr - 0x%08x, val - 0x%08x",
+		  (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
+	uccf_info("guemr : addr - 0x%08x, val - 0x%02x",
+		  (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
+}
+
+u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
+{
+	switch (uccf_num) {
+	case 0:	return QE_CR_SUBBLOCK_UCCFAST1;
+	case 1: return QE_CR_SUBBLOCK_UCCFAST2;
+	case 2: return QE_CR_SUBBLOCK_UCCFAST3;
+	case 3: return QE_CR_SUBBLOCK_UCCFAST4;
+	case 4: return QE_CR_SUBBLOCK_UCCFAST5;
+	case 5: return QE_CR_SUBBLOCK_UCCFAST6;
+	case 6: return QE_CR_SUBBLOCK_UCCFAST7;
+	case 7:	return QE_CR_SUBBLOCK_UCCFAST8;
+	default: return QE_CR_SUBBLOCK_INVALID;
+	}
+}
+
+void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
+{
+	out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
+}
+
+void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
+{
+	struct ucc_fast *uf_regs;
+	u32 gumr;
+
+	uf_regs = uccf->uf_regs;
+
+	/* Enable reception and/or transmission on this UCC. */
+	gumr = in_be32(&uf_regs->gumr);
+	if (mode & COMM_DIR_TX) {
+		gumr |= UCC_FAST_GUMR_ENT;
+		uccf->enabled_tx = 1;
+	}
+	if (mode & COMM_DIR_RX) {
+		gumr |= UCC_FAST_GUMR_ENR;
+		uccf->enabled_rx = 1;
+	}
+	out_be32(&uf_regs->gumr, gumr);
+}
+
+void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
+{
+	struct ucc_fast *uf_regs;
+	u32 gumr;
+
+	uf_regs = uccf->uf_regs;
+
+	/* Disable reception and/or transmission on this UCC. */
+	gumr = in_be32(&uf_regs->gumr);
+	if (mode & COMM_DIR_TX) {
+		gumr &= ~UCC_FAST_GUMR_ENT;
+		uccf->enabled_tx = 0;
+	}
+	if (mode & COMM_DIR_RX) {
+		gumr &= ~UCC_FAST_GUMR_ENR;
+		uccf->enabled_rx = 0;
+	}
+	out_be32(&uf_regs->gumr, gumr);
+}
+
+int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret)
+{
+	struct ucc_fast_private *uccf;
+	struct ucc_fast *uf_regs;
+	u32 gumr = 0;
+	int ret;
+
+	uccf_vdbg("%s: IN", __FUNCTION__);
+
+	if (!uf_info)
+		return -EINVAL;
+
+	/* check if the UCC port number is in range. */
+	if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
+		uccf_err("ucc_fast_init: Illagal UCC number!");
+		return -EINVAL;
+	}
+
+	/* Check that 'max_rx_buf_length' is properly aligned (4). */
+	if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
+		uccf_err("ucc_fast_init: max_rx_buf_length not aligned.");
+		return -EINVAL;
+	}
+
+	/* Validate Virtual Fifo register values */
+	if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
+		uccf_err
+		    ("ucc_fast_init: Virtual Fifo register urfs too small.");
+		return -EINVAL;
+	}
+
+	if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+		uccf_err
+		    ("ucc_fast_init: Virtual Fifo register urfs not aligned.");
+		return -EINVAL;
+	}
+
+	if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+		uccf_err
+		    ("ucc_fast_init: Virtual Fifo register urfet not aligned.");
+		return -EINVAL;
+	}
+
+	if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+		uccf_err
+		   ("ucc_fast_init: Virtual Fifo register urfset not aligned.");
+		return -EINVAL;
+	}
+
+	if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+		uccf_err
+		    ("ucc_fast_init: Virtual Fifo register utfs not aligned.");
+		return -EINVAL;
+	}
+
+	if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+		uccf_err
+		    ("ucc_fast_init: Virtual Fifo register utfet not aligned.");
+		return -EINVAL;
+	}
+
+	if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+		uccf_err
+		    ("ucc_fast_init: Virtual Fifo register utftt not aligned.");
+		return -EINVAL;
+	}
+
+	uccf = (struct ucc_fast_private *)
+		 kmalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
+	if (!uccf) {
+		uccf_err
+		    ("ucc_fast_init: No memory for UCC slow data structure!");
+		return -ENOMEM;
+	}
+	memset(uccf, 0, sizeof(struct ucc_fast_private));
+
+	/* Fill fast UCC structure */
+	uccf->uf_info = uf_info;
+	/* Set the PHY base address */
+	uccf->uf_regs =
+	    (struct ucc_fast *) ioremap(uf_info->regs, sizeof(struct ucc_fast));
+	if (uccf->uf_regs == NULL) {
+		uccf_err
+		    ("ucc_fast_init: No memory map for UCC slow controller!");
+		return -ENOMEM;
+	}
+
+	uccf->enabled_tx = 0;
+	uccf->enabled_rx = 0;
+	uccf->stopped_tx = 0;
+	uccf->stopped_rx = 0;
+	uf_regs = uccf->uf_regs;
+	uccf->p_ucce = (u32 *) & (uf_regs->ucce);
+	uccf->p_uccm = (u32 *) & (uf_regs->uccm);
+#ifdef STATISTICS
+	uccf->tx_frames = 0;
+	uccf->rx_frames = 0;
+	uccf->rx_discarded = 0;
+#endif				/* STATISTICS */
+
+	/* Init Guemr register */
+	if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) {
+		uccf_err("ucc_fast_init: Could not init the guemr register.");
+		ucc_fast_free(uccf);
+		return ret;
+	}
+
+	/* Set UCC to fast type */
+	if ((ret = ucc_set_type(uf_info->ucc_num,
+				(struct ucc_common *) (uf_regs),
+				UCC_SPEED_TYPE_FAST))) {
+		uccf_err("ucc_fast_init: Could not set type to fast.");
+		ucc_fast_free(uccf);
+		return ret;
+	}
+
+	uccf->mrblr = uf_info->max_rx_buf_length;
+
+	/* Set GUMR */
+	/* For more details see the hardware spec. */
+	/* gumr starts as zero. */
+	if (uf_info->tci)
+		gumr |= UCC_FAST_GUMR_TCI;
+	gumr |= uf_info->ttx_trx;
+	if (uf_info->cdp)
+		gumr |= UCC_FAST_GUMR_CDP;
+	if (uf_info->ctsp)
+		gumr |= UCC_FAST_GUMR_CTSP;
+	if (uf_info->cds)
+		gumr |= UCC_FAST_GUMR_CDS;
+	if (uf_info->ctss)
+		gumr |= UCC_FAST_GUMR_CTSS;
+	if (uf_info->txsy)
+		gumr |= UCC_FAST_GUMR_TXSY;
+	if (uf_info->rsyn)
+		gumr |= UCC_FAST_GUMR_RSYN;
+	gumr |= uf_info->synl;
+	if (uf_info->rtsm)
+		gumr |= UCC_FAST_GUMR_RTSM;
+	gumr |= uf_info->renc;
+	if (uf_info->revd)
+		gumr |= UCC_FAST_GUMR_REVD;
+	gumr |= uf_info->tenc;
+	gumr |= uf_info->tcrc;
+	gumr |= uf_info->mode;
+	out_be32(&uf_regs->gumr, gumr);
+
+	/* Allocate memory for Tx Virtual Fifo */
+	uccf->ucc_fast_tx_virtual_fifo_base_offset =
+	    qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
+	if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
+		uccf_err
+		    ("ucc_fast_init: Can not allocate MURAM memory for "
+			"struct ucc_fastx_virtual_fifo_base_offset.");
+		uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
+		ucc_fast_free(uccf);
+		return -ENOMEM;
+	}
+
+	/* Allocate memory for Rx Virtual Fifo */
+	uccf->ucc_fast_rx_virtual_fifo_base_offset =
+	    qe_muram_alloc(uf_info->urfs +
+			   (u32)
+			   UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
+			   UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
+	if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
+		uccf_err
+		    ("ucc_fast_init: Can not allocate MURAM memory for "
+			"ucc_fast_rx_virtual_fifo_base_offset.");
+		uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
+		ucc_fast_free(uccf);
+		return -ENOMEM;
+	}
+
+	/* Set Virtual Fifo registers */
+	out_be16(&uf_regs->urfs, uf_info->urfs);
+	out_be16(&uf_regs->urfet, uf_info->urfet);
+	out_be16(&uf_regs->urfset, uf_info->urfset);
+	out_be16(&uf_regs->utfs, uf_info->utfs);
+	out_be16(&uf_regs->utfet, uf_info->utfet);
+	out_be16(&uf_regs->utftt, uf_info->utftt);
+	/* utfb, urfb are offsets from MURAM base */
+	out_be32(&uf_regs->utfb, uccf->ucc_fast_tx_virtual_fifo_base_offset);
+	out_be32(&uf_regs->urfb, uccf->ucc_fast_rx_virtual_fifo_base_offset);
+
+	/* Mux clocking */
+	/* Grant Support */
+	ucc_set_qe_mux_grant(uf_info->ucc_num, uf_info->grant_support);
+	/* Breakpoint Support */
+	ucc_set_qe_mux_bkpt(uf_info->ucc_num, uf_info->brkpt_support);
+	/* Set Tsa or NMSI mode. */
+	ucc_set_qe_mux_tsa(uf_info->ucc_num, uf_info->tsa);
+	/* If NMSI (not Tsa), set Tx and Rx clock. */
+	if (!uf_info->tsa) {
+		/* Rx clock routing */
+		if (uf_info->rx_clock != QE_CLK_NONE) {
+			if (ucc_set_qe_mux_rxtx
+			    (uf_info->ucc_num, uf_info->rx_clock,
+			     COMM_DIR_RX)) {
+				uccf_err
+		("ucc_fast_init: Illegal value for parameter 'RxClock'.");
+				ucc_fast_free(uccf);
+				return -EINVAL;
+			}
+		}
+		/* Tx clock routing */
+		if (uf_info->tx_clock != QE_CLK_NONE) {
+			if (ucc_set_qe_mux_rxtx
+			    (uf_info->ucc_num, uf_info->tx_clock,
+			     COMM_DIR_TX)) {
+				uccf_err
+		("ucc_fast_init: Illegal value for parameter 'TxClock'.");
+				ucc_fast_free(uccf);
+				return -EINVAL;
+			}
+		}
+	}
+
+	/* Set interrupt mask register at UCC level. */
+	out_be32(&uf_regs->uccm, uf_info->uccm_mask);
+
+	/* First, clear anything pending at UCC level,
+	 * otherwise, old garbage may come through
+	 * as soon as the dam is opened
+	 * Writing '1' clears
+	 */
+	out_be32(&uf_regs->ucce, 0xffffffff);
+
+	*uccf_ret = uccf;
+	return 0;
+}
+
+void ucc_fast_free(struct ucc_fast_private * uccf)
+{
+	if (!uccf)
+		return;
+
+	if (uccf->ucc_fast_tx_virtual_fifo_base_offset)
+		qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);
+
+	if (uccf->ucc_fast_rx_virtual_fifo_base_offset)
+		qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
+
+	kfree(uccf);
+}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
new file mode 100644
index 0000000..1fb88ef
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * QE UCC Slow API Set - UCC Slow specific routines implementations.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include <asm/ucc.h>
+#include <asm/ucc_slow.h>
+
+#define uccs_printk(level, format, arg...) \
+        printk(level format "\n", ## arg)
+
+#define uccs_dbg(format, arg...) \
+	uccs_printk(KERN_DEBUG , format , ## arg)
+#define uccs_err(format, arg...) \
+	uccs_printk(KERN_ERR , format , ## arg)
+#define uccs_info(format, arg...) \
+	uccs_printk(KERN_INFO , format , ## arg)
+#define uccs_warn(format, arg...) \
+	uccs_printk(KERN_WARNING , format , ## arg)
+
+#ifdef UCCS_VERBOSE_DEBUG
+#define uccs_vdbg uccs_dbg
+#else
+#define uccs_vdbg(fmt, args...) do { } while (0)
+#endif				/* UCCS_VERBOSE_DEBUG */
+
+u32 ucc_slow_get_qe_cr_subblock(int uccs_num)
+{
+	switch (uccs_num) {
+	case 0: return QE_CR_SUBBLOCK_UCCSLOW1;
+	case 1: return QE_CR_SUBBLOCK_UCCSLOW2;
+	case 2: return QE_CR_SUBBLOCK_UCCSLOW3;
+	case 3: return QE_CR_SUBBLOCK_UCCSLOW4;
+	case 4: return QE_CR_SUBBLOCK_UCCSLOW5;
+	case 5: return QE_CR_SUBBLOCK_UCCSLOW6;
+	case 6: return QE_CR_SUBBLOCK_UCCSLOW7;
+	case 7: return QE_CR_SUBBLOCK_UCCSLOW8;
+	default: return QE_CR_SUBBLOCK_INVALID;
+	}
+}
+
+void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs)
+{
+	out_be16(&uccs->us_regs->utodr, UCC_SLOW_TOD);
+}
+
+void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs)
+{
+	struct ucc_slow_info *us_info = uccs->us_info;
+	u32 id;
+
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_GRACEFUL_STOP_TX, id,
+			 QE_CR_PROTOCOL_UNSPECIFIED, 0);
+}
+
+void ucc_slow_stop_tx(struct ucc_slow_private * uccs)
+{
+	struct ucc_slow_info *us_info = uccs->us_info;
+	u32 id;
+
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_STOP_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+}
+
+void ucc_slow_restart_tx(struct ucc_slow_private * uccs)
+{
+	struct ucc_slow_info *us_info = uccs->us_info;
+	u32 id;
+
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_RESTART_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+}
+
+void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
+{
+	struct ucc_slow *us_regs;
+	u32 gumr_l;
+
+	us_regs = uccs->us_regs;
+
+	/* Enable reception and/or transmission on this UCC. */
+	gumr_l = in_be32(&us_regs->gumr_l);
+	if (mode & COMM_DIR_TX) {
+		gumr_l |= UCC_SLOW_GUMR_L_ENT;
+		uccs->enabled_tx = 1;
+	}
+	if (mode & COMM_DIR_RX) {
+		gumr_l |= UCC_SLOW_GUMR_L_ENR;
+		uccs->enabled_rx = 1;
+	}
+	out_be32(&us_regs->gumr_l, gumr_l);
+}
+
+void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
+{
+	struct ucc_slow *us_regs;
+	u32 gumr_l;
+
+	us_regs = uccs->us_regs;
+
+	/* Disable reception and/or transmission on this UCC. */
+	gumr_l = in_be32(&us_regs->gumr_l);
+	if (mode & COMM_DIR_TX) {
+		gumr_l &= ~UCC_SLOW_GUMR_L_ENT;
+		uccs->enabled_tx = 0;
+	}
+	if (mode & COMM_DIR_RX) {
+		gumr_l &= ~UCC_SLOW_GUMR_L_ENR;
+		uccs->enabled_rx = 0;
+	}
+	out_be32(&us_regs->gumr_l, gumr_l);
+}
+
+int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret)
+{
+	u32 i;
+	struct ucc_slow *us_regs;
+	u32 gumr;
+	u8 function_code = 0;
+	u8 *bd;
+	struct ucc_slow_private *uccs;
+	u32 id;
+	u32 command;
+	int ret;
+
+	uccs_vdbg("%s: IN", __FUNCTION__);
+
+	if (!us_info)
+		return -EINVAL;
+
+	/* check if the UCC port number is in range. */
+	if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
+		uccs_err("ucc_slow_init: Illagal UCC number!");
+		return -EINVAL;
+	}
+
+	/*
+	 * Set mrblr
+	 * Check that 'max_rx_buf_length' is properly aligned (4), unless
+ 	 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
+	 * case when QE accepts 32 bits at a time.
+	 */
+	if ((!us_info->rfw) &&
+		(us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) {
+		uccs_err("max_rx_buf_length not aligned.");
+		return -EINVAL;
+	}
+
+	uccs = (struct ucc_slow_private *)
+		kmalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
+	if (!uccs) {
+		uccs_err
+		    ("ucc_slow_init: No memory for UCC slow data structure!");
+		return -ENOMEM;
+	}
+	memset(uccs, 0, sizeof(struct ucc_slow_private));
+
+	/* Fill slow UCC structure */
+	uccs->us_info = us_info;
+	uccs->saved_uccm = 0;
+	uccs->p_rx_frame = 0;
+	uccs->us_regs = us_info->us_regs;
+	us_regs = uccs->us_regs;
+	uccs->p_ucce = (u16 *) & (us_regs->ucce);
+	uccs->p_uccm = (u16 *) & (us_regs->uccm);
+#ifdef STATISTICS
+	uccs->rx_frames = 0;
+	uccs->tx_frames = 0;
+	uccs->rx_discarded = 0;
+#endif				/* STATISTICS */
+
+	/* Get PRAM base */
+	uccs->us_pram_offset = qe_muram_alloc(UCC_SLOW_PRAM_SIZE,
+						 ALIGNMENT_OF_UCC_SLOW_PRAM);
+	if (IS_MURAM_ERR(uccs->us_pram_offset)) {
+		uccs_err
+		    ("ucc_slow_init: Can not allocate MURAM memory "
+			"for Slow UCC.");
+		ucc_slow_free(uccs);
+		return -ENOMEM;
+	}
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED,
+			(u32) uccs->us_pram_offset);
+
+	uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
+
+	/* Init Guemr register */
+	if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->us_regs)))) {
+		uccs_err("ucc_slow_init: Could not init the guemr register.");
+		ucc_slow_free(uccs);
+		return ret;
+	}
+
+	/* Set UCC to slow type */
+	if ((ret = ucc_set_type(us_info->ucc_num,
+				(struct ucc_common *) (us_info->us_regs),
+				UCC_SPEED_TYPE_SLOW))) {
+		uccs_err("ucc_slow_init: Could not init the guemr register.");
+		ucc_slow_free(uccs);
+		return ret;
+	}
+
+	out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length);
+
+	INIT_LIST_HEAD(&uccs->confQ);
+
+	/* Allocate BDs. */
+	uccs->rx_base_offset =
+		qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
+				QE_ALIGNMENT_OF_BD);
+	if (IS_MURAM_ERR(uccs->rx_base_offset)) {
+		uccs_err("ucc_slow_init: No memory for Rx BD's.");
+		uccs->rx_base_offset = 0;
+		ucc_slow_free(uccs);
+		return -ENOMEM;
+	}
+
+	uccs->tx_base_offset =
+		qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
+			QE_ALIGNMENT_OF_BD);
+	if (IS_MURAM_ERR(uccs->tx_base_offset)) {
+		uccs_err("ucc_slow_init: No memory for Tx BD's.");
+		uccs->tx_base_offset = 0;
+		ucc_slow_free(uccs);
+		return -ENOMEM;
+	}
+
+	/* Init Tx bds */
+	bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
+	for (i = 0; i < us_info->tx_bd_ring_len; i++) {
+		/* clear bd buffer */
+		out_be32(&(((struct qe_bd *)bd)->buf), 0);
+		/* set bd status and length */
+		out_be32((u32*)bd, 0);
+		bd += sizeof(struct qe_bd);
+	}
+	bd -= sizeof(struct qe_bd);
+	/* set bd status and length */
+	out_be32((u32*)bd, T_W);	/* for last BD set Wrap bit */
+
+	/* Init Rx bds */
+	bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
+	for (i = 0; i < us_info->rx_bd_ring_len; i++) {
+		/* set bd status and length */
+		out_be32((u32*)bd, 0);
+		/* clear bd buffer */
+		out_be32(&(((struct qe_bd *)bd)->buf), 0);
+		bd += sizeof(struct qe_bd);
+	}
+	bd -= sizeof(struct qe_bd);
+	/* set bd status and length */
+	out_be32((u32*)bd, R_W);	/* for last BD set Wrap bit */
+
+	/* Set GUMR (For more details see the hardware spec.). */
+	/* gumr_h */
+	gumr = 0;
+	gumr |= us_info->tcrc;
+	if (us_info->cdp)
+		gumr |= UCC_SLOW_GUMR_H_CDP;
+	if (us_info->ctsp)
+		gumr |= UCC_SLOW_GUMR_H_CTSP;
+	if (us_info->cds)
+		gumr |= UCC_SLOW_GUMR_H_CDS;
+	if (us_info->ctss)
+		gumr |= UCC_SLOW_GUMR_H_CTSS;
+	if (us_info->tfl)
+		gumr |= UCC_SLOW_GUMR_H_TFL;
+	if (us_info->rfw)
+		gumr |= UCC_SLOW_GUMR_H_RFW;
+	if (us_info->txsy)
+		gumr |= UCC_SLOW_GUMR_H_TXSY;
+	if (us_info->rtsm)
+		gumr |= UCC_SLOW_GUMR_H_RTSM;
+	out_be32(&us_regs->gumr_h, gumr);
+
+	/* gumr_l */
+	gumr = 0;
+	if (us_info->tci)
+		gumr |= UCC_SLOW_GUMR_L_TCI;
+	if (us_info->rinv)
+		gumr |= UCC_SLOW_GUMR_L_RINV;
+	if (us_info->tinv)
+		gumr |= UCC_SLOW_GUMR_L_TINV;
+	if (us_info->tend)
+		gumr |= UCC_SLOW_GUMR_L_TEND;
+	gumr |= us_info->tdcr;
+	gumr |= us_info->rdcr;
+	gumr |= us_info->tenc;
+	gumr |= us_info->renc;
+	gumr |= us_info->diag;
+	gumr |= us_info->mode;
+	out_be32(&us_regs->gumr_l, gumr);
+
+	/* Function code registers */
+	/* function_code has initial value 0 */
+
+	/* if the data is in cachable memory, the 'global' */
+	/* in the function code should be set. */
+	function_code |= us_info->data_mem_part;
+	function_code |= QE_BMR_BYTE_ORDER_BO_MOT;	/* Required for QE */
+	uccs->us_pram->tfcr = function_code;
+	uccs->us_pram->rfcr = function_code;
+
+	/* rbase, tbase are offsets from MURAM base */
+	out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset);
+	out_be16(&uccs->us_pram->tbase, uccs->us_pram_offset);
+
+	/* Mux clocking */
+	/* Grant Support */
+	ucc_set_qe_mux_grant(us_info->ucc_num, us_info->grant_support);
+	/* Breakpoint Support */
+	ucc_set_qe_mux_bkpt(us_info->ucc_num, us_info->brkpt_support);
+	/* Set Tsa or NMSI mode. */
+	ucc_set_qe_mux_tsa(us_info->ucc_num, us_info->tsa);
+	/* If NMSI (not Tsa), set Tx and Rx clock. */
+	if (!us_info->tsa) {
+		/* Rx clock routing */
+		if (ucc_set_qe_mux_rxtx
+		    (us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX)) {
+			uccs_err
+			    ("ucc_slow_init: Illegal value for parameter"
+				" 'RxClock'.");
+			ucc_slow_free(uccs);
+			return -EINVAL;
+		}
+		/* Tx clock routing */
+		if (ucc_set_qe_mux_rxtx(us_info->ucc_num,
+				 us_info->tx_clock, COMM_DIR_TX)) {
+			uccs_err
+			    ("ucc_slow_init: Illegal value for parameter "
+				"'TxClock'.");
+			ucc_slow_free(uccs);
+			return -EINVAL;
+		}
+	}
+
+	/*
+	 * INTERRUPTS
+	 */
+	/* Set interrupt mask register at UCC level. */
+	out_be16(&us_regs->uccm, us_info->uccm_mask);
+
+	/* First, clear anything pending at UCC level, */
+	/* otherwise, old garbage may come through */
+	/* as soon as the dam is opened. */
+
+	/* Writing '1' clears */
+	out_be16(&us_regs->ucce, 0xffff);
+
+	/* Issue QE Init command */
+	if (us_info->init_tx && us_info->init_rx)
+		command = QE_INIT_TX_RX;
+	else if (us_info->init_tx)
+		command = QE_INIT_TX;
+	else
+		command = QE_INIT_RX;	/* We know at least one is TRUE */
+	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+	qe_issue_cmd(command, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+	*uccs_ret = uccs;
+	return 0;
+}
+
+void ucc_slow_free(struct ucc_slow_private * uccs)
+{
+	if (!uccs)
+		return;
+
+	if (uccs->rx_base_offset)
+		qe_muram_free(uccs->rx_base_offset);
+
+	if (uccs->tx_base_offset)
+		qe_muram_free(uccs->tx_base_offset);
+
+	if (uccs->us_pram) {
+		qe_muram_free(uccs->us_pram_offset);
+		uccs->us_pram = NULL;
+	}
+
+	kfree(uccs);
+}
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 8adad14..708236f 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2,6 +2,8 @@
  * Routines providing a simple monitor for use on the PowerMac.
  *
  * Copyright (C) 1996-2005 Paul Mackerras.
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
  *
  *      This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -503,7 +505,7 @@
 
 	mtmsr(msr);		/* restore interrupt enable */
 
-	return cmd != 'X';
+	return cmd != 'X' && cmd != EOF;
 }
 
 int xmon(struct pt_regs *excp)
@@ -2597,3 +2599,34 @@
 }
 __initcall(setup_xmon_sysrq);
 #endif /* CONFIG_MAGIC_SYSRQ */
+
+int __initdata xmon_early, xmon_off;
+
+static int __init early_parse_xmon(char *p)
+{
+	if (!p || strncmp(p, "early", 5) == 0) {
+		/* just "xmon" is equivalent to "xmon=early" */
+		xmon_init(1);
+		xmon_early = 1;
+	} else if (strncmp(p, "on", 2) == 0)
+		xmon_init(1);
+	else if (strncmp(p, "off", 3) == 0)
+		xmon_off = 1;
+	else if (strncmp(p, "nobt", 4) == 0)
+		xmon_no_auto_backtrace = 1;
+	else
+		return 1;
+
+	return 0;
+}
+early_param("xmon", early_parse_xmon);
+
+void __init xmon_setup(void)
+{
+#ifdef CONFIG_XMON_DEFAULT
+	if (!xmon_off)
+		xmon_init(1);
+#endif
+	if (xmon_early)
+		debugger(NULL);
+}
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
index b81a367d..87fe9a8 100644
--- a/arch/ppc/4xx_io/serial_sicc.c
+++ b/arch/ppc/4xx_io/serial_sicc.c
@@ -1720,7 +1720,7 @@
     return 0;
 }
 
-static struct tty_operations sicc_ops = {
+static const struct tty_operations sicc_ops = {
 	.open = siccuart_open,
 	.close = siccuart_close,
 	.write = siccuart_write,
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index fdd9e7b..077711e 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1345,7 +1345,7 @@
 	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
 	help
 	  This option allows you to set the base virtual address
-	  of the the consistent memory pool.  This pool of virtual
+	  of the consistent memory pool.  This pool of virtual
 	  memory is used to make consistent memory allocations.
 
 config CONSISTENT_START
@@ -1356,7 +1356,7 @@
 	bool "Set custom consistent memory pool size"
 	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
 	help
-	  This option allows you to set the size of the the
+	  This option allows you to set the size of the
 	  consistent memory pool.  This pool of virtual memory
 	  is used to make consistent memory allocations.
 
diff --git a/arch/ppc/boot/include/mpsc_defs.h b/arch/ppc/boot/include/mpsc_defs.h
index 2ce7bbb..9f37e13 100644
--- a/arch/ppc/boot/include/mpsc_defs.h
+++ b/arch/ppc/boot/include/mpsc_defs.h
@@ -1,5 +1,5 @@
 /*
- * drivers/serial/mpsc/mpsc_defs.h
+ * arch/ppc/boot/include/mpsc_defs.h
  *
  * Register definitions for the Marvell Multi-Protocol Serial Controller (MPSC),
  * Serial DMA Controller (SDMA), and Baud Rate Generator (BRG).
diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c
index 29115e0..1640c41 100644
--- a/arch/ppc/boot/utils/mkbugboot.c
+++ b/arch/ppc/boot/utils/mkbugboot.c
@@ -19,36 +19,13 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <netinet/in.h>
 #ifdef __sun__
 #include <inttypes.h>
 #else
 #include <stdint.h>
 #endif
 
-#ifdef __i386__
-#define cpu_to_be32(x) le32_to_cpu(x)
-#define cpu_to_be16(x) le16_to_cpu(x)
-#else
-#define cpu_to_be32(x) (x)
-#define cpu_to_be16(x) (x)
-#endif
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
-     	return (((x & 0x000000ffU) << 24) |
-		((x & 0x0000ff00U) <<  8) |
-		((x & 0x00ff0000U) >>  8) |
-		((x & 0xff000000U) >> 24));
-}
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
-	return (((x & 0x00ff) << 8) |
-		((x & 0xff00) >> 8));
-}
-
 /* size of read buffer */
 #define SIZE 0x1000
 
@@ -62,124 +39,109 @@
 
 #define HEADER_SIZE	sizeof(bug_boot_header_t)
 
-uint32_t copy_image(int32_t in_fd, int32_t out_fd)
+void update_checksum(void *buf, size_t size, uint16_t *sum)
 {
-  uint8_t buf[SIZE];
-  int n;
-  uint32_t image_size = 0;
-  uint8_t zero = 0;
+	uint32_t csum = *sum;
 
-  lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
-
-  /* Copy an image while recording its size */
-  while ( (n = read(in_fd, buf, SIZE)) > 0 )
-    {
-    image_size = image_size + n;
-    write(out_fd, buf, n);
-    }
-
-  /* BUG romboot requires that our size is divisible by 2 */
-  /* align image to 2 byte boundary */
-  if (image_size % 2)
-    {
-    image_size++;
-    write(out_fd, &zero, 1);
-    }
-
-  return image_size;
+	while (size) {
+		csum += *(uint16_t *)buf;
+		if (csum > 0xffff)
+			csum -= 0xffff;
+		buf = (uint16_t *)buf + 1;
+		size -= 2;
+	}
+	*sum = csum;
 }
 
-void write_bugboot_header(int32_t out_fd, uint32_t boot_size)
+uint32_t copy_image(int in_fd, int out_fd, uint16_t *sum)
 {
-  uint8_t header_block[HEADER_SIZE];
-  bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0];
+	uint8_t buf[SIZE];
+	int offset = 0;
+	int n;
+	uint32_t image_size = 0;
 
-  memset(header_block, 0, HEADER_SIZE);
+	lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
 
-  /* Fill in the PPCBUG ROM boot header */
-  strncpy(bbh->magic_word, "BOOT", 4);		/* PPCBUG magic word */
-  bbh->entry_offset = cpu_to_be32(HEADER_SIZE);	/* Entry address */
-  bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2);	/* Routine length */
-  strncpy(bbh->routine_name, "LINUXROM", 8);		/* Routine name   */
+	/* Copy an image while recording its size */
+	while ( (n = read(in_fd, buf + offset, SIZE - offset)) > 0 ) {
+		n += offset;
+		offset = n & 1;
+		n -= offset;
+		image_size = image_size + n;
+		/* who's going to deal with short writes? */
+		write(out_fd, buf, n);
+		update_checksum(buf, n, sum);
+		if (offset)
+			buf[0] = buf[n];
+	}
 
-  /* Output the header and bootloader to the file */
-  write(out_fd, header_block, HEADER_SIZE);
+	/* BUG romboot requires that our size is divisible by 2 */
+	/* align image to 2 byte boundary */
+	if (offset) {
+		image_size += 2;
+		buf[1] = '\0';
+		write(out_fd, buf, 2);
+		update_checksum(buf, 2, sum);
+	}
+	return image_size;
 }
 
-uint16_t calc_checksum(int32_t bug_fd)
+void write_bugboot_header(int out_fd, uint32_t boot_size, uint16_t *sum)
 {
-  uint32_t checksum_var = 0;
-  uint8_t buf[2];
-  int n;
+	static bug_boot_header_t bbh = {
+		.magic_word = "BOOT",
+		.routine_name = "LINUXROM"
+	};
 
-  /* Checksum loop */
-  while ( (n = read(bug_fd, buf, 2) ) )
-  {
-    checksum_var = checksum_var + *(uint16_t *)buf;
+	/* Fill in the PPCBUG ROM boot header */
+	bbh.entry_offset = htonl(HEADER_SIZE);	/* Entry address */
+	bbh.routine_length= htonl(HEADER_SIZE+boot_size+2);	/* Routine length */
 
-    /* If we carry out, mask it and add one to the checksum */
-    if (checksum_var >> 16)
-      checksum_var = (checksum_var & 0x0000ffff) + 1;
-  }
-
-  return checksum_var;
+	/* Output the header and bootloader to the file */
+	write(out_fd, &bbh, sizeof(bug_boot_header_t));
+	update_checksum(&bbh, sizeof(bug_boot_header_t), sum);
 }
 
 int main(int argc, char *argv[])
 {
-  int32_t image_fd, bugboot_fd;
-  int argptr = 1;
-  uint32_t kernel_size = 0;
-  uint16_t checksum = 0;
-  uint8_t bugbootname[256];
+	int image_fd, bugboot_fd;
+	uint32_t kernel_size = 0;
+	uint16_t checksum = 0;
 
-  if ( (argc != 3) )
-  {
-    fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]);
-    exit(-1);
-  }
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]);
+		exit(-1);
+	}
 
-  /* Get file args */
+	/* Get file args */
 
-  /* kernel image file */
-    if ((image_fd = open( argv[argptr] , 0)) < 0)
-      exit(-1);
-  argptr++;
+	/* kernel image file */
+	if ((image_fd = open(argv[1] , 0)) < 0)
+		exit(-1);
 
-  /* bugboot file */
-  if ( !strcmp( argv[argptr], "-" ) )
-    bugboot_fd = 1;			/* stdout */
-  else
-    if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0)
-      exit(-1);
-    else
-      strcpy(bugbootname, argv[argptr]);
-  argptr++;
+	/* bugboot file */
+	if (!strcmp(argv[2], "-"))
+		bugboot_fd = 1;			/* stdout */
+	else if ((bugboot_fd = creat(argv[2] , 0755)) < 0)
+		exit(-1);
 
-  /* Set file position after ROM header block where zImage will be written */
-  lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
+	/* Set file position after ROM header block where zImage will be written */
+	lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
 
-  /* Copy kernel image into bugboot image */
-  kernel_size = copy_image(image_fd, bugboot_fd);
-  close(image_fd);
+	/* Copy kernel image into bugboot image */
+	kernel_size = copy_image(image_fd, bugboot_fd, &checksum);
 
-  /* Set file position to beginning where header/romboot will be written */
-  lseek(bugboot_fd, 0, SEEK_SET);
+	/* Set file position to beginning where header/romboot will be written */
+	lseek(bugboot_fd, 0, SEEK_SET);
 
-  /* Write out BUG header/romboot */
-  write_bugboot_header(bugboot_fd, kernel_size);
+	/* Write out BUG header/romboot */
+	write_bugboot_header(bugboot_fd, kernel_size, &checksum);
 
-  /* Close bugboot file */
-  close(bugboot_fd);
+	/* Write out the calculated checksum */
+	lseek(bugboot_fd, 0, SEEK_END);
+	write(bugboot_fd, &checksum, 2);
 
-  /* Reopen it as read/write */
-  bugboot_fd = open(bugbootname, O_RDWR);
-
-  /* Calculate checksum */
-  checksum = calc_checksum(bugboot_fd);
-
-  /* Write out the calculated checksum */
-  write(bugboot_fd, &checksum, 2);
-
-  return 0;
+	/* Close bugboot file */
+	close(bugboot_fd);
+	return 0;
 }
diff --git a/arch/ppc/boot/utils/mkprep.c b/arch/ppc/boot/utils/mkprep.c
index f6d5a2f..192bb39 100644
--- a/arch/ppc/boot/utils/mkprep.c
+++ b/arch/ppc/boot/utils/mkprep.c
@@ -15,279 +15,227 @@
  * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de>
  */
 
-#include <fcntl.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <strings.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
-     	return (((x & 0x000000ffU) << 24) |
-		((x & 0x0000ff00U) <<  8) |
-		((x & 0x00ff0000U) >>  8) |
-		((x & 0xff000000U) >> 24));
-}
-
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
-	return (((x & 0x00ff) << 8) |
-		((x & 0xff00) >> 8));
-}
-
-#define cpu_to_be32(x) (x)
-#define be32_to_cpu(x) (x)
-#define cpu_to_be16(x) (x)
-#define be16_to_cpu(x) (x)
+#include <stdlib.h>
 
 /* size of read buffer */
 #define SIZE 0x1000
 
-
-typedef unsigned long dword_t;
-typedef unsigned short word_t;
-typedef unsigned char byte_t;
-typedef byte_t block_t[512];
-typedef byte_t page_t[4096];
-
-
 /*
  * Partition table entry
  *  - from the PReP spec
  */
 typedef struct partition_entry {
-  byte_t	boot_indicator;
-  byte_t	starting_head;
-  byte_t	starting_sector;
-  byte_t	starting_cylinder;
+	unsigned char boot_indicator;
+	unsigned char starting_head;
+	unsigned char starting_sector;
+	unsigned char starting_cylinder;
 
-  byte_t	system_indicator;
-  byte_t	ending_head;
-  byte_t	ending_sector;
-  byte_t	ending_cylinder;
+	unsigned char system_indicator;
+	unsigned char ending_head;
+	unsigned char ending_sector;
+	unsigned char ending_cylinder;
 
-  dword_t	beginning_sector;
-  dword_t	number_of_sectors;
+	unsigned char beginning_sector[4];
+	unsigned char number_of_sectors[4];
 } partition_entry_t;
 
 #define BootActive	0x80
 #define SystemPrep	0x41
 
-void copy_image(int , int);
-void write_prep_partition(int , int );
-void write_asm_data( int in, int out );
+void copy_image(FILE *, FILE *);
+void write_prep_partition(FILE *, FILE *);
+void write_asm_data(FILE *, FILE *);
 
 unsigned int elfhdr_size = 65536;
 
 int main(int argc, char *argv[])
 {
-  int in_fd, out_fd;
-  int argptr = 1;
-  unsigned int prep = 0;
-  unsigned int asmoutput = 0;
+	FILE *in, *out;
+	int argptr = 1;
+	int prep = 0;
+	int asmoutput = 0;
 
-  if ( (argc < 3) || (argc > 4) )
-  {
-    fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]);
-    exit(-1);
-  }
+	if (argc < 3 || argc > 4) {
+		fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",
+			argv[0]);
+		exit(-1);
+	}
 
-  /* needs to handle args more elegantly -- but this is a small/simple program */
+/* needs to handle args more elegantly -- but this is a small/simple program */
 
-  /* check for -pbp */
-  if ( !strcmp( argv[argptr], "-pbp" ) )
-  {
-    prep = 1;
-    argptr++;
-  }
+	/* check for -pbp */
+	if (!strcmp(argv[argptr], "-pbp")) {
+		prep = 1;
+		argptr++;
+	}
 
-  /* check for -asm */
-  if ( !strcmp( argv[argptr], "-asm" ) )
-  {
-    asmoutput = 1;
-    argptr++;
-  }
+	/* check for -asm */
+	if (!strcmp(argv[argptr], "-asm")) {
+		asmoutput = 1;
+		argptr++;
+	}
 
-  /* input file */
-  if ( !strcmp( argv[argptr], "-" ) )
-    in_fd = 0;			/* stdin */
-  else
-    if ((in_fd = open( argv[argptr] , 0)) < 0)
-      exit(-1);
-  argptr++;
+	/* input file */
+	if (!strcmp(argv[argptr], "-"))
+		in = stdin;
+	else if (!(in = fopen(argv[argptr], "r")))
+		exit(-1);
+	argptr++;
 
-  /* output file */
-  if ( !strcmp( argv[argptr], "-" ) )
-    out_fd = 1;			/* stdout */
-  else
-    if ((out_fd = creat( argv[argptr] , 0755)) < 0)
-      exit(-1);
-  argptr++;
+	/* output file */
+	if (!strcmp(argv[argptr], "-"))
+		out = stdout;
+	else if (!(out = fopen(argv[argptr], "w")))
+		exit(-1);
+	argptr++;
 
-  /* skip elf header in input file */
-  /*if ( !prep )*/
-  lseek(in_fd, elfhdr_size, SEEK_SET);
+	/* skip elf header in input file */
+	/*if ( !prep )*/
+	fseek(in, elfhdr_size, SEEK_SET);
 
-  /* write prep partition if necessary */
-  if ( prep )
-	  write_prep_partition( in_fd, out_fd );
+	/* write prep partition if necessary */
+	if (prep)
+		write_prep_partition(in, out);
 
-  /* write input image to bootimage */
-  if ( asmoutput )
-	  write_asm_data( in_fd, out_fd );
-  else
-	  copy_image(in_fd, out_fd);
+	/* write input image to bootimage */
+	if (asmoutput)
+		write_asm_data(in, out);
+	else
+		copy_image(in, out);
 
-  return 0;
+	return 0;
 }
 
-void write_prep_partition(int in, int out)
+void store_le32(unsigned int v, unsigned char *p)
 {
-  unsigned char block[512];
-  partition_entry_t pe;
-  dword_t *entry  = (dword_t *)&block[0];
-  dword_t *length = (dword_t *)&block[sizeof(long)];
-  struct stat info;
+	p[0] = v;
+	p[1] = v >>= 8;
+	p[2] = v >>= 8;
+	p[3] = v >> 8;
+}
 
-  if (fstat(in, &info) < 0)
-  {
-    fprintf(stderr,"info failed\n");
-    exit(-1);
-  }
+void write_prep_partition(FILE *in, FILE *out)
+{
+	unsigned char block[512];
+	partition_entry_t pe;
+	unsigned char *entry  = block;
+	unsigned char *length = block + 4;
+	long pos = ftell(in), size;
 
-  bzero( block, sizeof block );
+	if (fseek(in, 0, SEEK_END) < 0) {
+		fprintf(stderr,"info failed\n");
+		exit(-1);
+	}
+	size = ftell(in);
+	if (fseek(in, pos, SEEK_SET) < 0) {
+		fprintf(stderr,"info failed\n");
+		exit(-1);
+	}
 
-  /* set entry point and boot image size skipping over elf header */
-#ifdef __i386__
-  *entry = 0x400/*+65536*/;
-  *length = info.st_size-elfhdr_size+0x400;
-#else
-  *entry = cpu_to_le32(0x400/*+65536*/);
-  *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
-#endif /* __i386__ */
+	memset(block, '\0', sizeof(block));
 
-  /* sets magic number for msdos partition (used by linux) */
-  block[510] = 0x55;
-  block[511] = 0xAA;
+	/* set entry point and boot image size skipping over elf header */
+	store_le32(0x400/*+65536*/, entry);
+	store_le32(size-elfhdr_size+0x400, length);
 
-  /*
-   * Build a "PReP" partition table entry in the boot record
-   *  - "PReP" may only look at the system_indicator
-   */
-  pe.boot_indicator   = BootActive;
-  pe.system_indicator = SystemPrep;
-  /*
-   * The first block of the diskette is used by this "boot record" which
-   * actually contains the partition table. (The first block of the
-   * partition contains the boot image, but I digress...)  We'll set up
-   * one partition on the diskette and it shall contain the rest of the
-   * diskette.
-   */
-  pe.starting_head     = 0;	/* zero-based			     */
-  pe.starting_sector   = 2;	/* one-based			     */
-  pe.starting_cylinder = 0;	/* zero-based			     */
-  pe.ending_head       = 1;	/* assumes two heads		     */
-  pe.ending_sector     = 18;	/* assumes 18 sectors/track	     */
-  pe.ending_cylinder   = 79;	/* assumes 80 cylinders/diskette     */
+	/* sets magic number for msdos partition (used by linux) */
+	block[510] = 0x55;
+	block[511] = 0xAA;
 
-  /*
-   * The "PReP" software ignores the above fields and just looks at
-   * the next two.
-   *   - size of the diskette is (assumed to be)
-   *     (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
-   *   - unlike the above sector numbers, the beginning sector is zero-based!
-   */
+	/*
+	* Build a "PReP" partition table entry in the boot record
+	*  - "PReP" may only look at the system_indicator
+	*/
+	pe.boot_indicator   = BootActive;
+	pe.system_indicator = SystemPrep;
+	/*
+	* The first block of the diskette is used by this "boot record" which
+	* actually contains the partition table. (The first block of the
+	* partition contains the boot image, but I digress...)  We'll set up
+	* one partition on the diskette and it shall contain the rest of the
+	* diskette.
+	*/
+	pe.starting_head     = 0;	/* zero-based			     */
+	pe.starting_sector   = 2;	/* one-based			     */
+	pe.starting_cylinder = 0;	/* zero-based			     */
+	pe.ending_head       = 1;	/* assumes two heads		     */
+	pe.ending_sector     = 18;	/* assumes 18 sectors/track	     */
+	pe.ending_cylinder   = 79;	/* assumes 80 cylinders/diskette     */
+
+	/*
+	* The "PReP" software ignores the above fields and just looks at
+	* the next two.
+	*   - size of the diskette is (assumed to be)
+	*     (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
+	*   - unlike the above sector numbers, the beginning sector is zero-based!
+	*/
 #if 0
-  pe.beginning_sector  = cpu_to_le32(1);
+	store_le32(1, pe.beginning_sector);
 #else
-  /* This has to be 0 on the PowerStack? */
-#ifdef __i386__
-  pe.beginning_sector  = 0;
-#else
-  pe.beginning_sector  = cpu_to_le32(0);
-#endif /* __i386__ */
+	/* This has to be 0 on the PowerStack? */
+	store_le32(0, pe.beginning_sector);
 #endif
 
-#ifdef __i386__
-  pe.number_of_sectors = 2*18*80-1;
-#else
-  pe.number_of_sectors = cpu_to_le32(2*18*80-1);
-#endif /* __i386__ */
+	store_le32(2*18*80-1, pe.number_of_sectors);
 
-  memcpy(&block[0x1BE], &pe, sizeof(pe));
+	memcpy(&block[0x1BE], &pe, sizeof(pe));
 
-  write( out, block, sizeof(block) );
-  write( out, entry, sizeof(*entry) );
-  write( out, length, sizeof(*length) );
-  /* set file position to 2nd sector where image will be written */
-  lseek( out, 0x400, SEEK_SET );
+	fwrite(block, sizeof(block), 1, out);
+	fwrite(entry, 4, 1, out);
+	fwrite(length, 4, 1, out);
+	/* set file position to 2nd sector where image will be written */
+	fseek( out, 0x400, SEEK_SET );
 }
 
 
 
-void
-copy_image(int in, int out)
+void copy_image(FILE *in, FILE *out)
 {
-  char buf[SIZE];
-  int n;
+	char buf[SIZE];
+	int n;
 
-  while ( (n = read(in, buf, SIZE)) > 0 )
-    write(out, buf, n);
+	while ( (n = fread(buf, 1, SIZE, in)) > 0 )
+		fwrite(buf, 1, n, out);
 }
 
 
 void
-write_asm_data( int in, int out )
+write_asm_data(FILE *in, FILE *out)
 {
-  int i, cnt, pos, len;
-  unsigned int cksum, val;
-  unsigned char *lp;
-  unsigned char buf[SIZE];
-  unsigned char str[256];
+	int i, cnt, pos = 0;
+	unsigned int cksum = 0, val;
+	unsigned char *lp;
+	unsigned char buf[SIZE];
+	size_t len;
 
-  write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
-	 strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
-  pos = 0;
-  cksum = 0;
-  while ((len = read(in, buf, sizeof(buf))) > 0)
-  {
-    cnt = 0;
-    lp = (unsigned char *)buf;
-    len = (len + 3) & ~3;  /* Round up to longwords */
-    for (i = 0;  i < len;  i += 4)
-    {
-      if (cnt == 0)
-      {
-	write( out, "\t.long\t", strlen( "\t.long\t" ) );
-      }
-      sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
-      write( out, str, strlen(str) );
-      val = *(unsigned long *)lp;
-      cksum ^= val;
-      lp += 4;
-      if (++cnt == 4)
-      {
-	cnt = 0;
-	sprintf( str, " # %x \n", pos+i-12);
-	write( out, str, strlen(str) );
-      } else
-      {
-	write( out, ",", 1 );
-      }
-    }
-    if (cnt)
-    {
-      write( out, "0\n", 2 );
-    }
-    pos += len;
-  }
-  sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
-  write( out, str, strlen(str) );
-
-  fprintf(stderr, "cksum = %x\n", cksum);
+	fputs("\t.data\n\t.globl input_data\ninput_data:\n", out);
+	while ((len = fread(buf, 1, sizeof(buf), in)) > 0) {
+		cnt = 0;
+		lp = buf;
+		/* Round up to longwords */
+		while (len & 3)
+			buf[len++] = '\0';
+		for (i = 0;  i < len;  i += 4) {
+			if (cnt == 0)
+				fputs("\t.long\t", out);
+			fprintf(out, "0x%02X%02X%02X%02X",
+				lp[0], lp[1], lp[2], lp[3]);
+			val = *(unsigned long *)lp;
+			cksum ^= val;
+			lp += 4;
+			if (++cnt == 4) {
+				cnt = 0;
+				fprintf(out, " # %x \n", pos+i-12);
+			} else {
+				fputs(",", out);
+			}
+		}
+		if (cnt)
+			fputs("0\n", out);
+		pos += len;
+	}
+	fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
+	fprintf(stderr, "cksum = %x\n", cksum);
 }
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 50b4bbd..5f66840 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -942,20 +942,16 @@
 	addi	r1,r1,16
 	blr
 
+_GLOBAL(kernel_execve)
+	li	r0,__NR_execve
+	sc
+	bnslr
+	neg	r3,r3
+	blr
+
 /*
  * This routine is just here to keep GCC happy - sigh...
  */
 _GLOBAL(__main)
 	blr
 
-#define SYSCALL(name) \
-_GLOBAL(name) \
-	li	r0,__NR_##name; \
-	sc; \
-	bnslr; \
-	lis	r4,errno@ha; \
-	stw	r3,errno@l(r4); \
-	li	r3,-1; \
-	blr
-
-SYSCALL(execve)
diff --git a/arch/ppc/platforms/4xx/xparameters/xparameters.h b/arch/ppc/platforms/4xx/xparameters/xparameters.h
index cd7d0e7..66ec5f3 100644
--- a/arch/ppc/platforms/4xx/xparameters/xparameters.h
+++ b/arch/ppc/platforms/4xx/xparameters/xparameters.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/xparameters.h
+ * arch/ppc/platforms/4xx/xparameters/xparameters.h
  *
  * This file includes the correct xparameters.h for the CONFIG'ed board plus
  * fixups to translate board specific XPAR values to a common set of names
diff --git a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig
index 7ddd331..6f2d0ad 100644
--- a/arch/ppc/platforms/85xx/Kconfig
+++ b/arch/ppc/platforms/85xx/Kconfig
@@ -24,12 +24,12 @@
 config MPC8548_CDS
 	bool "Freescale MPC8548 CDS"
 	help
-	  This option enablese support for the MPC8548 CDS evaluation board.
+	  This option enables support for the MPC8548 CDS evaluation board.
 
 config MPC8555_CDS
 	bool "Freescale MPC8555 CDS"
 	help
-	  This option enablese support for the MPC8555 CDS evaluation board.
+	  This option enables support for the MPC8555 CDS evaluation board.
 
 config MPC8560_ADS
 	bool "Freescale MPC8560 ADS"
@@ -51,22 +51,22 @@
 config TQM8540
 	bool "TQ Components TQM8540"
 	help
-	  This option enablese support for the TQ Components TQM8540 board.
+	  This option enables support for the TQ Components TQM8540 board.
 
 config TQM8541
 	bool "TQ Components TQM8541"
 	help
-	  This option enablese support for the TQ Components TQM8541 board.
+	  This option enables support for the TQ Components TQM8541 board.
 
 config TQM8555
 	bool "TQ Components TQM8555"
 	help
-	  This option enablese support for the TQ Components TQM8555 board.
+	  This option enables support for the TQ Components TQM8555 board.
 
 config TQM8560
 	bool "TQ Components TQM8560"
 	help
-	  This option enablese support for the TQ Components TQM8560 board.
+	  This option enables support for the TQ Components TQM8560 board.
 
 endchoice
 
@@ -94,7 +94,7 @@
 	default y
 
 config 85xx_PCI2
-	bool "Supprt for 2nd PCI host controller"
+	bool "Support for 2nd PCI host controller"
 	depends on MPC8555_CDS
 	default y
 
diff --git a/arch/ppc/platforms/lopec.h b/arch/ppc/platforms/lopec.h
index 5490edb..d597b68 100644
--- a/arch/ppc/platforms/lopec.h
+++ b/arch/ppc/platforms/lopec.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/lopec_serial.h
+ * arch/ppc/platforms/lopec.h
  *
  * Definitions for Motorola LoPEC board.
  *
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
index 2a35fe2..d7b3a6a 100644
--- a/arch/ppc/platforms/mpc8272ads_setup.c
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/82xx/pq2ads_pd.c
+ * arch/ppc/platforms/mpc8272ads_setup.c
  *
  * MPC82xx Board-specific PlatformDevice descriptions
  *
@@ -103,7 +103,7 @@
 	},
 };
 
-static void init_fcc1_ioports(void)
+static void init_fcc1_ioports(struct fs_platform_info*)
 {
 	struct io_port *io;
 	u32 tempval;
@@ -144,7 +144,7 @@
 	iounmap(immap);
 }
 
-static void init_fcc2_ioports(void)
+static void init_fcc2_ioports(struct fs_platform_info*)
 {
 	cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
 	u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
@@ -229,7 +229,7 @@
 	}
 }
 
-static void init_scc1_uart_ioports(void)
+static void init_scc1_uart_ioports(struct fs_uart_platform_info*)
 {
 	cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
 
@@ -246,7 +246,7 @@
 	iounmap(immap);
 }
 
-static void init_scc4_uart_ioports(void)
+static void init_scc4_uart_ioports(struct fs_uart_platform_info*)
 {
 	cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
 
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
index e12cece..5f130dc 100644
--- a/arch/ppc/platforms/mpc866ads_setup.c
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -137,7 +137,7 @@
 	iounmap(bcsr_io);
 }
 
-static void setup_fec1_ioports(void)
+static void setup_fec1_ioports(struct fs_platform_info*)
 {
 	immap_t *immap = (immap_t *) IMAP_ADDR;
 
@@ -145,7 +145,7 @@
 	setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
 }
 
-static void setup_scc1_ioports(void)
+static void setup_scc1_ioports(struct fs_platform_info*)
 {
 	immap_t *immap = (immap_t *) IMAP_ADDR;
 	unsigned *bcsr_io;
@@ -194,7 +194,7 @@
 
 }
 
-static void setup_smc1_ioports(void)
+static void setup_smc1_ioports(struct fs_uart_platform_info*)
 {
 	immap_t *immap = (immap_t *) IMAP_ADDR;
 	unsigned *bcsr_io;
@@ -216,7 +216,7 @@
 
 }
 
-static void setup_smc2_ioports(void)
+static void setup_smc2_ioports(struct fs_uart_platform_info*)
 {
 	immap_t *immap = (immap_t *) IMAP_ADDR;
 	unsigned *bcsr_io;
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
index 5dfa4e6..0229314 100644
--- a/arch/ppc/platforms/mpc885ads_setup.c
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -1,4 +1,4 @@
-/*arch/ppc/platforms/mpc885ads-setup.c
+/*arch/ppc/platforms/mpc885ads_setup.c
  *
  * Platform setup for the Freescale mpc885ads board
  *
@@ -161,7 +161,7 @@
 #endif
 }
 
-static void setup_fec1_ioports(void)
+static void setup_fec1_ioports(struct fs_platform_info*)
 {
 	immap_t *immap = (immap_t *) IMAP_ADDR;
 
@@ -181,7 +181,7 @@
 	clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
 }
 
-static void setup_fec2_ioports(void)
+static void setup_fec2_ioports(struct fs_platform_info*)
 {
 	immap_t *immap = (immap_t *) IMAP_ADDR;
 
@@ -193,7 +193,7 @@
 	clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
 }
 
-static void setup_scc3_ioports(void)
+static void setup_scc3_ioports(struct fs_platform_info*)
 {
 	immap_t *immap = (immap_t *) IMAP_ADDR;
 	unsigned *bcsr_io;
@@ -315,7 +315,7 @@
 	mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
 }
 
-static void setup_smc1_ioports(void)
+static void setup_smc1_ioports(struct fs_uart_platform_info*)
 {
         immap_t *immap = (immap_t *) IMAP_ADDR;
         unsigned *bcsr_io;
@@ -335,7 +335,7 @@
         clrbits16(&immap->im_cpm.cp_pbodr, iobits);
 }
 
-static void setup_smc2_ioports(void)
+static void setup_smc2_ioports(struct fs_uart_platform_info*)
 {
         immap_t *immap = (immap_t *) IMAP_ADDR;
         unsigned *bcsr_io;
diff --git a/arch/ppc/platforms/mvme5100.h b/arch/ppc/platforms/mvme5100.h
index edd4794..9e2a09e 100644
--- a/arch/ppc/platforms/mvme5100.h
+++ b/arch/ppc/platforms/mvme5100.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/mvme5100.h
+ * arch/ppc/platforms/mvme5100.h
  *
  * Definitions for Motorola MVME5100.
  *
diff --git a/arch/ppc/platforms/powerpmc250.h b/arch/ppc/platforms/powerpmc250.h
index 41a6dc8..d33ad8dc 100644
--- a/arch/ppc/platforms/powerpmc250.h
+++ b/arch/ppc/platforms/powerpmc250.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/powerpmc250.h
+ * arch/ppc/platforms/powerpmc250.h
  *
  * Definitions for Force PowerPMC-250 board support
  *
diff --git a/arch/ppc/platforms/prpmc750.h b/arch/ppc/platforms/prpmc750.h
index 015b4f5..4c7adcc 100644
--- a/arch/ppc/platforms/prpmc750.h
+++ b/arch/ppc/platforms/prpmc750.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/prpmc750.h
+ * arch/ppc/platforms/prpmc750.h
  *
  * Definitions for Motorola PrPMC750 board support
  *
diff --git a/arch/ppc/platforms/prpmc800.h b/arch/ppc/platforms/prpmc800.h
index e53ec9b..26f604e 100644
--- a/arch/ppc/platforms/prpmc800.h
+++ b/arch/ppc/platforms/prpmc800.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/prpmc800.h
+ * arch/ppc/platforms/prpmc800.h
  *
  * Definitions for Motorola PrPMC800 board support
  *
diff --git a/arch/ppc/platforms/spruce.h b/arch/ppc/platforms/spruce.h
index a31ff7e..f1f96f1 100644
--- a/arch/ppc/platforms/spruce.h
+++ b/arch/ppc/platforms/spruce.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/spruce.h
+ * arch/ppc/platforms/spruce.h
  *
  * Definitions for IBM Spruce reference board support
  *
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index c46e3d4..e15e148 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -357,11 +357,16 @@
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+	compat_ino_t ino;
 	int err;
 
 	if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
+	ino = stat->ino;
+	if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+		return -EOVERFLOW;
+
 	err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
 	err |= put_user(stat->ino, &statbuf->st_ino);
 	err |= put_user(stat->mode, &statbuf->st_mode);
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index ca28fb0..4d9ff5c 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -369,11 +369,12 @@
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kretprobe_instance *ri = NULL;
-	struct hlist_head *head;
+	struct hlist_head *head, empty_rp;
 	struct hlist_node *node, *tmp;
 	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
 
+	INIT_HLIST_HEAD(&empty_rp);
 	spin_lock_irqsave(&kretprobe_lock, flags);
 	head = kretprobe_inst_table_head(current);
 
@@ -399,7 +400,7 @@
 			ri->rp->handler(ri, regs);
 
 		orig_ret_address = (unsigned long)ri->ret_addr;
-		recycle_rp_inst(ri);
+		recycle_rp_inst(ri, &empty_rp);
 
 		if (orig_ret_address != trampoline_address) {
 			/*
@@ -417,6 +418,10 @@
 	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	preempt_enable_no_resched();
 
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
 	/*
 	 * By returning a non-zero value, we are telling
 	 * kprobe_handler() that we don't want the post_handler
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index e351780..584ed95 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -27,6 +27,7 @@
 #include <linux/file.h>
 #include <linux/utsname.h>
 #include <linux/personality.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -266,3 +267,22 @@
 	return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register const char *__arg1 asm("2") = filename;
+	register char *const*__arg2 asm("3") = argv;
+	register char *const*__arg3 asm("4") = envp;
+	register long __svcres asm("2");
+	asm volatile(
+		"svc %b1"
+		: "=d" (__svcres)
+		: "i" (__NR_execve),
+		  "0" (__arg1),
+		  "d" (__arg2),
+		  "d" (__arg3) : "memory");
+	return __svcres;
+}
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 1cc5c9b..f6a0c44 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -377,7 +377,7 @@
 	default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
 	default "60000000" if CPU_SUBTYPE_SH7751
 	default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
-			      CPU_SUBTYPE_SH7760
+			      CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705
 	default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
 	default "66000000" if CPU_SUBTYPE_SH4_202
 	help
diff --git a/arch/sh/boards/bigsur/io.c b/arch/sh/boards/bigsur/io.c
index 6835381..23071f9 100644
--- a/arch/sh/boards/bigsur/io.c
+++ b/arch/sh/boards/bigsur/io.c
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_bigsur.c
+ * arch/sh/boards/bigsur/io.c
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  * Derived from io_hd64465.h, which bore the message:
diff --git a/arch/sh/boards/bigsur/led.c b/arch/sh/boards/bigsur/led.c
index 6b08c0e..d221439 100644
--- a/arch/sh/boards/bigsur/led.c
+++ b/arch/sh/boards/bigsur/led.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_bigsur.c
+ * linux/arch/sh/boards/bigsur/led.c
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  * Derived from led_se.c and led.c, which bore the message:
diff --git a/arch/sh/boards/ec3104/io.c b/arch/sh/boards/ec3104/io.c
index a70928c..2f86394 100644
--- a/arch/sh/boards/ec3104/io.c
+++ b/arch/sh/boards/ec3104/io.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/io_ec3104.c
+ * linux/arch/sh/boards/ec3104/io.c
  *  EC3104 companion chip support
  *
  * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c
index ad0e712..75f91aa 100644
--- a/arch/sh/boards/hp6xx/hp6xx_apm.c
+++ b/arch/sh/boards/hp6xx/hp6xx_apm.c
@@ -6,7 +6,6 @@
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License.
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/apm_bios.h>
 #include <linux/kernel.h>
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c
index 0e501bc..83d3272 100644
--- a/arch/sh/boards/hp6xx/pm.c
+++ b/arch/sh/boards/hp6xx/pm.c
@@ -6,7 +6,6 @@
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License.
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c
index 60ab17a..2d3a5b4 100644
--- a/arch/sh/boards/hp6xx/setup.c
+++ b/arch/sh/boards/hp6xx/setup.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/hp6xx/hp680/setup.c
+ * linux/arch/sh/boards/hp6xx/setup.c
  *
  * Copyright (C) 2002 Andriy Skulysh
  *
diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c
index a006d64..8f2e1c6 100644
--- a/arch/sh/boards/landisk/irq.c
+++ b/arch/sh/boards/landisk/irq.c
@@ -14,8 +14,6 @@
  * modified by kogiidena
  * 2005.03.03
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <asm/io.h>
@@ -83,7 +81,7 @@
 static void make_landisk_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-	irq_desc[irq].handler = &landisk_irq_type;
+	irq_desc[irq].chip = &landisk_irq_type;
 	disable_landisk_irq(irq);
 }
 
diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c
index e75cb57..0b7bee1 100644
--- a/arch/sh/boards/landisk/landisk_pwb.c
+++ b/arch/sh/boards/landisk/landisk_pwb.c
@@ -11,8 +11,6 @@
  *
  * LED control drive function added by kogiidena
  */
-
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c
index 35ba726..0a9a2a2 100644
--- a/arch/sh/boards/landisk/rtc.c
+++ b/arch/sh/boards/landisk/rtc.c
@@ -8,8 +8,6 @@
  * modifed by kogiidena
  * 2005.09.16
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c
index 127b9e0..122d699 100644
--- a/arch/sh/boards/landisk/setup.c
+++ b/arch/sh/boards/landisk/setup.c
@@ -16,7 +16,6 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/mm.h>
diff --git a/arch/sh/boards/mpc1211/led.c b/arch/sh/boards/mpc1211/led.c
index 1fe3692..8df1591 100644
--- a/arch/sh/boards/mpc1211/led.c
+++ b/arch/sh/boards/mpc1211/led.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_mpc1211.c
+ * linux/arch/sh/boards/mpc1211/led.c
  *
  * Copyright (C) 2001  Saito.K & Jeanne
  *
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c
index 8eb5d43..01c10fa 100644
--- a/arch/sh/boards/mpc1211/setup.c
+++ b/arch/sh/boards/mpc1211/setup.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/board/mpc1211/setup.c
+ * linux/arch/sh/boards/mpc1211/setup.c
  *
  * Copyright (C) 2002  Saito.K & Jeanne,  Fujii.Y
  *
diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c
index 9ea1136..51f3f65 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/io.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/io.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/io_hs7751rvoip.c
+ * linux/arch/sh/boards/renesas/hs7751rvoip/io.c
  *
  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
  * Based largely on io_se.c.
diff --git a/arch/sh/boards/renesas/hs7751rvoip/pci.c b/arch/sh/boards/renesas/hs7751rvoip/pci.c
index 7e5786b..1c0ddee 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/pci.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/pci.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-hs7751rvoip.c
+ * linux/arch/sh/boards/renesas/hs7751rvoip/pci.c
  *
  * Author:  Ian DaSilva (idasilva@mvista.com)
  *
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
index 61d5e5d..2d960e9 100644
--- a/arch/sh/boards/renesas/r7780rp/irq.c
+++ b/arch/sh/boards/renesas/r7780rp/irq.c
@@ -8,8 +8,6 @@
  * Modified for R7780RP-1 by
  * Atom Create Engineering Co., Ltd. 2002.
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <asm/io.h>
@@ -83,7 +81,7 @@
 static void make_r7780rp_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-	irq_desc[irq].handler = &r7780rp_irq_type;
+	irq_desc[irq].chip = &r7780rp_irq_type;
 	disable_r7780rp_irq(irq);
 }
 
diff --git a/arch/sh/boards/renesas/r7780rp/led.c b/arch/sh/boards/renesas/r7780rp/led.c
index 9f02766..6a00a25 100644
--- a/arch/sh/boards/renesas/r7780rp/led.c
+++ b/arch/sh/boards/renesas/r7780rp/led.c
@@ -6,8 +6,6 @@
  *
  * This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code.
  */
-
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/r7780rp/r7780rp.h>
diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c
index e14a13d..a7ce66c 100644
--- a/arch/sh/boards/renesas/rts7751r2d/led.c
+++ b/arch/sh/boards/renesas/rts7751r2d/led.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_rts7751r2d.c
+ * linux/arch/sh/boards/renesas/rts7751r2d/led.c
  *
  * Copyright (C) Atom Create Engineering Co., Ltd.
  *
diff --git a/arch/sh/boards/renesas/systemh/io.c b/arch/sh/boards/renesas/systemh/io.c
index cde6e5d..1b767e1 100644
--- a/arch/sh/boards/renesas/systemh/io.c
+++ b/arch/sh/boards/renesas/systemh/io.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/systemh/io.c
+ * linux/arch/sh/boards/renesas/systemh/io.c
  *
  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
  * Based largely on io_se.c.
diff --git a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c
index 8d016da..0ba2fe6 100644
--- a/arch/sh/boards/renesas/systemh/irq.c
+++ b/arch/sh/boards/renesas/systemh/irq.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/systemh/irq.c
+ * linux/arch/sh/boards/renesas/systemh/irq.c
  *
  * Copyright (C) 2000  Kazumoto Kojima
  *
diff --git a/arch/sh/boards/renesas/systemh/setup.c b/arch/sh/boards/renesas/systemh/setup.c
index a8467bf..9361176 100644
--- a/arch/sh/boards/renesas/systemh/setup.c
+++ b/arch/sh/boards/renesas/systemh/setup.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/systemh/setup.c
+ * linux/arch/sh/boards/renesas/systemh/setup.c
  *
  * Copyright (C) 2000  Kazumoto Kojima
  * Copyright (C) 2003  Paul Mundt
@@ -53,6 +53,6 @@
 	.mv_outsw		= sh7751systemh_outsw,
 	.mv_outsl		= sh7751systemh_outsl,
 
-	.mv_init_irq		= sh7751system_init_irq,
+	.mv_init_irq		= sh7751systemh_init_irq,
 };
 ALIAS_MV(7751systemh)
diff --git a/arch/sh/boards/se/7343/io.c b/arch/sh/boards/se/7343/io.c
index 646661a..3a6d114 100644
--- a/arch/sh/boards/se/7343/io.c
+++ b/arch/sh/boards/se/7343/io.c
@@ -4,8 +4,6 @@
  * I/O routine for SH-Mobile3AS 7343 SolutionEngine.
  *
  */
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <asm/io.h>
 #include <asm/mach/se7343.h>
diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c
index b41e3d4..288b62f 100644
--- a/arch/sh/boards/se/7343/irq.c
+++ b/arch/sh/boards/se/7343/irq.c
@@ -2,8 +2,6 @@
  * arch/sh/boards/se/7343/irq.c
  *
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -73,7 +71,7 @@
 make_intreq_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-	irq_desc[irq].handler = &intreq_irq_type;
+	irq_desc[irq].chip = &intreq_irq_type;
 	disable_intreq_irq(irq);
 }
 
diff --git a/arch/sh/boards/se/7343/led.c b/arch/sh/boards/se/7343/led.c
index 6a439cf..6b39e19 100644
--- a/arch/sh/boards/se/7343/led.c
+++ b/arch/sh/boards/se/7343/led.c
@@ -2,8 +2,6 @@
  * arch/sh/boards/se/7343/led.c
  *
  */
-
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <asm/mach/se7343.h>
 
diff --git a/arch/sh/boards/se/7343/setup.c b/arch/sh/boards/se/7343/setup.c
index 7873222..c7d17fe 100644
--- a/arch/sh/boards/se/7343/setup.c
+++ b/arch/sh/boards/se/7343/setup.c
@@ -1,4 +1,3 @@
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <asm/machvec.h>
diff --git a/arch/sh/boards/se/770x/led.c b/arch/sh/boards/se/770x/led.c
index daf7b1e..d93dd83 100644
--- a/arch/sh/boards/se/770x/led.c
+++ b/arch/sh/boards/se/770x/led.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_se.c
+ * linux/arch/sh/boards/se/770x/led.c
  *
  * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
  *
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
index f3f82b7..a1d51d5 100644
--- a/arch/sh/boards/se/770x/setup.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -8,13 +8,10 @@
  *
  */
 #include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <asm/io.h>
-#include <asm/se.h>
-#include <asm/smc37c93x.h>
 #include <asm/machvec.h>
+#include <asm/se.h>
+#include <asm/io.h>
+#include <asm/smc37c93x.h>
 
 void heartbeat_se(void);
 void init_se_IRQ(void);
diff --git a/arch/sh/boards/se/7751/led.c b/arch/sh/boards/se/7751/led.c
index ff0355d..de4194d 100644
--- a/arch/sh/boards/se/7751/led.c
+++ b/arch/sh/boards/se/7751/led.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_se.c
+ * linux/arch/sh/boards/se/7751/led.c
  *
  * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
  *
diff --git a/arch/sh/boards/se/7751/pci.c b/arch/sh/boards/se/7751/pci.c
index 3ee0301..203b292 100644
--- a/arch/sh/boards/se/7751/pci.c
+++ b/arch/sh/boards/se/7751/pci.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-7751se.c
+ * linux/arch/sh/boards/se/7751/pci.c
  *
  * Author:  Ian DaSilva (idasilva@mvista.com)
  *
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
index 73e8263..f7e1dd3 100644
--- a/arch/sh/boards/se/7751/setup.c
+++ b/arch/sh/boards/se/7751/setup.c
@@ -8,12 +8,10 @@
  * Modified for 7751 Solution Engine by
  * Ian da Silva and Jeremy Siegel, 2001.
  */
-
 #include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/ide.h>
-#include <asm/io.h>
+#include <asm/machvec.h>
 #include <asm/se7751.h>
+#include <asm/io.h>
 
 void heartbeat_7751se(void);
 void init_7751se_IRQ(void);
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
index 6c31058..137e2ba 100644
--- a/arch/sh/boards/sh03/setup.c
+++ b/arch/sh/boards/sh03/setup.c
@@ -7,6 +7,7 @@
 
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/pci.h>
 #include <asm/io.h>
 #include <asm/rtc.h>
 #include <asm/sh03/io.h>
diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c
index 4836b94..83419bf 100644
--- a/arch/sh/boards/superh/microdev/io.c
+++ b/arch/sh/boards/superh/microdev/io.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/io_microdev.c
+ * linux/arch/sh/boards/superh/microdev/io.c
  *
  * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
  * Copyright (C) 2003, 2004 SuperH, Inc.
diff --git a/arch/sh/boards/superh/microdev/led.c b/arch/sh/boards/superh/microdev/led.c
index a38f535..36e54b4 100644
--- a/arch/sh/boards/superh/microdev/led.c
+++ b/arch/sh/boards/superh/microdev/led.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_microdev.c
+ * linux/arch/sh/boards/superh/microdev/led.c
  *
  * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
  * Copyright (C) 2003 Richard Curnow (Richard.Curnow@superh.com)
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
new file mode 100644
index 0000000..b6718de
--- /dev/null
+++ b/arch/sh/boot/.gitignore
@@ -0,0 +1 @@
+zImage
diff --git a/arch/sh/configs/adx_defconfig b/arch/sh/configs/adx_defconfig
deleted file mode 100644
index 353bfdc..0000000
--- a/arch/sh/configs/adx_defconfig
+++ /dev/null
@@ -1,539 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:26 2005
-#
-CONFIG_SUPERH=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-CONFIG_SH_ADX=y
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
-CONFIG_CPU_SH4=y
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-# CONFIG_CPU_SUBTYPE_SH7708 is not set
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-CONFIG_CPU_SUBTYPE_SH7750=y
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x00400000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_CF_ENABLER=y
-# CONFIG_CF_AREA5 is not set
-CONFIG_CF_AREA6=y
-CONFIG_CF_BASE_ADDR=0xb8000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=50000000
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-# CONFIG_HD6446X_SERIES is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# SH initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# 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_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_SH_SCI is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# 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
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
-CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/cqreek_defconfig b/arch/sh/configs/cqreek_defconfig
deleted file mode 100644
index 614662a..0000000
--- a/arch/sh/configs/cqreek_defconfig
+++ /dev/null
@@ -1,533 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:38 2005
-#
-CONFIG_SUPERH=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-CONFIG_SH_CQREEK=y
-# CONFIG_SH_DMIDA is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-CONFIG_CPU_SUBTYPE_SH7708=y
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-# CONFIG_CPU_SUBTYPE_SH7750 is not set
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_DSP=y
-CONFIG_SH_ADC=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=1193182
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-# CONFIG_HD6446X_SERIES is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# SH initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# 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_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_SH_SCI is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# 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
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
-CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 776c190..8b6b5a7 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -1,50 +1,63 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:40 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 10:51:55 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -52,82 +65,158 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 CONFIG_SH_DREAMCAST=y
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 CONFIG_CPU_SUBTYPE_SH7750=y
+CONFIG_CPU_SUBTYPE_SH7091=y
+CONFIG_CPU_SUBTYPE_SH7750R=y
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_HUGETLB_PAGE_SIZE_64K=y
-# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
-CONFIG_SH_OCRAM=y
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 CONFIG_SH_STORE_QUEUES=y
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=49876504
 
 #
 # CPU Frequency scaling
 #
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
@@ -137,8 +226,8 @@
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-CONFIG_CPU_FREQ_TABLE=y
-CONFIG_SH_CPU_FREQ=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_SH_CPU_FREQ is not set
 
 #
 # DMA support
@@ -154,14 +243,35 @@
 # CONFIG_HD6446X_SERIES is not set
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-CONFIG_MAPLE=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 panic=3"
+
+#
+# Bus options
+#
 CONFIG_PCI=y
 # CONFIG_SH_PCIDMA_NONCOHERENT is not set
 CONFIG_PCI_AUTO=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -169,10 +279,6 @@
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
-#
-
-#
 # PCI Hotplug Support
 #
 # CONFIG_HOTPLUG_PCI is not set
@@ -185,9 +291,92 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -199,6 +388,12 @@
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -217,7 +412,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -226,21 +420,9 @@
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=1024
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -251,7 +433,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -261,6 +450,7 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -273,70 +463,8 @@
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-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
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -349,6 +477,11 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -356,6 +489,7 @@
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -398,15 +532,22 @@
 # 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_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -428,6 +569,8 @@
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -443,6 +586,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -457,19 +601,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 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 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
@@ -478,22 +609,33 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_MAPLE is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_MAPLE is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -505,9 +647,11 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -528,13 +672,14 @@
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_SH_WDT=y
+# CONFIG_SH_WDT_MMAP is not set
 
 #
 # PCI-based Watchdog Cards
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -547,14 +692,35 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -564,6 +730,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -573,7 +740,13 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -583,9 +756,10 @@
 # CONFIG_FB_IMSTT is not set
 CONFIG_FB_PVR2=y
 # CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
@@ -601,18 +775,20 @@
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 # CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 is not set
 # CONFIG_FONT_MINI_4x6 is not set
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 
 #
 # Logo configuration
@@ -634,12 +810,13 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -653,29 +830,64 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
+# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -695,16 +907,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -716,7 +926,7 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
+# CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -726,22 +936,14 @@
 #
 # Network File Systems
 #
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # 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
@@ -758,14 +960,19 @@
 # Profiling support
 #
 CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
+# CONFIG_OPROFILE is not set
 
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -782,13 +989,10 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # 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
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index b36f102..b931d9b 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -1,21 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-sh
-# Wed Jan  4 15:32:56 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:10:06 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -27,26 +27,31 @@
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-CONFIG_HOTPLUG=y
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -56,7 +61,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -77,29 +85,26 @@
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 CONFIG_SH_HP6XX=y
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 # CONFIG_SH_LANDISK is not set
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -117,9 +122,11 @@
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 CONFIG_CPU_SUBTYPE_SH7709=y
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -142,14 +149,23 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x00400000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -158,6 +174,7 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -165,22 +182,22 @@
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
+# CONFIG_SH_FPU_EMU is not set
 # CONFIG_SH_DSP is not set
 CONFIG_SH_ADC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
 CONFIG_SH_PCLK_FREQ=22110000
 
 #
@@ -194,7 +211,6 @@
 CONFIG_SH_DMA=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=4
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
-# CONFIG_DMA_PAGE_OPS is not set
 
 #
 # Companion Chips
@@ -209,9 +225,15 @@
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -241,8 +263,6 @@
 #
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
-CONFIG_HD64461_PCMCIA=y
-CONFIG_HD64461_PCMCIA_SOCKETS=1
 CONFIG_PCMCIA_PROBE=y
 
 #
@@ -257,6 +277,15 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+CONFIG_APM=y
+
+#
 # Networking
 #
 # CONFIG_NET is not set
@@ -271,6 +300,7 @@
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -299,6 +329,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 
@@ -315,7 +346,7 @@
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -325,7 +356,6 @@
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
@@ -337,6 +367,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -356,19 +392,12 @@
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
 
 #
-# Network device support
-#
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
 # ISDN subsystem
 #
 
@@ -381,6 +410,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -390,17 +420,33 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_TSDEV=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
 #
 # Input Device Drivers
 #
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_HP600=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -409,6 +455,7 @@
 CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
@@ -418,6 +465,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -442,7 +490,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -471,15 +519,23 @@
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -487,13 +543,10 @@
 #
 
 #
-# Multimedia Capabilities Port drivers
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -502,11 +555,13 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_EPSON1355 is not set
@@ -553,7 +608,7 @@
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 CONFIG_SOUND_SH_DAC_AUDIO=y
@@ -564,6 +619,7 @@
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -580,12 +636,42 @@
 # CONFIG_MMC is not set
 
 #
-# InfiniBand support
+# LED devices
 #
-# CONFIG_INFINIBAND is not set
+# CONFIG_NEW_LEDS is not set
 
 #
-# SN Devices
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
@@ -595,7 +681,6 @@
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -603,6 +688,7 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -630,12 +716,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -713,9 +800,14 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_KGDB is not set
 
@@ -731,13 +823,10 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/hs7751rvoip_defconfig b/arch/sh/configs/hs7751rvoip_defconfig
new file mode 100644
index 0000000..e1a886d
--- /dev/null
+++ b/arch/sh/configs/hs7751rvoip_defconfig
@@ -0,0 +1,908 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18
+# Tue Oct  3 13:04:52 2006
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_EC3104 is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_BIGSUR is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+CONFIG_SH_HS7751RVOIP=y
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+
+#
+# HS7751RVoIP options
+#
+CONFIG_HS7751RVOIP_CODEC=y
+CONFIG_SH_PCLK_FREQ=60000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=64M console=ttySC1,115200 root=/dev/hda1"
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=1
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_SMC91X is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# 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
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index 6b43316..238c0f1 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,21 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-sh
-# Sun Sep 11 13:00:46 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:14:13 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -26,29 +26,36 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_EMBEDDED is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -56,40 +63,57 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 CONFIG_SH_LANDISK=y
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -107,9 +131,11 @@
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -132,14 +158,23 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -147,6 +182,8 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -154,21 +191,21 @@
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x04000000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
 CONFIG_SH_PCLK_FREQ=33333333
 
 #
@@ -192,9 +229,15 @@
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 CONFIG_KEXEC=y
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -212,7 +255,7 @@
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -228,6 +271,11 @@
 # PC-card bridges
 #
 CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
 # CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
@@ -248,6 +296,11 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -255,9 +308,13 @@
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -279,20 +336,32 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
 #
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
@@ -308,66 +377,9 @@
 CONFIG_IP_NF_TFTP=m
 CONFIG_IP_NF_AMANDA=m
 # CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
 CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-# CONFIG_IP_NF_MATCH_CONNBYTES is not set
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-# CONFIG_IP_NF_MATCH_STRING is not set
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_TARGET_NFQUEUE is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-# CONFIG_IP_NF_TARGET_TTL is not set
-CONFIG_IP_NF_TARGET_CONNMARK=m
-# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
 
 #
 # DCCP Configuration (EXPERIMENTAL)
@@ -378,6 +390,11 @@
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -389,11 +406,13 @@
 # CONFIG_DEV_APPLETALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -414,6 +433,7 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -451,17 +471,9 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -518,7 +530,6 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
@@ -531,6 +542,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -551,16 +563,18 @@
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -569,12 +583,14 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -584,20 +600,14 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
@@ -616,6 +626,11 @@
 # CONFIG_PCMCIA_SYM53C500 is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Old CD-ROM drivers (not SCSI, not IDE)
 #
 # CONFIG_CD_NO_IDESCSI is not set
@@ -629,8 +644,7 @@
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -694,7 +708,6 @@
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
-# CONFIG_NE2000 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -730,10 +743,12 @@
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -741,6 +756,7 @@
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -785,6 +801,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -819,6 +836,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -830,6 +848,7 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -847,8 +866,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-CONFIG_RS5C313_RTC=y
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -863,12 +881,15 @@
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -876,15 +897,23 @@
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -892,28 +921,44 @@
 #
 
 #
-# Multimedia Capabilities Port drivers
-#
-
-#
 # Multimedia devices
 #
 CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
 
 #
-# Video For Linux
+# Video Capture Adapters
 #
 
 #
-# Video Adapters
+# Video Capture Adapters
 #
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
 # CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_DPC is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
 
 #
 # Radio Adapters
@@ -932,15 +977,18 @@
 # CONFIG_RADIO_TRUST is not set
 # CONFIG_RADIO_TYPHOON is not set
 # CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+CONFIG_USB_DABUSB=m
 
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -949,6 +997,7 @@
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FONT_8x16=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -964,32 +1013,21 @@
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
 # CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
 # CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 is not set
 
 #
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1007,6 +1045,7 @@
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1017,15 +1056,15 @@
 #
 # USB Device Class drivers
 #
-CONFIG_OBSOLETE_OSS_USB_DRIVER=y
-CONFIG_USB_AUDIO=m
-# CONFIG_USB_BLUETOOTH_TTY is not set
-CONFIG_USB_MIDI=m
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1037,12 +1076,16 @@
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=m
 CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
 
@@ -1056,14 +1099,14 @@
 # CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1072,20 +1115,6 @@
 # CONFIG_USB_MICROTEK is not set
 
 #
-# USB Multimedia devices
-#
-CONFIG_USB_DABUSB=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_STV680=m
-CONFIG_USB_PWC=m
-
-#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -1104,7 +1133,9 @@
 #
 CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
@@ -1112,6 +1143,7 @@
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
 # CONFIG_USB_SERIAL_VISOR is not set
 # CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
@@ -1124,9 +1156,12 @@
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
@@ -1138,15 +1173,18 @@
 #
 CONFIG_USB_EMI62=m
 CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 CONFIG_USB_SISUSBVGA=m
 CONFIG_USB_SISUSBVGA_CON=y
 # CONFIG_USB_LD is not set
@@ -1167,12 +1205,43 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
@@ -1195,9 +1264,11 @@
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1229,12 +1300,14 @@
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1252,7 +1325,8 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=m
-CONFIG_UFS_FS_WRITE=y
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -1341,9 +1415,13 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -1361,13 +1439,12 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index ab3db76..e89d951 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,19 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1
-# Fri Jan 27 19:43:20 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:27:01 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -28,13 +30,17 @@
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -45,11 +51,9 @@
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -62,7 +66,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -83,30 +90,26 @@
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
 # CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 CONFIG_SH_SH4202_MICRODEV=y
 # CONFIG_SH_LANDISK is not set
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -124,9 +127,11 @@
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -149,14 +154,25 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -165,22 +181,21 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
+CONFIG_SH_WRITETHROUGH=y
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x04000000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
@@ -212,9 +227,16 @@
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-CONFIG_PREEMPT=y
 # CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
 
 #
 # Boot options
@@ -223,12 +245,12 @@
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 # CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,115200"
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/hda1"
 
 #
 # Bus options
 #
-# CONFIG_SUPERHYWAY is not set
+CONFIG_SUPERHYWAY=y
 # CONFIG_PCI is not set
 
 #
@@ -248,6 +270,11 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -255,15 +282,19 @@
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_DHCP is not set
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
@@ -273,12 +304,19 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -304,7 +342,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -332,6 +369,7 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -361,6 +399,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -397,6 +436,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -502,6 +547,7 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -518,7 +564,8 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
@@ -547,13 +594,15 @@
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -561,13 +610,10 @@
 #
 
 #
-# Multimedia Capabilities Port drivers
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -577,7 +623,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -589,6 +637,7 @@
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -605,15 +654,42 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
-# EDAC - error detection and reporting (RAS)
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
@@ -637,6 +713,7 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -664,12 +741,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -772,10 +850,14 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -790,6 +872,9 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -799,6 +884,8 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -813,7 +900,6 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -826,3 +912,4 @@
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig
index d597fc5..2470364 100644
--- a/arch/sh/configs/r7780rp_defconfig
+++ b/arch/sh/configs/r7780rp_defconfig
@@ -1,20 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-sh
-# Sat Jan  7 19:47:53 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:32:47 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -26,33 +27,38 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -60,7 +66,6 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -68,7 +73,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -89,31 +97,26 @@
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R77703DRP is not set
 CONFIG_SH_R7780RP=y
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 # CONFIG_SH_LANDISK is not set
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -132,9 +135,11 @@
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -157,15 +162,24 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
 CONFIG_HUGETLB_PAGE_SIZE_64K=y
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -176,6 +190,7 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -183,21 +198,27 @@
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x08000000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_INTC2_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
+
+#
+# R7780RP options
+#
+CONFIG_SH_R7780MP=y
 CONFIG_SH_PCLK_FREQ=32000000
 
 #
@@ -220,11 +241,16 @@
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-CONFIG_PREEMPT=y
 # CONFIG_SMP is not set
-CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_INTC2_IRQ=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
 
 #
 # Boot options
@@ -242,7 +268,7 @@
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -266,6 +292,11 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -273,9 +304,13 @@
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -297,12 +332,19 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -314,16 +356,21 @@
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 CONFIG_BRIDGE=m
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -340,6 +387,7 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
 
 #
 # Device Drivers
@@ -352,6 +400,7 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -386,6 +435,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -438,13 +488,11 @@
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 CONFIG_BLK_DEV_PDC202XX_NEW=m
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 CONFIG_BLK_DEV_SIIMAGE=m
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -456,6 +504,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -476,12 +525,13 @@
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -494,27 +544,23 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -522,6 +568,11 @@
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -580,9 +631,9 @@
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-CONFIG_NE2000=y
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
@@ -605,6 +656,7 @@
 # CONFIG_TLAN is not set
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
+# CONFIG_VIA_RHINE_NAPI is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -613,6 +665,7 @@
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -620,10 +673,12 @@
 # CONFIG_R8169_NAPI is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -631,6 +686,7 @@
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -641,6 +697,7 @@
 # Wireless LAN (non-hamradio)
 #
 CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
 
 #
 # Obsolete Wireless cards support (pre-802.11)
@@ -650,6 +707,8 @@
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 CONFIG_HERMES=m
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
@@ -692,6 +751,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -714,6 +774,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -745,6 +806,7 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -762,7 +824,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -786,15 +848,23 @@
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -802,13 +872,10 @@
 #
 
 #
-# Multimedia Capabilities Port drivers
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -818,7 +885,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -834,18 +903,21 @@
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=m
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
-# CONFIG_SOUND_FUSION is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ES1371 is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
 
 #
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
 #
@@ -863,12 +935,43 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
@@ -888,9 +991,11 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -920,12 +1025,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1032,23 +1138,33 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
 CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
 # CONFIG_KGDB is not set
 
 #
@@ -1061,6 +1177,10 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1070,6 +1190,8 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig
index e43cf57..099e98f 100644
--- a/arch/sh/configs/rts7751r2d_defconfig
+++ b/arch/sh/configs/rts7751r2d_defconfig
@@ -1,125 +1,215 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:42 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:38:36 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 CONFIG_SH_RTS7751R2D=y
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+
+#
+# RTS7751R2D options
+#
 CONFIG_RTS7751R2D_REV11=y
-CONFIG_SH_PCLK_CALC=y
 CONFIG_SH_PCLK_FREQ=60000000
 
 #
@@ -140,17 +230,37 @@
 CONFIG_VOYAGERGX=y
 # CONFIG_HD6446X_SERIES is not set
 CONFIG_HEARTBEAT=y
-CONFIG_RTC_9701JE=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
+
+#
+# Bus options
 #
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -158,10 +268,6 @@
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
-#
-
-#
 # PCI Hotplug Support
 #
 CONFIG_HOTPLUG_PCI=y
@@ -177,6 +283,95 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
+
+#
 # Device Drivers
 #
 
@@ -186,6 +381,12 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -204,7 +405,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -216,18 +416,9 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -253,7 +444,6 @@
 #
 CONFIG_IDE_GENERIC=y
 # CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
@@ -262,7 +452,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -272,6 +469,7 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -284,67 +482,8 @@
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-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
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -357,6 +496,11 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -364,6 +508,7 @@
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -406,15 +551,22 @@
 # 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_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -425,6 +577,7 @@
 # Wireless LAN (non-hamradio)
 #
 CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
 
 #
 # Obsolete Wireless cards support (pre-802.11)
@@ -434,9 +587,12 @@
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 CONFIG_HERMES=m
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
 # CONFIG_PCI_HERMES is not set
 # CONFIG_ATMEL is not set
 
@@ -444,6 +600,7 @@
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
 #
 # CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 CONFIG_NET_WIRELESS=y
 
 #
@@ -456,6 +613,8 @@
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -473,20 +632,10 @@
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
+# Hardware I/O ports
 #
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -503,6 +652,7 @@
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_JSM is not set
 # CONFIG_UNIX98_PTYS is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -516,7 +666,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -529,14 +679,35 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -546,6 +717,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -555,7 +727,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -573,6 +747,9 @@
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -581,6 +758,8 @@
 #
 CONFIG_SND_MPU401_UART=m
 CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
@@ -589,7 +768,8 @@
 #
 # PCI devices
 #
-CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -598,73 +778,63 @@
 # CONFIG_SND_AU8830 is not set
 # CONFIG_SND_AZT3328 is not set
 # CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_TRIDENT is not set
-CONFIG_SND_YMFPCI=m
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_ENS1370 is not set
 # CONFIG_SND_ENS1371 is not set
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
 # CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
 # CONFIG_SND_INTEL8X0 is not set
 # CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
 # CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_VIA82XX is not set
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
+CONFIG_SND_YMFPCI=m
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
 # CONFIG_SOUND_BT878 is not set
-CONFIG_SOUND_CMPCI=m
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
 # CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 is not set
-CONFIG_SOUND_VOYAGERGX=m
 
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -678,30 +848,66 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -724,12 +930,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -758,6 +965,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
@@ -818,8 +1026,14 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -836,12 +1050,10 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/se7300_defconfig b/arch/sh/configs/se7300_defconfig
index 4b71cd6..8a21790 100644
--- a/arch/sh/configs/se7300_defconfig
+++ b/arch/sh/configs/se7300_defconfig
@@ -1,45 +1,55 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:43 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:43:22 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -47,68 +57,145 @@
 # CONFIG_MODULES is not set
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 CONFIG_SH_7300_SOLUTION_ENGINE=y
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 CONFIG_CPU_SUBTYPE_SH7300=y
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_DSP=y
-# CONFIG_SH_ADC is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00210000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-# CONFIG_SH_PCLK_CALC is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
+# CONFIG_SH_ADC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=33333333
 
 #
@@ -128,18 +215,35 @@
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00210000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0"
+
+#
+# Bus options
 #
 # CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
@@ -153,10 +257,14 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-CONFIG_EMBEDDED_RAMDISK=y
-CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+# CONFIG_NET is not set
 
 #
 # Device Drivers
@@ -167,7 +275,11 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
 
 #
 # Memory Technology Devices (MTD)
@@ -186,26 +298,16 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
 #
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-
-#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -213,7 +315,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -223,6 +332,7 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -233,13 +343,6 @@
 #
 
 #
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
 # ISDN subsystem
 #
 
@@ -252,6 +355,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -266,18 +370,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 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -287,6 +379,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -301,6 +403,7 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -328,7 +431,7 @@
 #
 CONFIG_SOFT_WATCHDOG=y
 # CONFIG_SH_WDT is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -336,18 +439,38 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -357,6 +480,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -365,7 +489,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -377,9 +503,10 @@
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -393,30 +520,64 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -436,14 +597,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -481,8 +641,16 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
 CONFIG_SH_STANDARD_BIOS=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_KGDB=y
@@ -520,12 +688,9 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se73180_defconfig b/arch/sh/configs/se73180_defconfig
index fe19feb..1a76615 100644
--- a/arch/sh/configs/se73180_defconfig
+++ b/arch/sh/configs/se73180_defconfig
@@ -1,120 +1,208 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:44 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:44:45 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 CONFIG_SH_73180_SOLUTION_ENGINE=y
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
 # CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-CONFIG_CPU_SUBTYPE_SH73180=y
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+CONFIG_CPU_SUBTYPE_SH73180=y
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
-# CONFIG_MEMORY_OVERRIDE is not set
-# CONFIG_SH_FPU is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU is not set
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-# CONFIG_SH_PCLK_CALC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=27000000
 
 #
@@ -134,18 +222,35 @@
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram"
+
+#
+# Bus options
 #
 # CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
@@ -159,10 +264,14 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-CONFIG_EMBEDDED_RAMDISK=y
-CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+# CONFIG_NET is not set
 
 #
 # Device Drivers
@@ -173,7 +282,11 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
 
 #
 # Memory Technology Devices (MTD)
@@ -192,27 +305,17 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
 #
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-
-#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -220,7 +323,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -230,6 +340,7 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -240,13 +351,6 @@
 #
 
 #
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
 # ISDN subsystem
 #
 
@@ -261,20 +365,10 @@
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
+# Hardware I/O ports
 #
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -291,6 +385,7 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -313,7 +408,7 @@
 #
 # CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_SH_WDT is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -321,18 +416,38 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -342,6 +457,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -350,6 +466,7 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -362,9 +479,10 @@
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -378,30 +496,64 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -421,12 +573,10 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -467,8 +617,13 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -478,7 +633,6 @@
 # Security options
 #
 # CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
@@ -486,12 +640,9 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 948e507..84c0075 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Aug  7 20:14:44 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:46:17 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -25,16 +26,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -46,10 +51,10 @@
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
-CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -64,6 +69,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -115,6 +121,7 @@
 #
 CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
 
 #
 # SH-2 Processor Support
@@ -153,12 +160,16 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-CONFIG_CPU_SUBTYPE_SH7343=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+CONFIG_CPU_SUBTYPE_SH7343=y
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
@@ -166,6 +177,7 @@
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x01000000
 CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -174,6 +186,7 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -274,6 +287,9 @@
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -292,12 +308,16 @@
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -323,7 +343,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -351,6 +370,7 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -376,6 +396,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -408,7 +429,6 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -466,6 +486,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -506,7 +532,6 @@
 CONFIG_MII=y
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
-# CONFIG_NE2000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -550,6 +575,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -581,6 +607,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -609,7 +636,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -641,10 +668,10 @@
 #
 # I2C Hardware Bus support
 #
+# CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
-CONFIG_I2C_SH7343=y
 
 #
 # Miscellaneous I2C Chip support
@@ -670,7 +697,6 @@
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -698,30 +724,16 @@
 # Video Capture Adapters
 #
 # CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
 # CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Encoders and Decoders
-#
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_CX25840 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
 
 #
 # Radio Adapters
 #
-# CONFIG_RADIO_MAESTRO is not set
 
 #
 # Digital Video Broadcasting Devices
@@ -731,12 +743,13 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
 # CONFIG_FB_MACMODES is not set
-CONFIG_FB_FIRMWARE_EDID=y
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_EPSON1355 is not set
@@ -789,12 +802,6 @@
 # CONFIG_SND_MPU401 is not set
 
 #
-# SuperH devices
-#
-CONFIG_SH7343_SIU=m
-CONFIG_AK4537_CODEC=y
-
-#
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
@@ -847,6 +854,19 @@
 # CONFIG_RTC_CLASS is not set
 
 #
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -883,8 +903,10 @@
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -905,6 +927,7 @@
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -962,7 +985,9 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
@@ -983,10 +1008,6 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index e4a1460..06ebd6e 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,125 +1,212 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:45 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:03:04 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 CONFIG_SH_SOLUTION_ENGINE=y
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 CONFIG_CPU_SUBTYPE_SH7705=y
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_SH7705_CACHE_32KB=y
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-# CONFIG_CF_ENABLER is not set
-CONFIG_SH_RTC=y
-# CONFIG_SH_DSP is not set
-# CONFIG_SH_ADC is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+CONFIG_SH7705_CACHE_32KB=y
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
+# CONFIG_CF_ENABLER is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU_EMU is not set
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_ADC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=33333333
 
 #
@@ -139,18 +226,35 @@
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
 #
 # CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
@@ -164,9 +268,95 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -177,15 +367,20 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
@@ -197,6 +392,8 @@
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -217,22 +414,19 @@
 # CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_SOLUTIONENGINE=y
-CONFIG_MTD_SUPERH_RESERVE=0x300000
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -240,7 +434,6 @@
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -256,6 +449,11 @@
 # CONFIG_MTD_NAND is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -267,25 +465,15 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -296,7 +484,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -306,6 +501,7 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -316,70 +512,8 @@
 #
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-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
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -387,6 +521,11 @@
 # CONFIG_TUN is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -422,10 +561,14 @@
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=y
 # CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=y
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -441,6 +584,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -452,18 +596,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 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -473,6 +605,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -487,6 +629,7 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -502,7 +645,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -510,18 +653,38 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -531,6 +694,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -540,6 +704,7 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -552,9 +717,10 @@
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -568,30 +734,64 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -611,9 +811,8 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -632,8 +831,9 @@
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -655,6 +855,7 @@
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -663,6 +864,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
@@ -683,9 +885,13 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_KGDB is not set
 
@@ -693,7 +899,6 @@
 # Security options
 #
 # CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
@@ -701,14 +906,12 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index 6dc3158..5d357d6 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -1,131 +1,218 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:46 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:49:01 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 CONFIG_SH_SOLUTION_ENGINE=y
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 CONFIG_CPU_SUBTYPE_SH7750=y
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
 CONFIG_CF_ENABLER=y
 # CONFIG_CF_AREA5 is not set
 CONFIG_CF_AREA6=y
 CONFIG_CF_BASE_ADDR=0xb8000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
+
+#
+# Processor features
+#
 CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=50000000
 
 #
 # CPU Frequency scaling
@@ -144,18 +231,35 @@
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
+
+#
+# Bus options
 #
 # CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
@@ -169,6 +273,98 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
 # Device Drivers
 #
 
@@ -177,15 +373,20 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
@@ -197,6 +398,8 @@
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -217,22 +420,19 @@
 # CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 CONFIG_MTD_ROM=y
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_SOLUTIONENGINE=y
-CONFIG_MTD_SUPERH_RESERVE=0x00010000
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -240,7 +440,6 @@
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -256,6 +455,11 @@
 # CONFIG_MTD_NAND is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -267,23 +471,12 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -294,7 +487,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -304,6 +504,7 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -314,71 +515,8 @@
 #
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-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
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -386,6 +524,11 @@
 # CONFIG_TUN is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -418,6 +561,8 @@
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -435,20 +580,10 @@
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
+# Hardware I/O ports
 #
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -462,12 +597,14 @@
 CONFIG_SERIAL_8250=y
 # CONFIG_SERIAL_8250_CONSOLE is not set
 CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -491,7 +628,8 @@
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_SH_WDT=y
-# CONFIG_RTC is not set
+# CONFIG_SH_WDT_MMAP is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -499,18 +637,38 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -520,6 +678,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -529,7 +688,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -541,9 +702,10 @@
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -557,29 +719,63 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -599,14 +795,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -621,8 +817,9 @@
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -644,6 +841,7 @@
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -652,6 +850,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
@@ -667,6 +866,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -682,8 +882,14 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -700,14 +906,12 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # 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
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index 1ce0289..a909559 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -1,126 +1,213 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:48 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:10:12 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 # CONFIG_SH_SOLUTION_ENGINE is not set
 CONFIG_SH_7751_SOLUTION_ENGINE=y
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=60013568
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -139,28 +226,39 @@
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-CONFIG_PCI=y
-# CONFIG_SH_PCIDMA_NONCOHERENT is not set
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,38400"
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -170,9 +268,115 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_QUEUE=y
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -183,15 +387,20 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
@@ -203,6 +412,8 @@
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -223,30 +434,26 @@
 # CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -262,6 +469,11 @@
 # CONFIG_MTD_NAND is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -273,30 +485,15 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -307,7 +504,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -317,109 +521,29 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
-# CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_DEBUG=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-CONFIG_IP_NF_QUEUE=y
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
-# ARCnet devices
+# PHY device support
 #
-# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -427,60 +551,19 @@
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_STNIC is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
 #
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-
-#
 # Ethernet (1000 Mbit)
 #
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
 
 #
 # Token Ring devices
 #
-# CONFIG_TR is not set
 
 #
 # Wireless LAN (non-hamradio)
@@ -491,12 +574,12 @@
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -514,20 +597,10 @@
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
+# Hardware I/O ports
 #
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -564,33 +637,46 @@
 #
 # CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_SH_WDT is not set
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -600,6 +686,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -609,7 +696,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -619,12 +708,12 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -638,30 +727,65 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -681,14 +805,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -703,8 +827,9 @@
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -726,6 +851,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
@@ -746,8 +872,14 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -764,14 +896,12 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # 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
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index 078f78c..9fd5ea7 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -1,51 +1,63 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:49 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:13:26 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -53,81 +65,154 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 CONFIG_SH_SH03=y
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
 CONFIG_CF_ENABLER=y
 CONFIG_CF_AREA5=y
 # CONFIG_CF_AREA6 is not set
 CONFIG_CF_BASE_ADDR=0xb4000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00004000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
+
+#
+# Processor features
+#
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -146,14 +231,36 @@
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00004000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
+
+#
+# Bus options
 #
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -161,10 +268,6 @@
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
-#
-
-#
 # PCI Hotplug Support
 #
 CONFIG_HOTPLUG_PCI=m
@@ -180,9 +283,96 @@
 CONFIG_BINFMT_MISC=y
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -194,6 +384,12 @@
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -212,7 +408,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -225,18 +420,9 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -263,7 +449,6 @@
 #
 CONFIG_IDE_GENERIC=y
 # CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
@@ -272,7 +457,9 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -284,6 +471,7 @@
 CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -293,15 +481,18 @@
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -309,40 +500,35 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP 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
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I 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
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -351,6 +537,9 @@
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -363,73 +552,8 @@
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -442,6 +566,11 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -449,6 +578,7 @@
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -487,15 +617,22 @@
 # 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_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -518,6 +655,8 @@
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -533,6 +672,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -547,14 +687,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -564,27 +696,38 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
 # Serial drivers
 #
 CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_PCI=m
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -605,14 +748,14 @@
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_SH_WDT=m
+# CONFIG_SH_WDT_MMAP is not set
 
 #
 # PCI-based Watchdog Cards
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
-CONFIG_SH03_RTC=y
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -625,14 +768,35 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -642,6 +806,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -651,13 +816,14 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -667,12 +833,13 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -686,17 +853,53 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 # CONFIG_EXT2_FS_POSIX_ACL is not set
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -707,17 +910,17 @@
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -744,14 +947,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -775,16 +978,19 @@
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
@@ -794,6 +1000,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
@@ -813,6 +1020,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -868,9 +1076,14 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -886,6 +1099,10 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -894,6 +1111,9 @@
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -918,7 +1138,9 @@
 # Library routines
 #
 CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index ec9a303..9380c32 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Aug  7 17:07:06 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:48:56 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -25,16 +26,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -46,10 +51,10 @@
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
-CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -64,6 +69,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -87,6 +93,7 @@
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
 # CONFIG_SH_HP6XX is not set
@@ -150,17 +157,23 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -169,6 +182,7 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -216,10 +230,10 @@
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -267,6 +281,9 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -282,9 +299,12 @@
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
@@ -293,6 +313,7 @@
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -317,6 +338,7 @@
 # CONFIG_IP_NF_AMANDA is not set
 CONFIG_IP_NF_PPTP=m
 # CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
 # CONFIG_IP_NF_QUEUE is not set
 
 #
@@ -342,7 +364,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -409,6 +430,7 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -434,6 +456,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -466,8 +489,6 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-CONFIG_MTD_SH7710VOIPGW=y
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -525,6 +546,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -565,7 +592,6 @@
 # CONFIG_MII is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
-# CONFIG_NE2000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -610,6 +636,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -667,7 +694,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -697,7 +724,6 @@
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -723,7 +749,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -778,6 +806,19 @@
 # CONFIG_RTC_CLASS is not set
 
 #
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -814,8 +855,10 @@
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -836,6 +879,7 @@
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -879,7 +923,9 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
@@ -899,10 +945,6 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
index 382b3bd..8800fef 100644
--- a/arch/sh/configs/shmin_defconfig
+++ b/arch/sh/configs/shmin_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Wed Aug  2 01:45:03 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:52:49 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,7 +10,7 @@
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_PTRACE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -28,14 +28,17 @@
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_UID16 is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
@@ -46,10 +49,10 @@
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
 # CONFIG_SLAB is not set
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=1
 CONFIG_SLOB=y
-CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -59,6 +62,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_LSF is not set
 
@@ -79,27 +83,21 @@
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7709_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
 # CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
@@ -128,6 +126,7 @@
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -150,17 +149,23 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -169,6 +174,7 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -211,9 +217,15 @@
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -232,7 +244,6 @@
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -261,6 +272,9 @@
 # CONFIG_NETDEBUG is not set
 # CONFIG_PACKET is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -279,13 +293,17 @@
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -311,7 +329,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -338,7 +355,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -364,11 +381,12 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
@@ -457,6 +475,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -497,7 +521,6 @@
 # CONFIG_MII is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
-CONFIG_NE2000=y
 
 #
 # Ethernet (1000 Mbit)
@@ -580,7 +603,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -610,7 +633,6 @@
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -636,6 +658,7 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -691,6 +714,19 @@
 # CONFIG_RTC_CLASS is not set
 
 #
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -699,7 +735,6 @@
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_INOTIFY is not set
@@ -727,8 +762,10 @@
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -795,7 +832,9 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_UNWIND_INFO is not set
@@ -814,10 +853,6 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index 69cf02a..98503f1 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,48 +1,60 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:51 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:55:47 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -50,70 +62,145 @@
 # CONFIG_MODULES is not set
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 CONFIG_SH_SECUREEDGE5410=y
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=60013568
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -133,28 +220,42 @@
 # CONFIG_HD6446X_SERIES is not set
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
 #
 CONFIG_PCI=y
 # CONFIG_SH_PCIDMA_NONCOHERENT is not set
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -164,9 +265,94 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+# CONFIG_PACKET is not set
+# CONFIG_UNIX is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -177,7 +363,12 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -196,7 +387,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -208,18 +398,9 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -230,7 +411,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -240,6 +428,7 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -252,69 +441,8 @@
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_UNIX is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -327,6 +455,11 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -334,6 +467,7 @@
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -376,15 +510,22 @@
 # 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_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -406,6 +547,8 @@
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -421,6 +564,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -435,18 +579,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_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -456,11 +588,23 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -472,6 +616,7 @@
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -485,7 +630,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -498,14 +643,35 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -515,6 +681,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -524,13 +691,14 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
-CONFIG_VGA_CONSOLE=y
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -540,12 +708,13 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -559,30 +728,66 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -602,16 +807,14 @@
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -635,12 +838,14 @@
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -649,6 +854,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
@@ -669,8 +875,15 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -687,13 +900,11 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # 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
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 431c9c9..c16350d 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,48 +1,58 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:53 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:57:29 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -50,75 +60,150 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 CONFIG_SH_7751_SYSTEMH=y
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00400000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -136,28 +221,39 @@
 # CONFIG_HD6446X_SERIES is not set
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-CONFIG_PCI=y
-# CONFIG_SH_PCIDMA_NONCOHERENT is not set
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -167,9 +263,14 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+# CONFIG_NET is not set
 
 #
 # Device Drivers
@@ -180,7 +281,11 @@
 #
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
 
 #
 # Memory Technology Devices (MTD)
@@ -199,31 +304,16 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=1024
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
 #
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -231,7 +321,14 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -241,23 +338,15 @@
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -274,25 +363,14 @@
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
+# Hardware I/O ports
 #
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -322,27 +400,46 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -352,6 +449,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -360,7 +458,9 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -370,12 +470,12 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -389,29 +489,62 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -431,16 +564,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -478,9 +609,14 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -497,13 +633,11 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # 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
+CONFIG_PLIST=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 1db2904..5e81754 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -1,21 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-sh
-# Wed Nov  9 00:35:56 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:59:14 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -26,31 +26,38 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_EMBEDDED is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -58,40 +65,57 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-CONFIG_SH_TITAN=y
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 # CONFIG_SH_LANDISK is not set
+CONFIG_SH_TITAN=y
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -109,9 +133,11 @@
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -134,14 +160,23 @@
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
 #
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08030000
+CONFIG_MEMORY_SIZE=0x7fd0000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -149,6 +184,8 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -156,22 +193,21 @@
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08030000
-CONFIG_MEMORY_SIZE=0x7fd0000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
 CONFIG_SH_PCLK_FREQ=30000000
 
 #
@@ -194,9 +230,15 @@
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -214,8 +256,8 @@
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-#CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -238,6 +280,11 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -245,11 +292,13 @@
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -270,40 +319,87 @@
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
 CONFIG_NET_IPGRE_BROADCAST=y
 CONFIG_IP_MROUTE=y
 CONFIG_IP_PIMSM_V1=y
 CONFIG_IP_PIMSM_V2=y
 # CONFIG_ARPD is not set
 CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_TUNNEL=m
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
 #
 # CONFIG_IP_VS is not set
-CONFIG_IPV6=m
+CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_TUNNEL=m
-CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_TUNNEL=y
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -320,42 +416,24 @@
 CONFIG_IP_NF_TFTP=m
 # CONFIG_IP_NF_AMANDA is not set
 CONFIG_IP_NF_PPTP=m
+CONFIG_IP_NF_H323=m
+# CONFIG_IP_NF_SIP is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
-# CONFIG_IP_NF_MATCH_PHYSDEV is not set
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-# CONFIG_IP_NF_MATCH_SCTP is not set
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_CONNBYTES=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -367,17 +445,13 @@
 CONFIG_IP_NF_NAT_FTP=m
 CONFIG_IP_NF_NAT_TFTP=m
 CONFIG_IP_NF_NAT_PPTP=m
+CONFIG_IP_NF_NAT_H323=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -387,26 +461,18 @@
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
-# CONFIG_IP6_NF_MATCH_PHYSDEV is not set
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 
@@ -424,22 +490,35 @@
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
 # CONFIG_DECNET is not set
+CONFIG_LLC=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
@@ -452,8 +531,10 @@
 CONFIG_NET_SCH_DSMARK=m
 CONFIG_NET_SCH_NETEM=m
 CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
+
+#
+# Classification
+#
 CONFIG_NET_CLS=y
 CONFIG_NET_CLS_BASIC=m
 CONFIG_NET_CLS_TCINDEX=m
@@ -462,7 +543,6 @@
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 CONFIG_CLS_U32_PERF=y
-CONFIG_NET_CLS_IND=y
 CONFIG_CLS_U32_MARK=y
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
@@ -481,6 +561,8 @@
 CONFIG_NET_ACT_IPT=m
 CONFIG_NET_ACT_PEDIT=m
 # CONFIG_NET_ACT_SIMP is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
 
 #
 # Network testing
@@ -489,7 +571,15 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+CONFIG_IEEE80211_SOFTMAC=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -502,6 +592,7 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -511,7 +602,86 @@
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=m
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=0
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_FTL=m
+CONFIG_NFTL=m
+# CONFIG_NFTL_RW is not set
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
 
 #
 # Parallel port support
@@ -528,29 +698,20 @@
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_SSFDC=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_CRYPTOLOOP=m
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -561,7 +722,8 @@
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -583,16 +745,18 @@
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -600,27 +764,23 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -628,6 +788,11 @@
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -654,6 +819,7 @@
 # Network device support
 #
 CONFIG_NETDEVICES=y
+# CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -668,7 +834,6 @@
 # PHY device support
 #
 CONFIG_PHYLIB=m
-CONFIG_PHYCONTROL=y
 
 #
 # MII PHY device drivers
@@ -678,6 +843,9 @@
 CONFIG_QSEMI_PHY=m
 CONFIG_LXT_PHY=m
 CONFIG_CICADA_PHY=m
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -687,7 +855,7 @@
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
-CONFIG_CASSINI=m
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -696,7 +864,6 @@
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-# CONFIG_NE2000 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -733,10 +900,12 @@
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -744,6 +913,7 @@
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -754,6 +924,7 @@
 # Wireless LAN (non-hamradio)
 #
 CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
 
 #
 # Obsolete Wireless cards support (pre-802.11)
@@ -763,6 +934,8 @@
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 # CONFIG_HERMES is not set
 # CONFIG_ATMEL is not set
 
@@ -770,7 +943,16 @@
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
 #
 CONFIG_PRISM54=m
+# CONFIG_USB_ZD1201 is not set
 # CONFIG_HOSTAP is not set
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+# CONFIG_ZD1211RW is not set
 CONFIG_NET_WIRELESS=y
 
 #
@@ -786,8 +968,13 @@
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
@@ -808,6 +995,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -842,6 +1030,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -853,6 +1042,7 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -869,8 +1059,27 @@
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SH_WDT=m
+# CONFIG_SH_WDT_MMAP is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -886,6 +1095,7 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -893,6 +1103,12 @@
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
@@ -902,6 +1118,9 @@
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -909,28 +1128,28 @@
 #
 
 #
-# Multimedia Capabilities Port drivers
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -942,7 +1161,8 @@
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB=m
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
 #
@@ -956,11 +1176,12 @@
 #
 # USB Host Controller Drivers
 #
-CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
 # CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
@@ -969,14 +1190,17 @@
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-CONFIG_USB_STORAGE=m
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
@@ -985,6 +1209,9 @@
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
@@ -1001,14 +1228,14 @@
 # CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1017,15 +1244,6 @@
 # CONFIG_USB_MICROTEK is not set
 
 #
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -1033,7 +1251,6 @@
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
-# CONFIG_USB_ZD1201 is not set
 CONFIG_USB_MON=y
 
 #
@@ -1045,7 +1262,9 @@
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
@@ -1053,6 +1272,7 @@
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
 # CONFIG_USB_SERIAL_VISOR is not set
 # CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
@@ -1065,12 +1285,16 @@
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 
 #
@@ -1078,15 +1302,18 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
@@ -1106,39 +1333,71 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT3_FS_XATTR is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1170,12 +1429,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-CONFIG_RELAYFS_FS=m
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1187,6 +1448,8 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -1241,6 +1504,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -1296,21 +1560,36 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
-CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
 # CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
 # CONFIG_KGDB is not set
 
 #
@@ -1323,28 +1602,35 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
 CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
 
@@ -1359,9 +1645,10 @@
 CONFIG_CRC16=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c
index 3b0b0f6..c1b6bc2 100644
--- a/arch/sh/drivers/dma/dma-pvr2.c
+++ b/arch/sh/drivers/dma/dma-pvr2.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/boards/dreamcast/dma-pvr2.c
+ * arch/sh/drivers/dma/dma-pvr2.c
  *
  * NEC PowerVR 2 (Dreamcast) DMA support
  *
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index 70a5d82..29b8ef9 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -48,12 +48,11 @@
 	int ret;
 
 	ret = sysdev_class_register(&dma_sysclass);
-	if (ret == 0)
-		sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
+	if (unlikely(ret))
+		return ret;
 
-	return ret;
+	return sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
 }
-
 postcore_initcall(dma_sysclass_init);
 
 static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
@@ -152,4 +151,3 @@
 
 	sysdev_unregister(dev);
 }
-
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
index 6acf02b..230d6ec 100644
--- a/arch/sh/drivers/pci/dma-dreamcast.c
+++ b/arch/sh/drivers/pci/dma-dreamcast.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/pci/dma-dreamcast.c
+ * arch/sh/drivers/pci/dma-dreamcast.c
  *
  * PCI DMA support for the Sega Dreamcast
  *
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index c0af5f7..6f53f82 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/pci/fixups-dreamcast.c
+ * arch/sh/drivers/pci/fixups-dreamcast.c
  *
  * PCI fixups for the Sega Dreamcast
  *
diff --git a/arch/sh/drivers/pci/ops-bigsur.c b/arch/sh/drivers/pci/ops-bigsur.c
index 5da501b..eb31be7 100644
--- a/arch/sh/drivers/pci/ops-bigsur.c
+++ b/arch/sh/drivers/pci/ops-bigsur.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-bigsur.c
+ * linux/arch/sh/drivers/pci/ops-bigsur.c
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  *
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
index 23d5279..381306c 100644
--- a/arch/sh/drivers/pci/ops-dreamcast.c
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/pci/ops-dreamcast.c
+ * arch/sh/drivers/pci/ops-dreamcast.c
  *
  * PCI operations for the Sega Dreamcast
  *
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c
index ada301c..d060308 100644
--- a/arch/sh/drivers/pci/ops-landisk.c
+++ b/arch/sh/drivers/pci/ops-landisk.c
@@ -8,7 +8,6 @@
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index 554d5ed..6e3ba9c6 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -8,8 +8,6 @@
  *
  * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board
  */
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
index 88f44e2..b68824c 100644
--- a/arch/sh/drivers/pci/ops-rts7751r2d.c
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-rts7751r2d.c
+ * linux/arch/sh/drivers/pci/ops-rts7751r2d.c
  *
  * Author:  Ian DaSilva (idasilva@mvista.com)
  *
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
index e58d556..ebb58e6 100644
--- a/arch/sh/drivers/pci/ops-sh03.c
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -35,10 +35,10 @@
 	.flags  = IORESOURCE_MEM
 };
 
-extern struct pci_ops sh7751_pci_ops;
+extern struct pci_ops sh4_pci_ops;
 
 struct pci_channel board_pci_channels[] = {
-	{ &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+	{ &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
 	{ NULL, NULL, NULL, 0, 0 },
 };
 
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c
index c6097bc..cd56d53 100644
--- a/arch/sh/drivers/pci/ops-titan.c
+++ b/arch/sh/drivers/pci/ops-titan.c
@@ -11,8 +11,6 @@
  *
  * PCI initialization for the Titan boards
  */
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index bd3064a..d6e6352 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -12,10 +12,8 @@
  *  License.  See linux/COPYING for more information.
  *
  */
-
 #undef DEBUG
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
diff --git a/arch/sh/kernel/apm.c b/arch/sh/kernel/apm.c
index 871e7d6..4f66f91 100644
--- a/arch/sh/kernel/apm.c
+++ b/arch/sh/kernel/apm.c
@@ -16,7 +16,6 @@
  * [This document is available from Microsoft at:
  *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/timer.h>
diff --git a/arch/sh/kernel/cpu/ubc.S b/arch/sh/kernel/cpu/ubc.S
index 0c569b2..8192307 100644
--- a/arch/sh/kernel/cpu/ubc.S
+++ b/arch/sh/kernel/cpu/ubc.S
@@ -1,5 +1,5 @@
 /*
- * arch/sh/kernel/ubc.S
+ * arch/sh/kernel/cpu/ubc.S
  *
  * Set of management routines for the User Break Controller (UBC)
  *
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index fe82218..97c571f 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -10,8 +10,8 @@
  * for more details.
  *
  */
-
 #include <linux/sys.h>
+#include <linux/errno.h>
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
@@ -53,10 +53,6 @@
  *	syscall #
  *
  */
-
-ENOSYS = 38
-EINVAL = 22
-
 #if defined(CONFIG_KGDB_NMI)
 NMI_VEC = 0x1c0			! Must catch early for debounce
 #endif
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 5f58733..36d86f9 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -1,5 +1,4 @@
-/* $Id: setup.c,v 1.30 2003/10/13 07:21:19 lethal Exp $
- *
+/*
  *  linux/arch/sh/kernel/setup.c
  *
  *  Copyright (C) 1999  Niibe Yutaka
@@ -21,6 +20,7 @@
 #include <linux/utsname.h>
 #include <linux/cpu.h>
 #include <linux/pfn.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/sections.h>
@@ -459,7 +459,7 @@
 		seq_printf(m, "machine\t\t: %s\n", get_system_type());
 
 	seq_printf(m, "processor\t: %d\n", cpu);
-	seq_printf(m, "cpu family\t: %s\n", system_utsname.machine);
+	seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
 	seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
 
 	show_cpuflags(m);
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index d3cbfa2..9daad70 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -72,6 +72,7 @@
 DECLARE_EXPORT(__ashldi3);
 DECLARE_EXPORT(__lshrdi3);
 DECLARE_EXPORT(__movstr);
+DECLARE_EXPORT(__movstrSI16);
 
 EXPORT_SYMBOL(strcpy);
 
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 6c0fb7c..dbebadd 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -42,6 +42,7 @@
 EXPORT_SYMBOL(cpu_possible_map);
 
 cpumask_t cpu_online_map;
+EXPORT_SYMBOL(cpu_online_map);
 static atomic_t cpus_booted = ATOMIC_INIT(0);
 
 /* These are defined by the board-specific code. */
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index b68ff70..8fde950 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -25,6 +25,7 @@
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -281,7 +282,7 @@
 	if (!name)
 		return -EFAULT;
 	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	return err?-EFAULT:0;
 }
@@ -309,3 +310,19 @@
 				(u64)len0 << 32 | len1,	advice);
 #endif
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __sc0 __asm__ ("r3") = __NR_execve;
+	register long __sc4 __asm__ ("r4") = (long) filename;
+	register long __sc5 __asm__ ("r5") = (long) argv;
+	register long __sc6 __asm__ ("r6") = (long) envp;
+	__asm__ __volatile__ ("trapa	#0x13" : "=z" (__sc0)
+			: "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
+			: "memory");
+	return __sc0;
+}
diff --git a/arch/sh/kernel/vsyscall/.gitignore b/arch/sh/kernel/vsyscall/.gitignore
new file mode 100644
index 0000000..40836ad
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/.gitignore
@@ -0,0 +1 @@
+vsyscall.lds
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index 26b6046..1efbac1 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -7,7 +7,6 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/types.h>
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index a22d914..e0122bd 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -111,7 +111,7 @@
 
 static int cache_debugfs_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, cache_seq_show, inode->u.generic_ip);
+	return single_open(file, cache_seq_show, inode->i_private);
 }
 
 static struct file_operations cache_debugfs_fops = {
diff --git a/arch/sh/tools/gen-mach-types b/arch/sh/tools/gen-mach-types
index bb2b822..65161e3 100644
--- a/arch/sh/tools/gen-mach-types
+++ b/arch/sh/tools/gen-mach-types
@@ -20,8 +20,6 @@
 	  printf("#ifndef __ASM_SH_MACHTYPES_H\n");
 	  printf("#define __ASM_SH_MACHTYPES_H\n");
 	  printf("\n");
-	  printf("#include <linux/config.h>\n");
-	  printf("\n");
 	  printf("/*\n");
 	  printf(" * We'll use the following MACH_xxx defs for placeholders for the time\n");
 	  printf(" * being .. these will all go away once sh_machtype is assigned per-board.\n");
diff --git a/arch/sh64/boot/compressed/misc.c b/arch/sh64/boot/compressed/misc.c
index ee7a1b6..aea00c5 100644
--- a/arch/sh64/boot/compressed/misc.c
+++ b/arch/sh64/boot/compressed/misc.c
@@ -1,5 +1,5 @@
 /*
- * arch/shmedia/boot/compressed/misc.c
+ * arch/sh64/boot/compressed/misc.c
  *
  * This is a collection of several routines from gzip-1.0.3
  * adapted for Linux.
diff --git a/arch/sh64/configs/cayman_defconfig b/arch/sh64/configs/cayman_defconfig
index 48f2740..d81df57 100644
--- a/arch/sh64/configs/cayman_defconfig
+++ b/arch/sh64/configs/cayman_defconfig
@@ -1,49 +1,62 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Fri Feb 25 18:14:31 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 13:30:51 2006
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH64=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -51,6 +64,27 @@
 # CONFIG_MODULES is not set
 
 #
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
 # System type
 #
 # CONFIG_SH_GENERIC is not set
@@ -103,15 +137,23 @@
 CONFIG_HDSP253_LED=y
 CONFIG_SH_DMA=y
 CONFIG_PREEMPT=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
-CONFIG_SUPERHYWAY=y
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -119,10 +161,6 @@
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
-#
-
-#
 # PCI Hotplug Support
 #
 # CONFIG_HOTPLUG_PCI is not set
@@ -135,6 +173,92 @@
 # CONFIG_BINFMT_MISC is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
 # Device Drivers
 #
 
@@ -145,6 +269,12 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -163,7 +293,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -176,18 +305,9 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -198,7 +318,9 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -209,6 +331,7 @@
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -218,15 +341,18 @@
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -234,40 +360,39 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP 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
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 # 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=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -276,6 +401,9 @@
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -288,70 +416,8 @@
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-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
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -364,6 +430,11 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -371,7 +442,9 @@
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
 
 #
 # Tulip family network device support
@@ -385,6 +458,7 @@
 # CONFIG_DE4X5 is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
@@ -416,15 +490,22 @@
 # 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_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -447,6 +528,8 @@
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -462,6 +545,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -476,19 +560,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_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -497,6 +568,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -506,11 +578,23 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -522,9 +606,11 @@
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -551,7 +637,7 @@
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -564,14 +650,35 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -581,6 +688,7 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -590,7 +698,13 @@
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -599,9 +713,10 @@
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
@@ -617,18 +732,20 @@
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 # CONFIG_FONT_8x8 is not set
 CONFIG_FONT_8x16=y
 # CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 is not set
 # CONFIG_FONT_MINI_4x6 is not set
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 
 #
 # Logo configuration
@@ -650,12 +767,13 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -669,15 +787,51 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -687,17 +841,18 @@
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -717,14 +872,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -748,12 +903,14 @@
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -762,6 +919,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
@@ -781,6 +939,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -796,13 +955,32 @@
 #
 # Kernel hacking
 #
-CONFIG_DEBUG_KERNEL=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set
 CONFIG_SH64_PROC_TLB=y
@@ -824,14 +1002,12 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/sh64/kernel/alphanum.c b/arch/sh64/kernel/alphanum.c
index 9079d1e..91707c1 100644
--- a/arch/sh64/kernel/alphanum.c
+++ b/arch/sh64/kernel/alphanum.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh64/kernel/alpanum.c
+ * arch/sh64/kernel/alphanum.c
  *
  * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
  *
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index db475b7..525d0ec 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -20,261 +20,16 @@
 /*
  * This file handles the architecture-dependent parts of process handling..
  */
-
-/* Temporary flags/tests. All to be removed/undefined. BEGIN */
-#define IDLE_TRACE
-#define VM_SHOW_TABLES
-#define VM_TEST_FAULT
-#define VM_TEST_RTLBMISS
-#define VM_TEST_WTLBMISS
-
-#undef VM_SHOW_TABLES
-#undef IDLE_TRACE
-/* Temporary flags/tests. All to be removed/undefined. END */
-
-#define __KERNEL_SYSCALLS__
-#include <stdarg.h>
-
-#include <linux/kernel.h>
-#include <linux/rwsem.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/unistd.h>
-#include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-
+#include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>		/* includes also <asm/registers.h> */
-#include <asm/mmu_context.h>
-#include <asm/elf.h>
-#include <asm/page.h>
-
-#include <linux/irq.h>
 
 struct task_struct *last_task_used_math = NULL;
 
-#ifdef IDLE_TRACE
-#ifdef VM_SHOW_TABLES
-/* For testing */
-static void print_PTE(long base)
-{
-	int i, skip=0;
-	long long x, y, *p = (long long *) base;
-
-	for (i=0; i< 512; i++, p++){
-		if (*p == 0) {
-			if (!skip) {
-				skip++;
-				printk("(0s) ");
-			}
-		} else {
-			skip=0;
-			x = (*p) >> 32;
-			y = (*p) & 0xffffffff;
-			printk("%08Lx%08Lx ", x, y);
-			if (!((i+1)&0x3)) printk("\n");
-		}
-	}
-}
-
-/* For testing */
-static void print_DIR(long base)
-{
-	int i, skip=0;
-	long *p = (long *) base;
-
-	for (i=0; i< 512; i++, p++){
-		if (*p == 0) {
-			if (!skip) {
-				skip++;
-				printk("(0s) ");
-			}
-		} else {
-			skip=0;
-			printk("%08lx ", *p);
-			if (!((i+1)&0x7)) printk("\n");
-		}
-	}
-}
-
-/* For testing */
-static void print_vmalloc_first_tables(void)
-{
-
-#define PRESENT	0x800	/* Bit 11 */
-
-	/*
-	 * Do it really dirty by looking at raw addresses,
-         * raw offsets, no types. If we used pgtable/pgalloc
-	 * macros/definitions we could hide potential bugs.
-	 *
-	 * Note that pointers are 32-bit for CDC.
-	 */
-	long pgdt, pmdt, ptet;
-
-	pgdt = (long) &swapper_pg_dir;
-	printk("-->PGD (0x%08lx):\n", pgdt);
-	print_DIR(pgdt);
-	printk("\n");
-
-	/* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */
-	pgdt += 4;
-	pmdt = (long) (* (long *) pgdt);
-	if (!(pmdt & PRESENT)) {
-		printk("No PMD\n");
-		return;
-	} else pmdt &= 0xfffff000;
-
-	printk("-->PMD (0x%08lx):\n", pmdt);
-	print_DIR(pmdt);
-	printk("\n");
-
-	/* Get the pmdt displacement for 0xc0000000 */
-	pmdt += 2048;
-
-	/* just look at first two address ranges ... */
-        /* ... 0xc0000000 ... */
-	ptet = (long) (* (long *) pmdt);
-	if (!(ptet & PRESENT)) {
-		printk("No PTE0\n");
-		return;
-	} else ptet &= 0xfffff000;
-
-	printk("-->PTE0 (0x%08lx):\n", ptet);
-	print_PTE(ptet);
-	printk("\n");
-
-        /* ... 0xc0001000 ... */
-	ptet += 4;
-	if (!(ptet & PRESENT)) {
-		printk("No PTE1\n");
-		return;
-	} else ptet &= 0xfffff000;
-	printk("-->PTE1 (0x%08lx):\n", ptet);
-	print_PTE(ptet);
-	printk("\n");
-}
-#else
-#define print_vmalloc_first_tables()
-#endif	/* VM_SHOW_TABLES */
-
-static void test_VM(void)
-{
-	void *a, *b, *c;
-
-#ifdef VM_SHOW_TABLES
-	printk("Initial PGD/PMD/PTE\n");
-#endif
-        print_vmalloc_first_tables();
-
-	printk("Allocating 2 bytes\n");
-	a = vmalloc(2);
-        print_vmalloc_first_tables();
-
-	printk("Allocating 4100 bytes\n");
-	b = vmalloc(4100);
-        print_vmalloc_first_tables();
-
-	printk("Allocating 20234 bytes\n");
-	c = vmalloc(20234);
-        print_vmalloc_first_tables();
-
-#ifdef VM_TEST_FAULT
-	/* Here you may want to fault ! */
-
-#ifdef VM_TEST_RTLBMISS
-	printk("Ready to fault upon read.\n");
-	if (* (char *) a) {
-		printk("RTLBMISSed on area a !\n");
-	}
-	printk("RTLBMISSed on area a !\n");
-#endif
-
-#ifdef VM_TEST_WTLBMISS
-	printk("Ready to fault upon write.\n");
-	*((char *) b) = 'L';
-	printk("WTLBMISSed on area b !\n");
-#endif
-
-#endif	/* VM_TEST_FAULT */
-
-	printk("Deallocating the 4100 byte chunk\n");
-	vfree(b);
-        print_vmalloc_first_tables();
-
-	printk("Deallocating the 2 byte chunk\n");
-	vfree(a);
-        print_vmalloc_first_tables();
-
-	printk("Deallocating the last chunk\n");
-	vfree(c);
-        print_vmalloc_first_tables();
-}
-
-extern unsigned long volatile jiffies;
-int once = 0;
-unsigned long old_jiffies;
-int pid = -1, pgid = -1;
-
-void idle_trace(void)
-{
-
-	_syscall0(int, getpid)
-	_syscall1(int, getpgid, int, pid)
-
-	if (!once) {
-        	/* VM allocation/deallocation simple test */
-		test_VM();
-		pid = getpid();
-
-        	printk("Got all through to Idle !!\n");
-        	printk("I'm now going to loop forever ...\n");
-        	printk("Any ! below is a timer tick.\n");
-		printk("Any . below is a getpgid system call from pid = %d.\n", pid);
-
-
-        	old_jiffies = jiffies;
-		once++;
-	}
-
-	if (old_jiffies != jiffies) {
-		old_jiffies = jiffies - old_jiffies;
-		switch (old_jiffies) {
-		case 1:
-			printk("!");
-			break;
-		case 2:
-			printk("!!");
-			break;
-		case 3:
-			printk("!!!");
-			break;
-		case 4:
-			printk("!!!!");
-			break;
-		default:
-			printk("(%d!)", (int) old_jiffies);
-		}
-		old_jiffies = jiffies;
-	}
-	pgid = getpgid(pid);
-	printk(".");
-}
-#else
-#define idle_trace()	do { } while (0)
-#endif	/* IDLE_TRACE */
-
 static int hlt_counter = 1;
 
 #define HARD_IDLE_TIMEOUT (HZ / 3)
@@ -323,7 +78,6 @@
 			local_irq_disable();
 			while (!need_resched()) {
 				local_irq_enable();
-				idle_trace();
 				hlt();
 				local_irq_disable();
 			}
@@ -622,6 +376,10 @@
 /*
  * Create a kernel thread
  */
+ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+	do_exit(fn(arg));
+}
 
 /*
  * This is the mechanism for creating a new kernel thread.
@@ -633,19 +391,17 @@
  */
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
-	/* A bit less processor dependent than older sh ... */
-	unsigned int reply;
+	struct pt_regs regs;
 
-static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
-static __inline__ _syscall1(int,exit,int,ret)
+	memset(&regs, 0, sizeof(regs));
+	regs.regs[2] = (unsigned long)arg;
+	regs.regs[3] = (unsigned long)fn;
 
-	reply = clone(flags | CLONE_VM, 0);
-	if (!reply) {
-		/* Child */
-		reply = exit(fn(arg));
-	}
+	regs.pc = (unsigned long)kernel_thread_helper;
+	regs.sr = (1 << 30);
 
-	return reply;
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+		       &regs, 0, NULL, NULL);
 }
 
 /*
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
index 58ff7d5..ad0fa4e 100644
--- a/arch/sh64/kernel/sys_sh64.c
+++ b/arch/sh64/kernel/sys_sh64.c
@@ -32,6 +32,7 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 #include <asm/ptrace.h>
+#include <asm/unistd.h>
 
 #define REG_3	3
 
@@ -279,7 +280,25 @@
 	if (!name)
 		return -EFAULT;
 	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	return err?-EFAULT:0;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
+	register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
+	register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv;
+	register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp;
+	__asm__ __volatile__ ("trapa	%1 !\t\t\t execve(%2,%3,%4)"
+	: "=r" (__sc0)
+	: "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) );
+	__asm__ __volatile__ ("!dummy	%0 %1 %2 %3"
+	: : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory");
+	return __sc0;
+}
diff --git a/arch/sh64/lib/c-checksum.c b/arch/sh64/lib/c-checksum.c
index 53c1cab..0e8a742 100644
--- a/arch/sh64/lib/c-checksum.c
+++ b/arch/sh64/lib/c-checksum.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/lib/csum_parial.c
+ * arch/sh64/lib/c-checksum.c
  *
  * This file contains network checksum routines that are better done
  * in an architecture-specific manner due to speed..
diff --git a/arch/sh64/mach-cayman/led.c b/arch/sh64/mach-cayman/led.c
index 8b3cc4c..b4e122f 100644
--- a/arch/sh64/mach-cayman/led.c
+++ b/arch/sh64/mach-cayman/led.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh64/kernel/led_cayman.c
+ * arch/sh64/mach-cayman/led.c
  *
  * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
  *
diff --git a/arch/sh64/oprofile/op_model_null.c b/arch/sh64/oprofile/op_model_null.c
index a845b08..a750ea1 100644
--- a/arch/sh64/oprofile/op_model_null.c
+++ b/arch/sh64/oprofile/op_model_null.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/oprofile/op_model_null.c
+ * arch/sh64/oprofile/op_model_null.c
  *
  * Copyright (C) 2003  Paul Mundt
  *
diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c
index c09afd9..01b07bb 100644
--- a/arch/sparc/kernel/sys_solaris.c
+++ b/arch/sparc/kernel/sys_solaris.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sparc/sys_solaris.c
+ * linux/arch/sparc/kernel/sys_solaris.c
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  */
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 896863f..a954a0c 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -24,6 +24,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
+#include <asm/unistd.h>
 
 /* #define DEBUG_UNIMP_SYSCALL */
 
@@ -475,16 +476,38 @@
 
  	down_read(&uts_sem);
  	
-	nlen = strlen(system_utsname.domainname) + 1;
+	nlen = strlen(utsname()->domainname) + 1;
 	err = -EINVAL;
 	if (nlen > len)
 		goto out;
 
 	err = -EFAULT;
-	if (!copy_to_user(name, system_utsname.domainname, nlen))
+	if (!copy_to_user(name, utsname()->domainname, nlen))
 		err = 0;
 
 out:
 	up_read(&uts_sem);
 	return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	register long __g1 __asm__ ("g1") = __NR_execve;
+	register long __o0 __asm__ ("o0") = (long)(filename);
+	register long __o1 __asm__ ("o1") = (long)(argv);
+	register long __o2 __asm__ ("o2") = (long)(envp);
+	asm volatile ("t 0x10\n\t"
+		      "bcc 1f\n\t"
+		      "mov %%o0, %0\n\t"
+		      "sub %%g0, %%o0, %0\n\t"
+		      "1:\n\t"
+		      : "=r" (__res), "=&r" (__o0)
+		      : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+		      : "cc");
+	return __res;
+}
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index aa0fb2e..6f3ac54 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -325,21 +325,25 @@
 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
 
 static int sunos_filldir(void * __buf, const char * name, int namlen,
-			 loff_t offset, ino_t ino, unsigned int d_type)
+			 loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct sunos_dirent __user *dirent;
 	struct sunos_dirent_callback * buf = __buf;
+	unsigned long d_ino;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	if (dirent)
 		put_user(offset, &dirent->d_off);
 	dirent = buf->curr;
 	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
 	copy_to_user(dirent->d_name, name, namlen);
@@ -406,19 +410,23 @@
 };
 
 static int sunos_filldirentry(void * __buf, const char * name, int namlen,
-			      loff_t offset, ino_t ino, unsigned int d_type)
+			      loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct sunos_direntry __user *dirent;
 	struct sunos_direntry_callback *buf = __buf;
+	unsigned long d_ino;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	dirent = buf->curr;
 	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
 	copy_to_user(dirent->d_name, name, namlen);
@@ -483,13 +491,18 @@
 {
 	int ret;
 	down_read(&uts_sem);
-	ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1);
+	ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
+			   sizeof(name->sname) - 1);
 	if (!ret) {
-		ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1);
+		ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0],
+				      sizeof(name->nname) - 1);
 		ret |= __put_user('\0', &name->nname[8]);
-		ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1);
-		ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
-		ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
+		ret |= __copy_to_user(&name->rel[0], &utsname()->release[0],
+				      sizeof(name->rel) - 1);
+		ret |= __copy_to_user(&name->ver[0], &utsname()->version[0],
+				      sizeof(name->ver) - 1);
+		ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0],
+				      sizeof(name->mach) - 1);
 	}
 	up_read(&uts_sem);
 	return ret ? -EFAULT : 0;
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 8d8ca71..b627f8d 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -420,7 +420,7 @@
 
 config KPROBES
 	bool "Kprobes (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && MODULES
+	depends on KALLSYMS && EXPERIMENTAL && MODULES
 	help
 	  Kprobes allows you to trap at almost any kernel address and
 	  execute a callback function.  register_kprobe() establishes
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 0fbdaa5..f54ab37 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.18
-# Tue Sep 26 23:09:35 2006
+# Mon Oct  2 14:24:40 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -35,17 +35,20 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -77,6 +80,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 CONFIG_BLK_DEV_IO_TRACE=y
 
 #
@@ -154,7 +158,7 @@
 #
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
-# CONFIG_SOLARIS_EMUL is not set
+CONFIG_SOLARIS_EMUL=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -622,6 +626,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -644,6 +649,7 @@
 CONFIG_KEYBOARD_LKKBD=m
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_SERIAL=y
@@ -821,6 +827,7 @@
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -1092,6 +1099,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1123,6 +1131,7 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1130,9 +1139,9 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
@@ -1256,8 +1265,10 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1374,9 +1385,11 @@
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_LKDTM is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index e55466c..0b9c706 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -4,8 +4,6 @@
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
  */
 
-#define __KERNEL_SYSCALLS__
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -14,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
+#include <linux/syscalls.h>
 
 #include <asm/system.h>
 #include <asm/auxio.h>
@@ -98,7 +97,7 @@
 
 	/* Ok, down we go... */
 	button_pressed = 0;
-	if (execve("/sbin/shutdown", argv, envp) < 0) {
+	if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
 		printk("powerd: shutdown execution failed\n");
 		add_wait_queue(&powerd_wait, &wait);
 		goto again;
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 708ba9b..c45f21b 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -29,6 +29,7 @@
 #include <asm/psrcompat.h>
 #include <asm/fpumacro.h>
 #include <asm/visasm.h>
+#include <asm/compat_signal.h>
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index c608c94..a53d4ab 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -31,6 +31,7 @@
 #include <asm/utrap.h>
 #include <asm/perfctr.h>
 #include <asm/a.out.h>
+#include <asm/unistd.h>
 
 /* #define DEBUG_UNIMP_SYSCALL */
 
@@ -712,13 +713,13 @@
 
  	down_read(&uts_sem);
  	
-	nlen = strlen(system_utsname.domainname) + 1;
+	nlen = strlen(utsname()->domainname) + 1;
 	err = -EINVAL;
 	if (nlen > len)
 		goto out;
 
 	err = -EFAULT;
-	if (!copy_to_user(name, system_utsname.domainname, nlen))
+	if (!copy_to_user(name, utsname()->domainname, nlen))
 		err = 0;
 
 out:
@@ -963,3 +964,23 @@
 	};
 	return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	register long __g1 __asm__ ("g1") = __NR_execve;
+	register long __o0 __asm__ ("o0") = (long)(filename);
+	register long __o1 __asm__ ("o1") = (long)(argv);
+	register long __o2 __asm__ ("o2") = (long)(envp);
+	asm volatile ("t 0x6d\n\t"
+		      "sub %%g0, %%o0, %0\n\t"
+		      "movcc %%xcc, %%o0, %0\n\t"
+		      : "=r" (__res), "=&r" (__o0)
+		      : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+		      : "cc");
+	return __res;
+}
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 69444f2..e27cb71 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -61,6 +61,7 @@
 #include <asm/semaphore.h>
 #include <asm/mmu_context.h>
 #include <asm/a.out.h>
+#include <asm/compat_signal.h>
 
 asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
 {
@@ -337,12 +338,17 @@
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+	compat_ino_t ino;
 	int err;
 
 	if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
 	    !old_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
+	ino = stat->ino;
+	if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+		return -EOVERFLOW;
+
 	err  = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
 	err |= put_user(stat->ino, &statbuf->st_ino);
 	err |= put_user(stat->mode, &statbuf->st_mode);
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 87ebdf8..7da72d3 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -43,6 +43,7 @@
 #include <asm/idprom.h> /* for gethostid() */
 #include <asm/unistd.h>
 #include <asm/system.h>
+#include <asm/compat_signal.h>
 
 /* For the nfs mount emulation */
 #include <linux/socket.h>
@@ -280,16 +281,20 @@
 	struct sunos_dirent __user *dirent;
 	struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+	u32 d_ino;
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	if (dirent)
 		put_user(offset, &dirent->d_off);
 	dirent = buf->curr;
 	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
 	if (copy_to_user(dirent->d_name, name, namlen))
@@ -363,14 +368,18 @@
 	struct sunos_direntry_callback * buf =
 		(struct sunos_direntry_callback *) __buf;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+	u32 d_ino;
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	dirent = buf->curr;
 	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
+	put_user(d_ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
 	if (copy_to_user(dirent->d_name, name, namlen))
@@ -439,16 +448,16 @@
 	int ret;
 
 	down_read(&uts_sem);
-	ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0],
+	ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
 			   sizeof(name->sname) - 1);
-	ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0],
+	ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0],
 			    sizeof(name->nname) - 1);
 	ret |= put_user('\0', &name->nname[8]);
-	ret |= copy_to_user(&name->rel[0], &system_utsname.release[0],
+	ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
 			    sizeof(name->rel) - 1);
-	ret |= copy_to_user(&name->ver[0], &system_utsname.version[0],
+	ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
 			    sizeof(name->ver) - 1);
-	ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0],
+	ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
 			    sizeof(name->mach) - 1);
 	up_read(&uts_sem);
 	return (ret ? -EFAULT : 0);
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 0f0eb6a..12a940c 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -82,12 +82,17 @@
 
 static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
 {
+	u32 ino;
+
 	if (kbuf->size > MAX_NON_LFS ||
 	    !sysv_valid_dev(kbuf->dev) ||
 	    !sysv_valid_dev(kbuf->rdev))
 		return -EOVERFLOW;
+	ino = kbuf->ino;
+	if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
+		return -EOVERFLOW;
 	if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev)	||
-	    __put_user (kbuf->ino, &ubuf->st_ino)		||
+	    __put_user (ino, &ubuf->st_ino)				||
 	    __put_user (kbuf->mode, &ubuf->st_mode)		||
 	    __put_user (kbuf->nlink, &ubuf->st_nlink)	||
 	    __put_user (kbuf->uid, &ubuf->st_uid)		||
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 9c58132..9ed9979 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -249,7 +249,7 @@
 		/* Let's cheat */
 		err  = set_utsfield(v->sysname, "SunOS", 1, 0);
 		down_read(&uts_sem);
-		err |= set_utsfield(v->nodename, system_utsname.nodename,
+		err |= set_utsfield(v->nodename, utsname()->nodename,
 				    1, 1);
 		up_read(&uts_sem);
 		err |= set_utsfield(v->release, "2.6", 0, 0);
@@ -273,7 +273,7 @@
 	/* Why should we not lie a bit? */
 	down_read(&uts_sem);
 	err  = set_utsfield(v->sysname, "SunOS", 0, 0);
-	err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
+	err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
 	err |= set_utsfield(v->release, "5.6", 0, 0);
 	err |= set_utsfield(v->version, "Generic", 0, 0);
 	err |= set_utsfield(v->machine, machine(), 0, 0);
@@ -305,7 +305,7 @@
 	case SI_HOSTNAME:
 		r = buffer + 256;
 		down_read(&uts_sem);
-		for (p = system_utsname.nodename, q = buffer; 
+		for (p = utsname()->nodename, q = buffer;
 		     q < r && *p && *p != '.'; *q++ = *p++);
 		up_read(&uts_sem);
 		*q = 0;
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 76e85bb..d753075 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -257,7 +257,7 @@
 	UML and spend long times with UML stopped at a breakpoint.  In this
 	case, when UML is restarted, it will call the timer enough times to make
 	up for the time spent at the breakpoint.  This could result in a
-	noticable lag.  If this is a problem, then disable this option.
+	noticeable lag.  If this is a problem, then disable this option.
 
 endmenu
 
diff --git a/arch/um/Makefile b/arch/um/Makefile
index f6ad832..c8016a9 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -102,7 +102,7 @@
 define archhelp
   echo '* linux		- Binary kernel image (./linux) - for backward'
   echo '		   compatibility only, this creates a hard link to the'
-  echo '		   real kernel binary, the the "vmlinux" binary you'
+  echo '		   real kernel binary, the "vmlinux" binary you'
   echo '		   find in the kernel root.'
 endef
 
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 563ce76..cfd9f01 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -497,7 +497,7 @@
 }
 
 /* Common setup code for both startup command line and mconsole initialization.
- * @lines contains the the array (of size @num) to modify;
+ * @lines contains the array (of size @num) to modify;
  * @init is the setup string;
  */
 
@@ -642,9 +642,9 @@
 }
 
 struct tty_driver *line_register_devfs(struct lines *set,
-			 struct line_driver *line_driver,
-			 struct tty_operations *ops, struct line *lines,
-			 int nlines)
+				       struct line_driver *line_driver,
+				       const struct tty_operations *ops,
+				       struct line *lines, int nlines)
 {
 	int i;
 	struct tty_driver *driver = alloc_tty_driver(nlines);
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 773a134..a67dcbd 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -106,9 +106,9 @@
 {
 	char version[256];
 
-	sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
-		system_utsname.nodename, system_utsname.release,
-		system_utsname.version, system_utsname.machine);
+	sprintf(version, "%s %s %s %s %s", utsname()->sysname,
+		utsname()->nodename, utsname()->release,
+		utsname()->version, utsname()->machine);
 	mconsole_reply(req, version, 0, 0);
 }
 
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 642c9a0..7be2481 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -91,10 +91,9 @@
 			  void *data);
 extern void line_close_chan(struct line *line);
 extern struct tty_driver * line_register_devfs(struct lines *set,
-				struct line_driver *line_driver,
-				struct tty_operations *driver,
-				struct line *lines,
-				int nlines);
+					       struct line_driver *line_driver,
+					       const struct tty_operations *driver,
+					       struct line *lines, int nlines);
 extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
 extern void close_lines(struct line *lines, int nlines);
 
diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
index 128faf0..4cd61a8 100644
--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -55,7 +55,7 @@
 #define PTRACE_OLDSETOPTIONS 21
 #endif
 
-/* These are before the system call, so the the system call number is RAX
+/* These are before the system call, so the system call number is RAX
  * rather than ORIG_RAX, and arg4 is R10 rather than RCX
  */
 #define REGS_SYSCALL_NR PT_INDEX(RAX)
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 48cf88d..f5ed862 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -110,7 +110,7 @@
 	if (!name)
 		return -EFAULT;
 	down_read(&uts_sem);
-	err = copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	return err?-EFAULT:0;
 }
@@ -126,21 +126,21 @@
 
   	down_read(&uts_sem);
 
-	error = __copy_to_user(&name->sysname,&system_utsname.sysname,
+	error = __copy_to_user(&name->sysname, &utsname()->sysname,
 			       __OLD_UTS_LEN);
-	error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
+	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
 				__OLD_UTS_LEN);
-	error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->release,&system_utsname.release,
+	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->release, &utsname()->release,
 				__OLD_UTS_LEN);
-	error |= __put_user(0,name->release+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->version,&system_utsname.version,
+	error |= __put_user(0, name->release + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->version, &utsname()->version,
 				__OLD_UTS_LEN);
-	error |= __put_user(0,name->version+__OLD_UTS_LEN);
-	error |= __copy_to_user(&name->machine,&system_utsname.machine,
+	error |= __put_user(0, name->version + __OLD_UTS_LEN);
+	error |= __copy_to_user(&name->machine, &utsname()->machine,
 				__OLD_UTS_LEN);
-	error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+	error |= __put_user(0, name->machine + __OLD_UTS_LEN);
 
 	up_read(&uts_sem);
 
@@ -164,3 +164,16 @@
 	spin_unlock(&syscall_lock);
 	return(ret);
 }
+
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	mm_segment_t fs;
+	int ret;
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = um_execve(filename, argv, envp);
+	set_fs(fs);
+
+	return ret;
+}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 5500571..97d88e7 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -167,7 +167,7 @@
 
 static int __init uml_version_setup(char *line, int *add)
 {
-	printf("%s\n", system_utsname.release);
+	printf("%s\n", init_utsname()->release);
 	exit(0);
 
 	return 0;
@@ -278,7 +278,7 @@
 {
  	const char **p;
 
-	printf(usage_string, system_utsname.release);
+	printf(usage_string, init_utsname()->release);
  	p = &__uml_help_start;
  	while (p < &__uml_help_end) {
  		printf("%s", *p);
@@ -403,7 +403,7 @@
 	/* Reserve up to 4M after the current brk */
 	uml_reserved = ROUND_4M(brk_start) + (1 << 22);
 
-	setup_machinename(system_utsname.machine);
+	setup_machinename(init_utsname()->machine);
 
 #ifdef CONFIG_CMDLINE_ON_HOST
 	argv1_begin = argv[1];
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index ff20362..51f0893 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -11,6 +11,7 @@
 #include <sys/mman.h>
 #include <sys/wait.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include "ptrace_user.h"
 #include "os.h"
 #include "user.h"
@@ -140,11 +141,9 @@
  * syscalls, and also breaks with clone(), which does not unshare the TLS.
  */
 
-inline _syscall0(pid_t, getpid)
-
 int os_getpid(void)
 {
-	return(getpid());
+	return(syscall(__NR_getpid));
 }
 
 int os_getpgrp(void)
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 120abbe..6e945ab 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -1,10 +1,9 @@
 #include <errno.h>
 #include <linux/unistd.h>
+#include <sys/syscall.h>
 #include "sysdep/tls.h"
 #include "user_util.h"
 
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-
 /* Checks whether host supports TLS, and sets *tls_min according to the value
  * valid on the host.
  * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
@@ -17,7 +16,7 @@
 		user_desc_t info;
 		info.entry_number = val[i];
 
-		if (get_thread_area(&info) == 0) {
+		if (syscall(__NR_get_thread_area, &info) == 0) {
 			*tls_min = val[i];
 			*supports_tls = 1;
 			return;
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index 9cb09a4..a2de258 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -1,5 +1,6 @@
 #include <errno.h>
 #include <sys/ptrace.h>
+#include <sys/syscall.h>
 #include <asm/ldt.h>
 #include "sysdep/tls.h"
 #include "uml-config.h"
@@ -48,14 +49,11 @@
 #ifdef UML_CONFIG_MODE_TT
 #include "linux/unistd.h"
 
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-static _syscall1(int, set_thread_area, user_desc_t *, u_info);
-
 int do_set_thread_area_tt(user_desc_t *info)
 {
 	int ret;
 
-	ret = set_thread_area(info);
+	ret = syscall(__NR_set_thread_area,info);
 	if (ret < 0) {
 		ret = -errno;
 	}
@@ -66,7 +64,7 @@
 {
 	int ret;
 
-	ret = get_thread_area(info);
+	ret = syscall(__NR_get_thread_area,info);
 	if (ret < 0) {
 		ret = -errno;
 	}
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 1b0ad0e4..8e55cd5 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -5,20 +5,17 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
+#include <sys/syscall.h>
 
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-	if(munmap(to, size) < 0){
+	if (syscall(__NR_munmap, to, size) < 0){
 		return(-1);
 	}
-	if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+	if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
 		return(-1);
 	}
-	if(munmap(from, size) < 0){
+	if (syscall(__NR_munmap, from, size) < 0){
 		return(-1);
 	}
 	return(0);
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 6fce9f4..73ce446 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -21,7 +21,7 @@
 {
 	int err;
 	down_read(&uts_sem);
-	err = copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	if (personality(current->personality) == PER_LINUX32)
 		err |= copy_to_user(&name->machine, "i686", 5);
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
index d0a25af..ce3e07f 100644
--- a/arch/um/sys-x86_64/sysrq.c
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -16,7 +16,7 @@
 	printk("\n");
 	print_modules();
 	printk("Pid: %d, comm: %.20s %s %s\n",
-	       current->pid, current->comm, print_tainted(), system_utsname.release);
+	       current->pid, current->comm, print_tainted(), init_utsname()->release);
 	printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
 	       PT_REGS_RIP(regs));
 	printk("\nRSP: %016lx  EFLAGS: %08lx\n", PT_REGS_RSP(regs),
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
index f4a4bff..57c9286 100644
--- a/arch/um/sys-x86_64/unmap.c
+++ b/arch/um/sys-x86_64/unmap.c
@@ -5,20 +5,17 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
+#include <sys/syscall.h>
 
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-	if(munmap(to, size) < 0){
+	if (syscall(__NR_munmap, to, size) < 0){
 		return(-1);
 	}
-	if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+	if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
 		return(-1);
 	}
-	if(munmap(from, size) < 0){
+	if (syscall(__NR_munmap, from, size) < 0){
 		return(-1);
 	}
 	return(0);
diff --git a/arch/v850/kernel/entry.S b/arch/v850/kernel/entry.S
index d991e45..8bc521c 100644
--- a/arch/v850/kernel/entry.S
+++ b/arch/v850/kernel/entry.S
@@ -195,7 +195,7 @@
 	sst.w	lp, PTO+PT_GPR(GPR_LP)[ep];				      \
 	type ## _STATE_SAVER
 /* Pop a register state pushed by PUSH_STATE, except for the stack pointer,
-   from the the stack.  */
+   from the stack.  */
 #define POP_STATE(type)							      \
 	mov	sp, ep;							      \
 	type ## _STATE_RESTORER;					      \
diff --git a/arch/v850/kernel/memcons.c b/arch/v850/kernel/memcons.c
index 815f8a4..92f514f 100644
--- a/arch/v850/kernel/memcons.c
+++ b/arch/v850/kernel/memcons.c
@@ -104,7 +104,7 @@
 	return 0;
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
 	.open = memcons_tty_open,
 	.write = memcons_tty_write,
 	.write_room = memcons_tty_write_room,
diff --git a/arch/v850/kernel/simcons.c b/arch/v850/kernel/simcons.c
index 3975aa0..9973596 100644
--- a/arch/v850/kernel/simcons.c
+++ b/arch/v850/kernel/simcons.c
@@ -77,7 +77,7 @@
 	return 0;
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
 	.open = simcons_tty_open,
 	.write = simcons_tty_write,
 	.write_room = simcons_tty_write_room,
diff --git a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c
index 2ec0700..d2b1fb1 100644
--- a/arch/v850/kernel/syscalls.c
+++ b/arch/v850/kernel/syscalls.c
@@ -33,6 +33,7 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 #include <asm/semaphore.h>
+#include <asm/unistd.h>
 
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
@@ -194,3 +195,22 @@
 out:
 	return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register char *__a __asm__ ("r6") = filename;
+	register void *__b __asm__ ("r7") = argv;
+	register void *__c __asm__ ("r8") = envp;
+	register unsigned long __syscall __asm__ ("r12") = __NR_execve;
+	register unsigned long __ret __asm__ ("r10");
+	__asm__ __volatile__ ("trap 0"
+			: "=r" (__ret), "=r" (__syscall)
+			: "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+			: "r1", "r5", "r11", "r13", "r14",
+			  "r15", "r16", "r17", "r18", "r19");
+	return __ret;
+}
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index b87a19f..010d226 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -310,7 +310,7 @@
        help
 	 Enable K8 NUMA node topology detection.  You should say Y here if
 	 you have a multi processor AMD K8 system. This uses an old
-	 method to read the NUMA configurtion directly from the builtin
+	 method to read the NUMA configuration directly from the builtin
 	 Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
 	 instead, which also takes priority if both are compiled in.   
 
@@ -690,7 +690,7 @@
 
 config KPROBES
 	bool "Kprobes (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && MODULES
+	depends on KALLSYMS && EXPERIMENTAL && MODULES
 	help
 	  Kprobes allows you to trap at almost any kernel address and
 	  execute a callback function.  register_kprobe() establishes
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index f280d36..c9bac3a 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -76,6 +76,8 @@
 
 int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
 {
+	compat_ino_t ino;
+
 	typeof(ubuf->st_uid) uid = 0;
 	typeof(ubuf->st_gid) gid = 0;
 	SET_UID(uid, kbuf->uid);
@@ -84,9 +86,12 @@
 		return -EOVERFLOW;
 	if (kbuf->size >= 0x7fffffff)
 		return -EOVERFLOW;
+	ino = kbuf->ino;
+	if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
+		return -EOVERFLOW;
 	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
 	    __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
-	    __put_user (kbuf->ino, &ubuf->st_ino) ||
+	    __put_user (ino, &ubuf->st_ino) ||
 	    __put_user (kbuf->mode, &ubuf->st_mode) ||
 	    __put_user (kbuf->nlink, &ubuf->st_nlink) ||
 	    __put_user (uid, &ubuf->st_uid) ||
@@ -784,36 +789,36 @@
 
 	if (!name)
 		return -EFAULT;
-	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+	if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
 		return -EFAULT;
   
   	down_read(&uts_sem);
-	
-	err = __copy_to_user(&name->sysname,&system_utsname.sysname,
+
+	err = __copy_to_user(&name->sysname,&utsname()->sysname,
 				__OLD_UTS_LEN);
 	err |= __put_user(0,name->sysname+__OLD_UTS_LEN);
-	err |= __copy_to_user(&name->nodename,&system_utsname.nodename,
+	err |= __copy_to_user(&name->nodename,&utsname()->nodename,
 				__OLD_UTS_LEN);
 	err |= __put_user(0,name->nodename+__OLD_UTS_LEN);
-	err |= __copy_to_user(&name->release,&system_utsname.release,
+	err |= __copy_to_user(&name->release,&utsname()->release,
 				__OLD_UTS_LEN);
 	err |= __put_user(0,name->release+__OLD_UTS_LEN);
-	err |= __copy_to_user(&name->version,&system_utsname.version,
+	err |= __copy_to_user(&name->version,&utsname()->version,
 				__OLD_UTS_LEN);
 	err |= __put_user(0,name->version+__OLD_UTS_LEN);
-	 { 
-		 char *arch = "x86_64";
-		 if (personality(current->personality) == PER_LINUX32)
-			 arch = "i686";
+	{
+		char *arch = "x86_64";
+		if (personality(current->personality) == PER_LINUX32)
+			arch = "i686";
 		 
-		 err |= __copy_to_user(&name->machine,arch,strlen(arch)+1);
-	 }
-	
-	 up_read(&uts_sem);
-	 
-	 err = err ? -EFAULT : 0;
-	 
-	 return err;
+		err |= __copy_to_user(&name->machine, arch, strlen(arch)+1);
+	}
+
+	up_read(&uts_sem);
+
+	err = err ? -EFAULT : 0;
+
+	return err;
 }
 
 long sys32_uname(struct old_utsname __user * name)
@@ -822,7 +827,7 @@
 	if (!name)
 		return -EFAULT;
 	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	if (personality(current->personality) == PER_LINUX32) 
 		err |= copy_to_user(&name->machine, "i686", 5);
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 135ff25..6472e32 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -25,7 +25,6 @@
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
 #include <linux/module.h>
-#include <linux/ioport.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -46,11 +45,6 @@
 
 int disable_apic_timer __initdata;
 
-static struct resource lapic_resource = {
-	.name = "Local APIC",
-	.flags = IORESOURCE_MEM | IORESOURCE_BUSY,
-};
-
 /*
  * cpu_mask that denotes the CPUs that needs timer interrupt coming in as
  * IPIs in place of local APIC timers
@@ -591,40 +585,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_X86_IO_APIC
-static struct resource * __init ioapic_setup_resources(void)
-{
-#define IOAPIC_RESOURCE_NAME_SIZE 11
-	unsigned long n;
-	struct resource *res;
-	char *mem;
-	int i;
-
-	if (nr_ioapics <= 0)
-		return NULL;
-
-	n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
-	n *= nr_ioapics;
-
-	res = alloc_bootmem(n);
-
-	if (!res)
-		return NULL;
-
-	memset(res, 0, n);
-	mem = (void *)&res[nr_ioapics];
-
-	for (i = 0; i < nr_ioapics; i++) {
-		res[i].name = mem;
-		res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
-		mem += IOAPIC_RESOURCE_NAME_SIZE;
-	}
-
-	return res;
-}
-#endif
-
 void __init init_apic_mappings(void)
 {
 	unsigned long apic_phys;
@@ -644,11 +604,6 @@
 	apic_mapped = 1;
 	apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys);
 
-	/* Put local APIC into the resource map. */
-	lapic_resource.start = apic_phys;
-	lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
-	insert_resource(&iomem_resource, &lapic_resource);
-
 	/*
 	 * Fetch the APIC ID of the BSP in case we have a
 	 * default configuration (or the MP table is broken).
@@ -658,9 +613,7 @@
 	{
 		unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
 		int i;
-		struct resource *ioapic_res;
 
-		ioapic_res = ioapic_setup_resources();
 		for (i = 0; i < nr_ioapics; i++) {
 			if (smp_found_config) {
 				ioapic_phys = mp_ioapics[i].mpc_apicaddr;
@@ -672,13 +625,6 @@
 			apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n",
 					__fix_to_virt(idx), ioapic_phys);
 			idx++;
-
-			if (ioapic_res) {
-				ioapic_res->start = ioapic_phys;
-				ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
-				insert_resource(&iomem_resource, ioapic_res);
-				ioapic_res++;
-			}
 		}
 	}
 }
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 2802524..b8285cf 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -1023,7 +1023,7 @@
  * do_sys_execve asm fallback arguments:
  *	rdi: name, rsi: argv, rdx: envp, fake frame on the stack
  */
-ENTRY(execve)
+ENTRY(kernel_execve)
 	CFI_STARTPROC
 	FAKE_STACK_FRAME $0
 	SAVE_ALL	
@@ -1036,7 +1036,7 @@
 	UNFAKE_STACK_FRAME
 	ret
 	CFI_ENDPROC
-ENDPROC(execve)
+ENDPROC(kernel_execve)
 
 KPROBE_ENTRY(page_fault)
 	errorentry do_page_fault
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index 2dd51f3..0612a33 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -43,17 +43,10 @@
 	BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
 	BI(x,c) BI(x,d) BI(x,e) BI(x,f)
 
-#define BUILD_15_IRQS(x) \
-	BI(x,0) BI(x,1) BI(x,2) BI(x,3) \
-	BI(x,4) BI(x,5) BI(x,6) BI(x,7) \
-	BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
-	BI(x,c) BI(x,d) BI(x,e)
-
 /*
  * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
  * (these are usually mapped to vectors 0x20-0x2f)
  */
-BUILD_16_IRQS(0x0)
 
 /*
  * The IO-APIC gives us many more interrupt sources. Most of these 
@@ -65,17 +58,12 @@
  *
  * (these are usually mapped into the 0x30-0xff vector range)
  */
-		   BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
+				      BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
 BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
 BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
-BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
-
-#ifdef CONFIG_PCI_MSI
-	BUILD_15_IRQS(0xe)
-#endif
+BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf)
 
 #undef BUILD_16_IRQS
-#undef BUILD_15_IRQS
 #undef BI
 
 
@@ -88,29 +76,15 @@
 	IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
 	IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
 
-#define IRQLIST_15(x) \
-	IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
-	IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
-	IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
-	IRQ(x,c), IRQ(x,d), IRQ(x,e)
-
 void (*interrupt[NR_IRQS])(void) = {
-	IRQLIST_16(0x0),
-
-			 IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
+					  IRQLIST_16(0x2), IRQLIST_16(0x3),
 	IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
 	IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
-	IRQLIST_16(0xc), IRQLIST_16(0xd)
-
-#ifdef CONFIG_PCI_MSI
-	, IRQLIST_15(0xe)
-#endif
-
+	IRQLIST_16(0xc), IRQLIST_16(0xd), IRQLIST_16(0xe), IRQLIST_16(0xf)
 };
 
 #undef IRQ
 #undef IRQLIST_16
-#undef IRQLIST_14
 
 /*
  * This is the 'legacy' 8259A Programmable Interrupt Controller,
@@ -121,42 +95,15 @@
  * moves to arch independent land
  */
 
-DEFINE_SPINLOCK(i8259A_lock);
-
 static int i8259A_auto_eoi;
-
-static void end_8259A_irq (unsigned int irq)
-{
-	if (irq > 256) { 
-		char var;
-		printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, task_thread_info(current));
-
-		BUG(); 
-	}
-
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
-	    irq_desc[irq].action)
-		enable_8259A_irq(irq);
-}
-
-#define shutdown_8259A_irq	disable_8259A_irq
-
+DEFINE_SPINLOCK(i8259A_lock);
 static void mask_and_ack_8259A(unsigned int);
 
-static unsigned int startup_8259A_irq(unsigned int irq)
-{ 
-	enable_8259A_irq(irq);
-	return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type i8259A_irq_type = {
-	.typename = "XT-PIC",
-	.startup = startup_8259A_irq,
-	.shutdown = shutdown_8259A_irq,
-	.enable = enable_8259A_irq,
-	.disable = disable_8259A_irq,
-	.ack = mask_and_ack_8259A,
-	.end = end_8259A_irq,
+static struct irq_chip i8259A_chip = {
+	.name		= "XT-PIC",
+	.mask		= disable_8259A_irq,
+	.unmask		= enable_8259A_irq,
+	.mask_ack	= mask_and_ack_8259A,
 };
 
 /*
@@ -231,7 +178,7 @@
 {
 	disable_irq_nosync(irq);
 	io_apic_irqs &= ~(1<<irq);
-	irq_desc[irq].chip = &i8259A_irq_type;
+	set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
 	enable_irq(irq);
 }
 
@@ -367,9 +314,9 @@
 		 * in AEOI mode we just have to mask the interrupt
 		 * when acking.
 		 */
-		i8259A_irq_type.ack = disable_8259A_irq;
+		i8259A_chip.mask_ack = disable_8259A_irq;
 	else
-		i8259A_irq_type.ack = mask_and_ack_8259A;
+		i8259A_chip.mask_ack = mask_and_ack_8259A;
 
 	udelay(100);		/* wait for 8259A to initialize */
 
@@ -447,6 +394,26 @@
  */
 
 static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
+DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
+	[0 ... FIRST_EXTERNAL_VECTOR - 1] = -1,
+	[FIRST_EXTERNAL_VECTOR + 0] = 0,
+	[FIRST_EXTERNAL_VECTOR + 1] = 1,
+	[FIRST_EXTERNAL_VECTOR + 2] = 2,
+	[FIRST_EXTERNAL_VECTOR + 3] = 3,
+	[FIRST_EXTERNAL_VECTOR + 4] = 4,
+	[FIRST_EXTERNAL_VECTOR + 5] = 5,
+	[FIRST_EXTERNAL_VECTOR + 6] = 6,
+	[FIRST_EXTERNAL_VECTOR + 7] = 7,
+	[FIRST_EXTERNAL_VECTOR + 8] = 8,
+	[FIRST_EXTERNAL_VECTOR + 9] = 9,
+	[FIRST_EXTERNAL_VECTOR + 10] = 10,
+	[FIRST_EXTERNAL_VECTOR + 11] = 11,
+	[FIRST_EXTERNAL_VECTOR + 12] = 12,
+	[FIRST_EXTERNAL_VECTOR + 13] = 13,
+	[FIRST_EXTERNAL_VECTOR + 14] = 14,
+	[FIRST_EXTERNAL_VECTOR + 15] = 15,
+	[FIRST_EXTERNAL_VECTOR + 16 ... NR_VECTORS - 1] = -1
+};
 
 void __init init_ISA_irqs (void)
 {
@@ -464,12 +431,13 @@
 			/*
 			 * 16 old-style INTA-cycle interrupts:
 			 */
-			irq_desc[i].chip = &i8259A_irq_type;
+			set_irq_chip_and_handler(i, &i8259A_chip,
+						 handle_level_irq);
 		} else {
 			/*
 			 * 'high' PCI IRQs filled in on demand
 			 */
-			irq_desc[i].chip = &no_irq_type;
+			irq_desc[i].chip = &no_irq_chip;
 		}
 	}
 }
@@ -543,8 +511,6 @@
 	 */
 	for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
 		int vector = FIRST_EXTERNAL_VECTOR + i;
-		if (i >= NR_IRQS)
-			break;
 		if (vector != IA32_SYSCALL_VECTOR)
 			set_intr_gate(vector, interrupt[i]);
 	}
@@ -554,7 +520,7 @@
 	 * IRQ0 must be given a fixed assignment and initialized,
 	 * because it's used before the IO-APIC is set up.
 	 */
-	set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
+	__get_cpu_var(vector_irq)[FIRST_DEVICE_VECTOR] = 0;
 
 	/*
 	 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 0491019..91728d9 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -26,9 +26,12 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+#include <linux/pci.h>
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
 #include <linux/sysdev.h>
+#include <linux/msi.h>
+#include <linux/htirq.h>
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
@@ -41,6 +44,10 @@
 #include <asm/acpi.h>
 #include <asm/dma.h>
 #include <asm/nmi.h>
+#include <asm/msidef.h>
+#include <asm/hypertransport.h>
+
+static int assign_irq_vector(int irq, cpumask_t mask);
 
 #define __apicdebuginit  __init
 
@@ -81,14 +88,6 @@
 	short apic, pin, next;
 } irq_2_pin[PIN_MAP_SIZE];
 
-int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
-#ifdef CONFIG_PCI_MSI
-#define vector_to_irq(vector) 	\
-	(platform_legacy_irq(vector) ? vector : vector_irq[vector])
-#else
-#define vector_to_irq(vector)	(vector)
-#endif
-
 #define __DO_ACTION(R, ACTION, FINAL)					\
 									\
 {									\
@@ -139,11 +138,35 @@
 }
 
 #ifdef CONFIG_SMP
+static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)
+{
+	int apic, pin;
+	struct irq_pin_list *entry = irq_2_pin + irq;
+
+	BUG_ON(irq >= NR_IRQS);
+	for (;;) {
+		unsigned int reg;
+		apic = entry->apic;
+		pin = entry->pin;
+		if (pin == -1)
+			break;
+		io_apic_write(apic, 0x11 + pin*2, dest);
+		reg = io_apic_read(apic, 0x10 + pin*2);
+		reg &= ~0x000000ff;
+		reg |= vector;
+		io_apic_modify(apic, reg);
+		if (!entry->next)
+			break;
+		entry = irq_2_pin + entry->next;
+	}
+}
+
 static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
 {
 	unsigned long flags;
 	unsigned int dest;
 	cpumask_t tmp;
+	int vector;
 
 	cpus_and(tmp, mask, cpu_online_map);
 	if (cpus_empty(tmp))
@@ -151,7 +174,13 @@
 
 	cpus_and(mask, tmp, CPU_MASK_ALL);
 
-	dest = cpu_mask_to_apicid(mask);
+	vector = assign_irq_vector(irq, mask);
+	if (vector < 0)
+		return;
+
+	cpus_clear(tmp);
+	cpu_set(vector >> 8, tmp);
+	dest = cpu_mask_to_apicid(tmp);
 
 	/*
 	 * Only the high 8 bits are valid.
@@ -159,14 +188,12 @@
 	dest = SET_APIC_LOGICAL_ID(dest);
 
 	spin_lock_irqsave(&ioapic_lock, flags);
-	__DO_ACTION(1, = dest, )
-	set_irq_info(irq, mask);
+	__target_IO_APIC_irq(irq, dest, vector & 0xff);
+	set_native_irq_info(irq, mask);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 #endif
 
-static u8 gsi_2_irq[NR_IRQ_VECTORS] = { [0 ... NR_IRQ_VECTORS-1] = 0xFF };
-
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
  * shared ISA-space IRQs, so we have to support them. We are super
@@ -492,64 +519,6 @@
 	return MPBIOS_trigger(idx);
 }
 
-static int next_irq = 16;
-
-/*
- * gsi_irq_sharing -- Name overload!  "irq" can be either a legacy IRQ
- * in the range 0-15, a linux IRQ in the range 0-223, or a GSI number
- * from ACPI, which can reach 800 in large boxen.
- *
- * Compact the sparse GSI space into a sequential IRQ series and reuse
- * vectors if possible.
- */
-int gsi_irq_sharing(int gsi)
-{
-	int i, tries, vector;
-
-	BUG_ON(gsi >= NR_IRQ_VECTORS);
-
-	if (platform_legacy_irq(gsi))
-		return gsi;
-
-	if (gsi_2_irq[gsi] != 0xFF)
-		return (int)gsi_2_irq[gsi];
-
-	tries = NR_IRQS;
-  try_again:
-	vector = assign_irq_vector(gsi);
-
-	/*
-	 * Sharing vectors means sharing IRQs, so scan irq_vectors for previous
-	 * use of vector and if found, return that IRQ.  However, we never want
-	 * to share legacy IRQs, which usually have a different trigger mode
-	 * than PCI.
-	 */
-	for (i = 0; i < NR_IRQS; i++)
-		if (IO_APIC_VECTOR(i) == vector)
-			break;
-	if (platform_legacy_irq(i)) {
-		if (--tries >= 0) {
-			IO_APIC_VECTOR(i) = 0;
-			goto try_again;
-		}
-		panic("gsi_irq_sharing: didn't find an IRQ using vector 0x%02X for GSI %d", vector, gsi);
-	}
-	if (i < NR_IRQS) {
-		gsi_2_irq[gsi] = i;
-		printk(KERN_INFO "GSI %d sharing vector 0x%02X and IRQ %d\n",
-				gsi, vector, i);
-		return i;
-	}
-
-	i = next_irq++;
-	BUG_ON(i >= NR_IRQS);
-	gsi_2_irq[gsi] = i;
-	IO_APIC_VECTOR(i) = vector;
-	printk(KERN_INFO "GSI %d assigned vector 0x%02X and IRQ %d\n",
-			gsi, vector, i);
-	return i;
-}
-
 static int pin_2_irq(int idx, int apic, int pin)
 {
 	int irq, i;
@@ -571,7 +540,6 @@
 		while (i < apic)
 			irq += nr_ioapic_registers[i++];
 		irq += pin;
-		irq = gsi_irq_sharing(irq);
 	}
 	BUG_ON(irq >= NR_IRQS);
 	return irq;
@@ -595,46 +563,83 @@
 }
 
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
+unsigned int irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_EXTERNAL_VECTOR, 0 };
 
-int assign_irq_vector(int irq)
+static int __assign_irq_vector(int irq, cpumask_t mask)
 {
-	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
-	unsigned long flags;
-	int vector;
+	/*
+	 * NOTE! The local APIC isn't very good at handling
+	 * multiple interrupts at the same interrupt level.
+	 * As the interrupt level is determined by taking the
+	 * vector number and shifting that right by 4, we
+	 * want to spread these out a bit so that they don't
+	 * all fall in the same interrupt level.
+	 *
+	 * Also, we've got to be careful not to trash gate
+	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
+	 */
+	static struct {
+		int vector;
+		int offset;
+	} pos[NR_CPUS] = { [ 0 ... NR_CPUS - 1] = {FIRST_DEVICE_VECTOR, 0} };
+	int old_vector = -1;
+	int cpu;
 
-	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
+	BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
+
+	if (IO_APIC_VECTOR(irq) > 0)
+		old_vector = IO_APIC_VECTOR(irq);
+	if ((old_vector > 0) && cpu_isset(old_vector >> 8, mask)) {
+		return old_vector;
+	}
+
+	for_each_cpu_mask(cpu, mask) {
+		int vector, offset;
+		vector = pos[cpu].vector;
+		offset = pos[cpu].offset;
+next:
+		vector += 8;
+		if (vector >= FIRST_SYSTEM_VECTOR) {
+			/* If we run out of vectors on large boxen, must share them. */
+			offset = (offset + 1) % 8;
+			vector = FIRST_DEVICE_VECTOR + offset;
+		}
+		if (unlikely(pos[cpu].vector == vector))
+			continue;
+		if (vector == IA32_SYSCALL_VECTOR)
+			goto next;
+		if (per_cpu(vector_irq, cpu)[vector] != -1)
+			goto next;
+		/* Found one! */
+		pos[cpu].vector = vector;
+		pos[cpu].offset = offset;
+		if (old_vector >= 0) {
+			int old_cpu = old_vector >> 8;
+			old_vector &= 0xff;
+			per_cpu(vector_irq, old_cpu)[old_vector] = -1;
+		}
+		per_cpu(vector_irq, cpu)[vector] = irq;
+		vector |= cpu << 8;
+		IO_APIC_VECTOR(irq) = vector;
+		return vector;
+	}
+	return -ENOSPC;
+}
+
+static int assign_irq_vector(int irq, cpumask_t mask)
+{
+	int vector;
+	unsigned long flags;
 
 	spin_lock_irqsave(&vector_lock, flags);
-
-	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
-		spin_unlock_irqrestore(&vector_lock, flags);
-		return IO_APIC_VECTOR(irq);
-	}
-next:
-	current_vector += 8;
-	if (current_vector == IA32_SYSCALL_VECTOR)
-		goto next;
-
-	if (current_vector >= FIRST_SYSTEM_VECTOR) {
-		/* If we run out of vectors on large boxen, must share them. */
-		offset = (offset + 1) % 8;
-		current_vector = FIRST_DEVICE_VECTOR + offset;
-	}
-
-	vector = current_vector;
-	vector_irq[vector] = irq;
-	if (irq != AUTO_ASSIGN)
-		IO_APIC_VECTOR(irq) = vector;
-
+	vector = __assign_irq_vector(irq, mask);
 	spin_unlock_irqrestore(&vector_lock, flags);
-
 	return vector;
 }
 
 extern void (*interrupt[NR_IRQS])(void);
-static struct hw_interrupt_type ioapic_level_type;
-static struct hw_interrupt_type ioapic_edge_type;
+
+static struct irq_chip ioapic_chip;
 
 #define IOAPIC_AUTO	-1
 #define IOAPIC_EDGE	0
@@ -642,16 +647,13 @@
 
 static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
 {
-	unsigned idx;
-
-	idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;
-
 	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
 			trigger == IOAPIC_LEVEL)
-		irq_desc[idx].chip = &ioapic_level_type;
+		set_irq_chip_and_handler(irq, &ioapic_chip,
+					 handle_fasteoi_irq);
 	else
-		irq_desc[idx].chip = &ioapic_edge_type;
-	set_intr_gate(vector, interrupt[idx]);
+		set_irq_chip_and_handler(irq, &ioapic_chip,
+					 handle_edge_irq);
 }
 
 static void __init setup_IO_APIC_irqs(void)
@@ -701,8 +703,15 @@
 			continue;
 
 		if (IO_APIC_IRQ(irq)) {
-			vector = assign_irq_vector(irq);
-			entry.vector = vector;
+			cpumask_t mask;
+			vector = assign_irq_vector(irq, TARGET_CPUS);
+			if (vector < 0)
+				continue;
+
+			cpus_clear(mask);
+			cpu_set(vector >> 8, mask);
+			entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
+			entry.vector = vector & 0xff;
 
 			ioapic_register_intr(irq, vector, IOAPIC_AUTO);
 			if (!apic && (irq < 16))
@@ -752,7 +761,7 @@
 	 * The timer IRQ doesn't have to know that behind the
 	 * scene we have a 8259A-master in AEOI mode ...
 	 */
-	irq_desc[0].chip = &ioapic_edge_type;
+	set_irq_chip_and_handler(0, &ioapic_chip, handle_edge_irq);
 
 	/*
 	 * Add it to the IO-APIC irq-routing table:
@@ -868,17 +877,12 @@
 		);
 	}
 	}
-	if (use_pci_vector())
-		printk(KERN_INFO "Using vector-based indexing\n");
 	printk(KERN_DEBUG "IRQ to pin mappings:\n");
 	for (i = 0; i < NR_IRQS; i++) {
 		struct irq_pin_list *entry = irq_2_pin + i;
 		if (entry->pin < 0)
 			continue;
- 		if (use_pci_vector() && !platform_legacy_irq(i))
-			printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
-		else
-			printk(KERN_DEBUG "IRQ%d ", i);
+		printk(KERN_DEBUG "IRQ%d ", i);
 		for (;;) {
 			printk("-> %d:%d", entry->apic, entry->pin);
 			if (!entry->next)
@@ -1185,7 +1189,7 @@
  * an edge even if it isn't on the 8259A...
  */
 
-static unsigned int startup_edge_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(unsigned int irq)
 {
 	int was_pending = 0;
 	unsigned long flags;
@@ -1202,107 +1206,16 @@
 	return was_pending;
 }
 
-/*
- * Once we have recorded IRQ_PENDING already, we can mask the
- * interrupt for real. This prevents IRQ storms from unhandled
- * devices.
- */
-static void ack_edge_ioapic_irq(unsigned int irq)
+static int ioapic_retrigger_irq(unsigned int irq)
 {
-	move_irq(irq);
-	if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
-					== (IRQ_PENDING | IRQ_DISABLED))
-		mask_IO_APIC_irq(irq);
-	ack_APIC_irq();
-}
+	cpumask_t mask;
+	unsigned vector;
 
-/*
- * Level triggered interrupts can just be masked,
- * and shutting down and starting up the interrupt
- * is the same as enabling and disabling them -- except
- * with a startup need to return a "was pending" value.
- *
- * Level triggered interrupts are special because we
- * do not touch any IO-APIC register while handling
- * them. We ack the APIC in the end-IRQ handler, not
- * in the start-IRQ-handler. Protection against reentrance
- * from the same interrupt is still provided, both by the
- * generic IRQ layer and by the fact that an unacked local
- * APIC does not accept IRQs.
- */
-static unsigned int startup_level_ioapic_irq (unsigned int irq)
-{
-	unmask_IO_APIC_irq(irq);
+	vector = irq_vector[irq];
+	cpus_clear(mask);
+	cpu_set(vector >> 8, mask);
 
-	return 0; /* don't check for pending */
-}
-
-static void end_level_ioapic_irq (unsigned int irq)
-{
-	move_irq(irq);
-	ack_APIC_irq();
-}
-
-#ifdef CONFIG_PCI_MSI
-static unsigned int startup_edge_ioapic_vector(unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	return startup_edge_ioapic_irq(irq);
-}
-
-static void ack_edge_ioapic_vector(unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	move_native_irq(vector);
-	ack_edge_ioapic_irq(irq);
-}
-
-static unsigned int startup_level_ioapic_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	return startup_level_ioapic_irq (irq);
-}
-
-static void end_level_ioapic_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	move_native_irq(vector);
-	end_level_ioapic_irq(irq);
-}
-
-static void mask_IO_APIC_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	mask_IO_APIC_irq(irq);
-}
-
-static void unmask_IO_APIC_vector (unsigned int vector)
-{
-	int irq = vector_to_irq(vector);
-
-	unmask_IO_APIC_irq(irq);
-}
-
-#ifdef CONFIG_SMP
-static void set_ioapic_affinity_vector (unsigned int vector,
-					cpumask_t cpu_mask)
-{
-	int irq = vector_to_irq(vector);
-
-	set_native_irq_info(vector, cpu_mask);
-	set_ioapic_affinity_irq(irq, cpu_mask);
-}
-#endif // CONFIG_SMP
-#endif // CONFIG_PCI_MSI
-
-static int ioapic_retrigger(unsigned int irq)
-{
-	send_IPI_self(IO_APIC_VECTOR(irq));
+	send_IPI_mask(mask, vector & 0xff);
 
 	return 1;
 }
@@ -1316,32 +1229,47 @@
  * races.
  */
 
-static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
-	.typename = "IO-APIC-edge",
-	.startup 	= startup_edge_ioapic,
-	.shutdown 	= shutdown_edge_ioapic,
-	.enable 	= enable_edge_ioapic,
-	.disable 	= disable_edge_ioapic,
-	.ack 		= ack_edge_ioapic,
-	.end 		= end_edge_ioapic,
-#ifdef CONFIG_SMP
-	.set_affinity = set_ioapic_affinity,
-#endif
-	.retrigger	= ioapic_retrigger,
-};
+static void ack_apic_edge(unsigned int irq)
+{
+	move_native_irq(irq);
+	ack_APIC_irq();
+}
 
-static struct hw_interrupt_type ioapic_level_type __read_mostly = {
-	.typename = "IO-APIC-level",
-	.startup 	= startup_level_ioapic,
-	.shutdown 	= shutdown_level_ioapic,
-	.enable 	= enable_level_ioapic,
-	.disable 	= disable_level_ioapic,
-	.ack 		= mask_and_ack_level_ioapic,
-	.end 		= end_level_ioapic,
-#ifdef CONFIG_SMP
-	.set_affinity = set_ioapic_affinity,
+static void ack_apic_level(unsigned int irq)
+{
+	int do_unmask_irq = 0;
+
+#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
+	/* If we are moving the irq we need to mask it */
+	if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+		do_unmask_irq = 1;
+		mask_IO_APIC_irq(irq);
+	}
 #endif
-	.retrigger	= ioapic_retrigger,
+
+	/*
+	 * We must acknowledge the irq before we move it or the acknowledge will
+	 * not propogate properly.
+	 */
+	ack_APIC_irq();
+
+	/* Now we can move and renable the irq */
+	move_masked_irq(irq);
+	if (unlikely(do_unmask_irq))
+		unmask_IO_APIC_irq(irq);
+}
+
+static struct irq_chip ioapic_chip __read_mostly = {
+	.name 		= "IO-APIC",
+	.startup 	= startup_ioapic_irq,
+	.mask	 	= mask_IO_APIC_irq,
+	.unmask	 	= unmask_IO_APIC_irq,
+	.ack 		= ack_apic_edge,
+	.eoi 		= ack_apic_level,
+#ifdef CONFIG_SMP
+	.set_affinity 	= set_ioapic_affinity_irq,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -1361,11 +1289,6 @@
 	 */
 	for (irq = 0; irq < NR_IRQS ; irq++) {
 		int tmp = irq;
-		if (use_pci_vector()) {
-			if (!platform_legacy_irq(tmp))
-				if ((tmp = vector_to_irq(tmp)) == -1)
-					continue;
-		}
 		if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
 			/*
 			 * Hmm.. We don't have an entry for this,
@@ -1376,7 +1299,7 @@
 				make_8259A_irq(irq);
 			else
 				/* Strange. Oh, well.. */
-				irq_desc[irq].chip = &no_irq_type;
+				irq_desc[irq].chip = &no_irq_chip;
 		}
 	}
 }
@@ -1495,8 +1418,6 @@
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-int timer_uses_ioapic_pin_0;
-
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
@@ -1514,8 +1435,7 @@
 	 * get/set the timer IRQ vector:
 	 */
 	disable_8259A_irq(0);
-	vector = assign_irq_vector(0);
-	set_intr_gate(vector, interrupt[0]);
+	vector = assign_irq_vector(0, TARGET_CPUS);
 
 	/*
 	 * Subtle, code in do_timer_interrupt() expects an AEOI
@@ -1534,9 +1454,6 @@
 	pin2  = ioapic_i8259.pin;
 	apic2 = ioapic_i8259.apic;
 
-	if (pin1 == 0)
-		timer_uses_ioapic_pin_0 = 1;
-
 	apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
 		vector, apic1, pin1, apic2, pin2);
 
@@ -1740,6 +1657,253 @@
 
 device_initcall(ioapic_init_sysfs);
 
+/*
+ * Dynamic irq allocate and deallocation
+ */
+int create_irq(void)
+{
+	/* Allocate an unused irq */
+	int irq;
+	int new;
+	int vector = 0;
+	unsigned long flags;
+
+	irq = -ENOSPC;
+	spin_lock_irqsave(&vector_lock, flags);
+	for (new = (NR_IRQS - 1); new >= 0; new--) {
+		if (platform_legacy_irq(new))
+			continue;
+		if (irq_vector[new] != 0)
+			continue;
+		vector = __assign_irq_vector(new, TARGET_CPUS);
+		if (likely(vector > 0))
+			irq = new;
+		break;
+	}
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	if (irq >= 0) {
+		dynamic_irq_init(irq);
+	}
+	return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	dynamic_irq_cleanup(irq);
+
+	spin_lock_irqsave(&vector_lock, flags);
+	irq_vector[irq] = 0;
+	spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+/*
+ * MSI mesage composition
+ */
+#ifdef CONFIG_PCI_MSI
+static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+{
+	int vector;
+	unsigned dest;
+
+	vector = assign_irq_vector(irq, TARGET_CPUS);
+	if (vector >= 0) {
+		cpumask_t tmp;
+
+		cpus_clear(tmp);
+		cpu_set(vector >> 8, tmp);
+		dest = cpu_mask_to_apicid(tmp);
+
+		msg->address_hi = MSI_ADDR_BASE_HI;
+		msg->address_lo =
+			MSI_ADDR_BASE_LO |
+			((INT_DEST_MODE == 0) ?
+				MSI_ADDR_DEST_MODE_PHYSICAL:
+				MSI_ADDR_DEST_MODE_LOGICAL) |
+			((INT_DELIVERY_MODE != dest_LowestPrio) ?
+				MSI_ADDR_REDIRECTION_CPU:
+				MSI_ADDR_REDIRECTION_LOWPRI) |
+			MSI_ADDR_DEST_ID(dest);
+
+		msg->data =
+			MSI_DATA_TRIGGER_EDGE |
+			MSI_DATA_LEVEL_ASSERT |
+			((INT_DELIVERY_MODE != dest_LowestPrio) ?
+				MSI_DATA_DELIVERY_FIXED:
+				MSI_DATA_DELIVERY_LOWPRI) |
+			MSI_DATA_VECTOR(vector);
+	}
+	return vector;
+}
+
+#ifdef CONFIG_SMP
+static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+	struct msi_msg msg;
+	unsigned int dest;
+	cpumask_t tmp;
+	int vector;
+
+	cpus_and(tmp, mask, cpu_online_map);
+	if (cpus_empty(tmp))
+		tmp = TARGET_CPUS;
+
+	cpus_and(mask, tmp, CPU_MASK_ALL);
+
+	vector = assign_irq_vector(irq, mask);
+	if (vector < 0)
+		return;
+
+	cpus_clear(tmp);
+	cpu_set(vector >> 8, tmp);
+	dest = cpu_mask_to_apicid(tmp);
+
+	read_msi_msg(irq, &msg);
+
+	msg.data &= ~MSI_DATA_VECTOR_MASK;
+	msg.data |= MSI_DATA_VECTOR(vector);
+	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+	write_msi_msg(irq, &msg);
+	set_native_irq_info(irq, mask);
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
+ * which implement the MSI or MSI-X Capability Structure.
+ */
+static struct irq_chip msi_chip = {
+	.name		= "PCI-MSI",
+	.unmask		= unmask_msi_irq,
+	.mask		= mask_msi_irq,
+	.ack		= ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_msi_irq_affinity,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev)
+{
+	struct msi_msg msg;
+	int ret;
+	ret = msi_compose_msg(dev, irq, &msg);
+	if (ret < 0)
+		return ret;
+
+	write_msi_msg(irq, &msg);
+
+	set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq);
+
+	return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	return;
+}
+
+#endif /* CONFIG_PCI_MSI */
+
+/*
+ * Hypertransport interrupt support
+ */
+#ifdef CONFIG_HT_IRQ
+
+#ifdef CONFIG_SMP
+
+static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
+{
+	u32 low, high;
+	low  = read_ht_irq_low(irq);
+	high = read_ht_irq_high(irq);
+
+	low  &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
+	high &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
+
+	low  |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
+	high |= HT_IRQ_HIGH_DEST_ID(dest);
+
+	write_ht_irq_low(irq, low);
+	write_ht_irq_high(irq, high);
+}
+
+static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+	unsigned int dest;
+	cpumask_t tmp;
+	int vector;
+
+	cpus_and(tmp, mask, cpu_online_map);
+	if (cpus_empty(tmp))
+		tmp = TARGET_CPUS;
+
+	cpus_and(mask, tmp, CPU_MASK_ALL);
+
+	vector = assign_irq_vector(irq, mask);
+	if (vector < 0)
+		return;
+
+	cpus_clear(tmp);
+	cpu_set(vector >> 8, tmp);
+	dest = cpu_mask_to_apicid(tmp);
+
+	target_ht_irq(irq, dest, vector & 0xff);
+	set_native_irq_info(irq, mask);
+}
+#endif
+
+static struct hw_interrupt_type ht_irq_chip = {
+	.name		= "PCI-HT",
+	.mask		= mask_ht_irq,
+	.unmask		= unmask_ht_irq,
+	.ack		= ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_ht_irq_affinity,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
+{
+	int vector;
+
+	vector = assign_irq_vector(irq, TARGET_CPUS);
+	if (vector >= 0) {
+		u32 low, high;
+		unsigned dest;
+		cpumask_t tmp;
+
+		cpus_clear(tmp);
+		cpu_set(vector >> 8, tmp);
+		dest = cpu_mask_to_apicid(tmp);
+
+		high = 	HT_IRQ_HIGH_DEST_ID(dest);
+
+		low =	HT_IRQ_LOW_BASE |
+			HT_IRQ_LOW_DEST_ID(dest) |
+			HT_IRQ_LOW_VECTOR(vector) |
+			((INT_DEST_MODE == 0) ?
+				HT_IRQ_LOW_DM_PHYSICAL :
+				HT_IRQ_LOW_DM_LOGICAL) |
+			HT_IRQ_LOW_RQEOI_EDGE |
+			((INT_DELIVERY_MODE != dest_LowestPrio) ?
+				HT_IRQ_LOW_MT_FIXED :
+				HT_IRQ_LOW_MT_ARBITRATED);
+
+		write_ht_irq_low(irq, low);
+		write_ht_irq_high(irq, high);
+
+		set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq);
+	}
+	return vector;
+}
+#endif /* CONFIG_HT_IRQ */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- */
@@ -1765,6 +1929,8 @@
 {
 	struct IO_APIC_route_entry entry;
 	unsigned long flags;
+	int vector;
+	cpumask_t mask;
 
 	if (!IO_APIC_IRQ(irq)) {
 		apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
@@ -1773,6 +1939,20 @@
 	}
 
 	/*
+	 * IRQs < 16 are already in the irq_2_pin[] map
+	 */
+	if (irq >= 16)
+		add_pin_to_irq(irq, ioapic, pin);
+
+
+	vector = assign_irq_vector(irq, TARGET_CPUS);
+	if (vector < 0)
+		return vector;
+
+	cpus_clear(mask);
+	cpu_set(vector >> 8, mask);
+
+	/*
 	 * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
 	 * Note that we mask (disable) IRQs now -- these get enabled when the
 	 * corresponding device driver registers for this IRQ.
@@ -1782,19 +1962,11 @@
 
 	entry.delivery_mode = INT_DELIVERY_MODE;
 	entry.dest_mode = INT_DEST_MODE;
-	entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
+	entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
 	entry.trigger = triggering;
 	entry.polarity = polarity;
 	entry.mask = 1;					 /* Disabled (masked) */
-
-	irq = gsi_irq_sharing(irq);
-	/*
-	 * IRQs < 16 are already in the irq_2_pin[] map
-	 */
-	if (irq >= 16)
-		add_pin_to_irq(irq, ioapic, pin);
-
-	entry.vector = assign_irq_vector(irq);
+	entry.vector = vector & 0xff;
 
 	apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
 		"IRQ %d Mode:%i Active:%i)\n", ioapic, 
@@ -1809,7 +1981,7 @@
 	ioapic_write_entry(ioapic, pin, entry);
 
 	spin_lock_irqsave(&ioapic_lock, flags);
-	set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
+	set_native_irq_info(irq, TARGET_CPUS);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return 0;
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
index b3677e6..506f27c 100644
--- a/arch/x86_64/kernel/irq.c
+++ b/arch/x86_64/kernel/irq.c
@@ -74,7 +74,8 @@
 		for_each_online_cpu(j)
 			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
-		seq_printf(p, " %14s", irq_desc[i].chip->typename);
+		seq_printf(p, " %8s", irq_desc[i].chip->name);
+		seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
 
 		seq_printf(p, "  %s", action->name);
 		for (action=action->next; action; action = action->next)
@@ -104,7 +105,12 @@
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
 {	
 	/* high bit used in ret_from_ code  */
-	unsigned irq = ~regs->orig_rax;
+	unsigned vector = ~regs->orig_rax;
+	unsigned irq;
+
+	exit_idle();
+	irq_enter();
+	irq = __get_cpu_var(vector_irq)[vector];
 
 	if (unlikely(irq >= NR_IRQS)) {
 		printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
@@ -112,12 +118,10 @@
 		BUG();
 	}
 
-	exit_idle();
-	irq_enter();
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 	stack_overflow_check(regs);
 #endif
-	__do_IRQ(irq, regs);
+	generic_handle_irq(irq, regs);
 	irq_exit();
 
 	return 1;
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index ffc73ac..ac24156 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -270,20 +270,19 @@
 				      struct pt_regs *regs)
 {
 	unsigned long *sara = (unsigned long *)regs->rsp;
-        struct kretprobe_instance *ri;
+	struct kretprobe_instance *ri;
 
-        if ((ri = get_free_rp_inst(rp)) != NULL) {
-                ri->rp = rp;
-                ri->task = current;
+	if ((ri = get_free_rp_inst(rp)) != NULL) {
+		ri->rp = rp;
+		ri->task = current;
 		ri->ret_addr = (kprobe_opcode_t *) *sara;
 
 		/* Replace the return addr with trampoline addr */
 		*sara = (unsigned long) &kretprobe_trampoline;
-
-                add_rp_inst(ri);
-        } else {
-                rp->nmissed++;
-        }
+		add_rp_inst(ri);
+	} else {
+		rp->nmissed++;
+	}
 }
 
 int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -405,14 +404,15 @@
  */
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
-        struct kretprobe_instance *ri = NULL;
-        struct hlist_head *head;
-        struct hlist_node *node, *tmp;
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head, empty_rp;
+	struct hlist_node *node, *tmp;
 	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+	INIT_HLIST_HEAD(&empty_rp);
 	spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
+	head = kretprobe_inst_table_head(current);
 
 	/*
 	 * It is possible to have multiple instances associated with a given
@@ -423,20 +423,20 @@
 	 * We can handle this because:
 	 *     - instances are always inserted at the head of the list
 	 *     - when multiple return probes are registered for the same
-         *       function, the first instance's ret_addr will point to the
+	 *       function, the first instance's ret_addr will point to the
 	 *       real return address, and all the rest will point to
 	 *       kretprobe_trampoline
 	 */
 	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
+		if (ri->task != current)
 			/* another task is sharing our hash bucket */
-                        continue;
+			continue;
 
 		if (ri->rp && ri->rp->handler)
 			ri->rp->handler(ri, regs);
 
 		orig_ret_address = (unsigned long)ri->ret_addr;
-		recycle_rp_inst(ri);
+		recycle_rp_inst(ri, &empty_rp);
 
 		if (orig_ret_address != trampoline_address)
 			/*
@@ -454,12 +454,16 @@
 	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	preempt_enable_no_resched();
 
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we don't want the post_handler
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
+	/*
+	 * 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;
+	 */
+	return 1;
 }
 
 /*
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index b8d53df..b147ab1 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -790,20 +790,11 @@
 	}
 }
 
-#define MAX_GSI_NUM	4096
-
 int mp_register_gsi(u32 gsi, int triggering, int polarity)
 {
 	int ioapic = -1;
 	int ioapic_pin = 0;
 	int idx, bit = 0;
-	static int pci_irq = 16;
-	/*
-	 * Mapping between Global System Interrupts, which
-	 * represent all possible interrupts, to the IRQs
-	 * assigned to actual devices.
-	 */
-	static int gsi_to_irq[MAX_GSI_NUM];
 
 	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
 		return gsi;
@@ -836,42 +827,11 @@
 	if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
 		Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
 			mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-		return gsi_to_irq[gsi];
+		return gsi;
 	}
 
 	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
-	if (triggering == ACPI_LEVEL_SENSITIVE) {
-		/*
-		 * For PCI devices assign IRQs in order, avoiding gaps
-		 * due to unused I/O APIC pins.
-		 */
-		int irq = gsi;
-		if (gsi < MAX_GSI_NUM) {
-			/*
-			 * Retain the VIA chipset work-around (gsi > 15), but
-			 * avoid a problem where the 8254 timer (IRQ0) is setup
-			 * via an override (so it's not on pin 0 of the ioapic),
-			 * and at the same time, the pin 0 interrupt is a PCI
-			 * type.  The gsi > 15 test could cause these two pins
-			 * to be shared as IRQ0, and they are not shareable.
-			 * So test for this condition, and if necessary, avoid
-			 * the pin collision.
-			 */
-			if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
-				gsi = pci_irq++;
-			/*
-			 * Don't assign IRQ used by ACPI SCI
-			 */
-			if (gsi == acpi_fadt.sci_int)
-				gsi = pci_irq++;
-			gsi_to_irq[irq] = gsi;
-		} else {
-			printk(KERN_ERR "GSI %u is too high\n", gsi);
-			return gsi;
-		}
-	}
-
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
 		triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
 		polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 458006a..de10cb8 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -294,9 +294,9 @@
 	print_modules();
 	printk("Pid: %d, comm: %.20s %s %s %.*s\n",
 		current->pid, current->comm, print_tainted(),
-		system_utsname.release,
-		(int)strcspn(system_utsname.version, " "),
-		system_utsname.version);
+		init_utsname()->release,
+		(int)strcspn(init_utsname()->version, " "),
+		init_utsname()->version);
 	printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
 	printk_address(regs->rip); 
 	printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 6449ea8..76bf7c2 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -148,7 +148,7 @@
 {
 	int err;
 	down_read(&uts_sem);
-	err = copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, utsname(), sizeof (*name));
 	up_read(&uts_sem);
 	if (personality(current->personality) == PER_LINUX32) 
 		err |= copy_to_user(&name->machine, "i686", 5); 		
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 848f173..c1e69a1 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -206,7 +206,7 @@
 
 endmenu
 
-menu "Exectuable file formats"
+menu "Executable file formats"
 
 # only elf supported
 config KCORE_ELF
@@ -241,7 +241,7 @@
 	bool "Embed root filesystem ramdisk into the kernel"
 
 config EMBEDDED_RAMDISK_IMAGE
-	string "Filename of gziped ramdisk image"
+	string "Filename of gzipped ramdisk image"
 	depends on EMBEDDED_RAMDISK
 	default "ramdisk.gz"
 	help
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c
index d1683cf..2ea1755 100644
--- a/arch/xtensa/kernel/module.c
+++ b/arch/xtensa/kernel/module.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/kernel/platform.c
+ * arch/xtensa/kernel/module.c
  *
  * Module support.
  *
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 1ff8226..6648fa9 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/pci-dma.c
+ * arch/xtensa/kernel/pci-dma.c
  *
  * DMA coherent memory allocation.
  *
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 8709f82..45571cc 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/pcibios.c
+ * arch/xtensa/kernel/pci.c
  *
  * PCI bios-type initialisation for PCI machines
  *
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 82684d0..c99ab72 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/setup.c
+ * arch/xtensa/kernel/setup.c
  *
  * 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
diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c
index 4688ba2..f49cb23 100644
--- a/arch/xtensa/kernel/syscalls.c
+++ b/arch/xtensa/kernel/syscalls.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/kernel/syscall.c
+ * arch/xtensa/kernel/syscalls.c
  *
  * 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
@@ -128,7 +128,7 @@
 
 int sys_uname(struct old_utsname * name)
 {
-	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+	if (name && !copy_to_user(name, utsname(), sizeof (*name)))
 		return 0;
 	return -EFAULT;
 }
@@ -266,3 +266,23 @@
 	regs->areg[2] = res;
 	do_syscall_trace();
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	asm volatile (
+		"  mov   a5, %2 \n"
+		"  mov   a4, %4 \n"
+		"  mov   a3, %3 \n"
+		"  movi  a2, %1 \n"
+		"  syscall      \n"
+		"  mov   %0, a2 \n"
+		: "=a" (__res)
+		: "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp)
+		: "a2", "a3", "a4", "a5");
+	return __res;
+}
diff --git a/arch/xtensa/lib/pci-auto.c b/arch/xtensa/lib/pci-auto.c
index 90c790f..a71733a 100644
--- a/arch/xtensa/lib/pci-auto.c
+++ b/arch/xtensa/lib/pci-auto.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/kernel/pci-auto.c
+ * arch/xtensa/lib/pci-auto.c
  *
  * PCI autoconfiguration library
  *
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S
index 265db26..4641ef5 100644
--- a/arch/xtensa/lib/usercopy.S
+++ b/arch/xtensa/lib/usercopy.S
@@ -5,10 +5,10 @@
  *
  *  DO NOT COMBINE this function with <arch/xtensa/lib/hal/memcopy.S>.
  *  It needs to remain separate and distinct.  The hal files are part
- *  of the the Xtensa link-time HAL, and those files may differ per
+ *  of the Xtensa link-time HAL, and those files may differ per
  *  processor configuration.  Patching the kernel for another
  *  processor configuration includes replacing the hal files, and we
- *  could loose the special functionality for accessing user-space
+ *  could lose the special functionality for accessing user-space
  *  memory during such a patch.  We sacrifice a little code space here
  *  in favor to simplify code maintenance.
  *
diff --git a/arch/xtensa/mm/pgtable.c b/arch/xtensa/mm/pgtable.c
index 7d28914..6979927 100644
--- a/arch/xtensa/mm/pgtable.c
+++ b/arch/xtensa/mm/pgtable.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/mm/fault.c
+ * arch/xtensa/mm/pgtable.c
  *
  * 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
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c
index d3bd3bf..0fefb866 100644
--- a/arch/xtensa/mm/tlb.c
+++ b/arch/xtensa/mm/tlb.c
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/mm/mmu.c
+ * arch/xtensa/mm/tlb.c
  *
  * Logic that manipulates the Xtensa MMU.  Derived from MIPS.
  *
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c
index 22d3c57..5c947ca 100644
--- a/arch/xtensa/platform-iss/console.c
+++ b/arch/xtensa/platform-iss/console.c
@@ -191,7 +191,7 @@
 }
 
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
diff --git a/block/ioctl.c b/block/ioctl.c
index 309760b..58aab63 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -199,8 +199,8 @@
 	return -ENOIOCTLCMD;
 }
 
-static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
-		struct gendisk *disk, unsigned cmd, unsigned long arg)
+int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+			struct gendisk *disk, unsigned cmd, unsigned long arg)
 {
 	int ret;
 	if (disk->fops->unlocked_ioctl)
@@ -215,6 +215,7 @@
 
 	return -ENOTTY;
 }
+EXPORT_SYMBOL_GPL(blkdev_driver_ioctl);
 
 int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
 			unsigned long arg)
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index 3dd6b7b..1bace29 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/drivers/block/mfmhd.c
+ * linux/drivers/acorn/block/mfmhd.c
  *
  * Copyright (C) 1995, 1996 Russell King, Dave Alan Gilbert (gilbertd@cs.man.ac.uk)
  *
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 56c5ba8..0f9d4be 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -253,7 +253,7 @@
 	depends on !STANDALONE
 	default n 
 	help
-	  Thist option is to load a custom ACPI DSDT
+	  This option is to load a custom ACPI DSDT
 	  If you don't know what that is, say N.
 
 config ACPI_CUSTOM_DSDT_FILE
@@ -310,7 +310,7 @@
 	  The Power Management Timer is available on all ACPI-capable,
 	  in most cases even if ACPI is unusable or blacklisted.
 
-	  This timing source is not affected by powermanagement features
+	  This timing source is not affected by power management features
 	  like aggressive processor idling, throttling, frequency and/or
 	  voltage scaling, unlike the commonly used Time Stamp Counter
 	  (TSC) timing source.
@@ -345,7 +345,7 @@
 	  Enabling this driver assumes that your platform hardware
 	  and firmware have support for hot-plugging physical memory. If
 	  your system does not support physically adding or ripping out 
-	  memory DIMMs at some platfrom defined granularity (individually 
+	  memory DIMMs at some platform defined granularity (individually 
 	  or as a bank) at runtime, then you need not enable this driver.
 
 	  If one selects "m," this driver can be loaded using the following
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 1aabc81..54e1f38 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -299,76 +299,46 @@
 
 static const struct pci_device_id ahci_pci_tbl[] = {
 	/* Intel */
-	{ PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH6 */
-	{ PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH6M */
-	{ PCI_VENDOR_ID_INTEL, 0x27c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH7 */
-	{ PCI_VENDOR_ID_INTEL, 0x27c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH7M */
-	{ PCI_VENDOR_ID_INTEL, 0x27c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH7R */
-	{ PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ULi M5288 */
-	{ PCI_VENDOR_ID_INTEL, 0x2681, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ESB2 */
-	{ PCI_VENDOR_ID_INTEL, 0x2682, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ESB2 */
-	{ PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ESB2 */
-	{ PCI_VENDOR_ID_INTEL, 0x27c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH7-M DH */
-	{ PCI_VENDOR_ID_INTEL, 0x2821, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH8 */
-	{ PCI_VENDOR_ID_INTEL, 0x2822, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH8 */
-	{ PCI_VENDOR_ID_INTEL, 0x2824, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH8 */
-	{ PCI_VENDOR_ID_INTEL, 0x2829, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH8M */
-	{ PCI_VENDOR_ID_INTEL, 0x282a, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ICH8M */
+	{ PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */
+	{ PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */
+	{ PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
+	{ PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */
+	{ PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */
+	{ PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */
+	{ PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */
+	{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
+	{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
+	{ PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
+	{ PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
+	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
+	{ PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
+	{ PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
+	{ PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
 
 	/* JMicron */
-	{ 0x197b, 0x2360, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* JMicron JMB360 */
-	{ 0x197b, 0x2361, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* JMicron JMB361 */
-	{ 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* JMicron JMB363 */
-	{ 0x197b, 0x2365, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* JMicron JMB365 */
-	{ 0x197b, 0x2366, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* JMicron JMB366 */
+	{ PCI_VDEVICE(JMICRON, 0x2360), board_ahci }, /* JMicron JMB360 */
+	{ PCI_VDEVICE(JMICRON, 0x2361), board_ahci }, /* JMicron JMB361 */
+	{ PCI_VDEVICE(JMICRON, 0x2363), board_ahci }, /* JMicron JMB363 */
+	{ PCI_VDEVICE(JMICRON, 0x2365), board_ahci }, /* JMicron JMB365 */
+	{ PCI_VDEVICE(JMICRON, 0x2366), board_ahci }, /* JMicron JMB366 */
 
 	/* ATI */
-	{ PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ATI SB600 non-raid */
-	{ PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* ATI SB600 raid */
+	{ PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
+	{ PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
 
 	/* VIA */
-	{ PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci_vt8251 }, /* VIA VT8251 */
+	{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
 
 	/* NVIDIA */
-	{ PCI_VENDOR_ID_NVIDIA, 0x044c, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci },		/* MCP65 */
-	{ PCI_VENDOR_ID_NVIDIA, 0x044d, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci },		/* MCP65 */
-	{ PCI_VENDOR_ID_NVIDIA, 0x044e, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci },		/* MCP65 */
-	{ PCI_VENDOR_ID_NVIDIA, 0x044f, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x044c), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci },		/* MCP65 */
 
 	/* SiS */
-	{ PCI_VENDOR_ID_SI, 0x1184, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* SiS 966 */
-	{ PCI_VENDOR_ID_SI, 0x1185, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* SiS 966 */
-	{ PCI_VENDOR_ID_SI, 0x0186, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci }, /* SiS 968 */
+	{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
+	{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
+	{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
 
 	{ }	/* terminate list */
 };
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b4abd68..dce6565 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2340,7 +2340,8 @@
 
 	if (status & ATA_BUSY)
 		ata_port_printk(ap, KERN_WARNING,
-				"port is slow to respond, please be patient\n");
+				"port is slow to respond, please be patient "
+				"(Status 0x%x)\n", status);
 
 	timeout = timer_start + tmout;
 	while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
@@ -2350,7 +2351,8 @@
 
 	if (status & ATA_BUSY) {
 		ata_port_printk(ap, KERN_ERR, "port failed to respond "
-				"(%lu secs)\n", tmout / HZ);
+				"(%lu secs, Status 0x%x)\n",
+				tmout / HZ, status);
 		return 1;
 	}
 
@@ -5478,11 +5480,10 @@
 		int irq_line = ent->irq;
 
 		ap = ata_port_add(ent, host, i);
+		host->ports[i] = ap;
 		if (!ap)
 			goto err_out;
 
-		host->ports[i] = ap;
-
 		/* dummy? */
 		if (ent->dummy_port_mask & (1 << i)) {
 			ata_port_printk(ap, KERN_INFO, "DUMMY\n");
@@ -5740,7 +5741,7 @@
 
 /**
  *	ata_scsi_release - SCSI layer callback hook for host unload
- *	@host: libata host to be unloaded
+ *	@shost: libata host to be unloaded
  *
  *	Performs all duties necessary to shut down a libata port...
  *	Kill port kthread, disable port, and release resources.
@@ -5786,6 +5787,7 @@
 	probe_ent->mwdma_mask = port->mwdma_mask;
 	probe_ent->udma_mask = port->udma_mask;
 	probe_ent->port_ops = port->port_ops;
+	probe_ent->private_data = port->private_data;
 
 	return probe_ent;
 }
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 3986ec8..b0d0cc4 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -889,6 +889,7 @@
 {
 	struct ata_port *ap = ata_shost_to_port(sdev->host);
 	struct ata_device *dev;
+	unsigned long flags;
 	int max_depth;
 
 	if (queue_depth < 1)
@@ -904,6 +905,14 @@
 		queue_depth = max_depth;
 
 	scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth);
+
+	spin_lock_irqsave(ap->lock, flags);
+	if (queue_depth > 1)
+		dev->flags &= ~ATA_DFLAG_NCQ_OFF;
+	else
+		dev->flags |= ATA_DFLAG_NCQ_OFF;
+	spin_unlock_irqrestore(ap->lock, flags);
+
 	return queue_depth;
 }
 
@@ -1293,7 +1302,8 @@
 		 */
 		goto nothing_to_do;
 
-	if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
+	if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
+			   ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
 		/* yay, NCQ */
 		if (!lba_48_ok(block, n_block))
 			goto out_of_range;
@@ -3174,7 +3184,7 @@
 
 /**
  *	ata_sas_port_alloc - Allocate port for a SAS attached SATA device
- *	@pdev: PCI device that the scsi device is attached to
+ *	@host: ATA host container for all SAS ports
  *	@port_info: Information from low-level host driver
  *	@shost: SCSI host that the scsi device is attached to
  *
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 08b3a40..06daaa3 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -828,7 +828,6 @@
 
 	probe_ent->irq = pdev->irq;
 	probe_ent->irq_flags = IRQF_SHARED;
-	probe_ent->private_data = port[0]->private_data;
 
 	if (ports & ATA_PORT_PRIMARY) {
 		probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
@@ -878,7 +877,6 @@
 		return NULL;
 
 	probe_ent->n_ports = 2;
-	probe_ent->private_data = port[0]->private_data;
 
 	if (port_mask & ATA_PORT_PRIMARY) {
 		probe_ent->irq = ATA_PRIMARY_IRQ;
@@ -908,6 +906,8 @@
 				probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
 		}
 		ata_std_ports(&probe_ent->port[1]);
+
+		/* FIXME: could be pointing to stack area; must copy */
 		probe_ent->pinfo2 = port[1];
 	} else
 		probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
@@ -946,35 +946,21 @@
 {
 	struct ata_probe_ent *probe_ent = NULL;
 	struct ata_port_info *port[2];
-	u8 tmp8, mask;
+	u8 mask;
 	unsigned int legacy_mode = 0;
 	int disable_dev_on_err = 1;
 	int rc;
 
 	DPRINTK("ENTER\n");
 
+	BUG_ON(n_ports < 1 || n_ports > 2);
+
 	port[0] = port_info[0];
 	if (n_ports > 1)
 		port[1] = port_info[1];
 	else
 		port[1] = port[0];
 
-	if ((port[0]->flags & ATA_FLAG_NO_LEGACY) == 0
-	    && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
-		/* TODO: What if one channel is in native mode ... */
-		pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
-		mask = (1 << 2) | (1 << 0);
-		if ((tmp8 & mask) != mask)
-			legacy_mode = (1 << 3);
-	}
-
-	/* FIXME... */
-	if ((!legacy_mode) && (n_ports > 2)) {
-		printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
-		n_ports = 2;
-		/* For now */
-	}
-
 	/* FIXME: Really for ATA it isn't safe because the device may be
 	   multi-purpose and we want to leave it alone if it was already
 	   enabled. Secondly for shared use as Arjan says we want refcounting
@@ -987,6 +973,16 @@
 	if (rc)
 		return rc;
 
+	if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+		u8 tmp8;
+
+		/* TODO: What if one channel is in native mode ... */
+		pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
+		mask = (1 << 2) | (1 << 0);
+		if ((tmp8 & mask) != mask)
+			legacy_mode = (1 << 3);
+	}
+
 	rc = pci_request_regions(pdev, DRV_NAME);
 	if (rc) {
 		disable_dev_on_err = 0;
@@ -1039,7 +1035,7 @@
 		goto err_out_regions;
 	}
 
-	/* FIXME: If we get no DMA mask we should fall back to PIO */
+	/* TODO: If we get no DMA mask we should fall back to PIO */
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
 		goto err_out_regions;
@@ -1062,13 +1058,17 @@
 
 	pci_set_master(pdev);
 
-	/* FIXME: check ata_device_add return */
-	ata_device_add(probe_ent);
+	if (!ata_device_add(probe_ent)) {
+		rc = -ENODEV;
+		goto err_out_ent;
+	}
 
 	kfree(probe_ent);
 
 	return 0;
 
+err_out_ent:
+	kfree(probe_ent);
 err_out_regions:
 	if (legacy_mode & ATA_PORT_PRIMARY)
 		release_region(ATA_PRIMARY_CMD, 8);
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 87af3b5..1d695df 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -34,7 +34,7 @@
 #include <linux/dmi.h>
 
 #define DRV_NAME "pata_ali"
-#define DRV_VERSION "0.6.5"
+#define DRV_VERSION "0.6.6"
 
 /*
  *	Cable special cases
@@ -630,7 +630,7 @@
 		pci_read_config_byte(pdev, 0x53, &tmp);
 		if (rev <= 0x20)
 			tmp &= ~0x02;
-		if (rev == 0xc7)
+		if (rev >= 0xc7)
 			tmp |= 0x03;
 		else
 			tmp |= 0x01;	/* CD_ROM enable for DMA */
@@ -644,10 +644,11 @@
 	return ata_pci_init_one(pdev, port_info, 2);
 }
 
-static struct pci_device_id ali[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229), },
-	{ 0, },
+static const struct pci_device_id ali[] = {
+	{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), },
+	{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), },
+
+	{ },
 };
 
 static struct pci_driver ali_pci_driver = {
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 599ee26..29234c8 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -662,27 +662,28 @@
 }
 
 static const struct pci_device_id amd[] = {
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_COBRA_7401,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  0 },
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7409,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  1 },
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7411,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  3 },
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_OPUS_7441,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  4 },
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8111_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  5 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  7 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_CS5536_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
-	{ 0, },
+	{ PCI_VDEVICE(AMD,	PCI_DEVICE_ID_AMD_COBRA_7401),		0 },
+	{ PCI_VDEVICE(AMD,	PCI_DEVICE_ID_AMD_VIPER_7409),		1 },
+	{ PCI_VDEVICE(AMD,	PCI_DEVICE_ID_AMD_VIPER_7411),		3 },
+	{ PCI_VDEVICE(AMD,	PCI_DEVICE_ID_AMD_OPUS_7441),		4 },
+	{ PCI_VDEVICE(AMD,	PCI_DEVICE_ID_AMD_8111_IDE),		5 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_IDE),	7 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE),	8 },
+	{ PCI_VDEVICE(AMD,	PCI_DEVICE_ID_AMD_CS5536_IDE),		9 },
+
+	{ },
 };
 
 static struct pci_driver amd_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= amd,
 	.probe 		= amd_init_one,
 	.remove		= ata_pci_remove_one
@@ -698,7 +699,6 @@
 	pci_unregister_driver(&amd_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for AMD PATA IDE");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index c4ccb75..690828e 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -426,7 +426,7 @@
 		.port_ops	= &artop6260_ops,
 	};
 	struct ata_port_info *port_info[2];
-	struct ata_port_info *info;
+	struct ata_port_info *info = NULL;
 	int ports = 2;
 
 	if (!printed_version++)
@@ -470,16 +470,20 @@
 		pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
 
 	}
+
+	BUG_ON(info == NULL);
+
 	port_info[0] = port_info[1] = info;
 	return ata_pci_init_one(pdev, port_info, ports);
 }
 
 static const struct pci_device_id artop_pci_tbl[] = {
-	{ 0x1191, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ 0x1191, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ 0x1191, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ 0x1191, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-	{ 0x1191, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+	{ PCI_VDEVICE(ARTOP, 0x0005), 0 },
+	{ PCI_VDEVICE(ARTOP, 0x0006), 1 },
+	{ PCI_VDEVICE(ARTOP, 0x0007), 1 },
+	{ PCI_VDEVICE(ARTOP, 0x0008), 2 },
+	{ PCI_VDEVICE(ARTOP, 0x0009), 2 },
+
 	{ }	/* terminate list */
 };
 
@@ -500,7 +504,6 @@
 	pci_unregister_driver(&artop_pci_driver);
 }
 
-
 module_init(artop_init);
 module_exit(artop_exit);
 
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 6c2269b..1ce28d2 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -267,12 +267,13 @@
 	return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id atiixp[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
-	{ 0, },
+static const struct pci_device_id atiixp[] = {
+	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), },
+	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
+	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
+	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
+
+	{ },
 };
 
 static struct pci_driver atiixp_pci_driver = {
@@ -293,7 +294,6 @@
 	pci_unregister_driver(&atiixp_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index e92b0ef..b9bbd1d 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -468,16 +468,17 @@
 	return ata_pci_init_one(pdev, port_info, 2);
 }
 
-static struct pci_device_id cmd64x[] = {
-	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
-	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
-	{ 0, },
+static const struct pci_device_id cmd64x[] = {
+	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
+	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
+	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 4 },
+	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 5 },
+
+	{ },
 };
 
 static struct pci_driver cmd64x_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= cmd64x,
 	.probe 		= cmd64x_init_one,
 	.remove		= ata_pci_remove_one
@@ -488,13 +489,11 @@
 	return pci_register_driver(&cmd64x_pci_driver);
 }
 
-
 static void __exit cmd64x_exit(void)
 {
 	pci_unregister_driver(&cmd64x_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index a6c6ceb..2cd3c0f 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -299,10 +299,11 @@
 /* For now keep DMA off. We can set it for all but A rev CS5510 once the
    core ATA code can handle it */
 
-static struct pci_device_id pata_cs5520[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
-	{ 0, },
+static const struct pci_device_id pata_cs5520[] = {
+	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
+	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
+
+	{ },
 };
 
 static struct pci_driver cs5520_pci_driver = {
@@ -312,7 +313,6 @@
 	.remove		= cs5520_remove_one
 };
 
-
 static int __init cs5520_init(void)
 {
 	return pci_register_driver(&cs5520_pci_driver);
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 7bba4d95..a07cc81 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -353,13 +353,14 @@
 	return -ENODEV;
 }
 
-static struct pci_device_id cs5530[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
-	{ 0, },
+static const struct pci_device_id cs5530[] = {
+	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
+
+	{ },
 };
 
 static struct pci_driver cs5530_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= cs5530,
 	.probe 		= cs5530_init_one,
 	.remove		= ata_pci_remove_one
@@ -370,13 +371,11 @@
 	return pci_register_driver(&cs5530_pci_driver);
 }
 
-
 static void __exit cs5530_exit(void)
 {
 	pci_unregister_driver(&cs5530_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index d64fcdc..f8def3f 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -257,9 +257,10 @@
 	return ata_pci_init_one(dev, ports, 1);
 }
 
-static struct pci_device_id cs5535[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_NS, 0x002D), },
-	{ 0, },
+static const struct pci_device_id cs5535[] = {
+	{ PCI_VDEVICE(NS, 0x002D), },
+
+	{ },
 };
 
 static struct pci_driver cs5535_pci_driver = {
@@ -274,13 +275,11 @@
 	return pci_register_driver(&cs5535_pci_driver);
 }
 
-
 static void __exit cs5535_exit(void)
 {
 	pci_unregister_driver(&cs5535_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch");
 MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index dfa5ac5..247b436 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -184,8 +184,8 @@
 	};
 	static struct ata_port_info *port_info[1] = { &info };
 
-	/* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. For the
-	   moment we don't handle the secondary. FIXME */
+	/* Devfn 1 is the ATA primary. The secondary is magic and on devfn2.
+	   For the moment we don't handle the secondary. FIXME */
 
 	if (PCI_FUNC(pdev->devfn) != 1)
 		return -ENODEV;
@@ -193,13 +193,14 @@
 	return ata_pci_init_one(pdev, port_info, 1);
 }
 
-static struct pci_device_id cy82c693[] = {
-	{ PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ 0, },
+static const struct pci_device_id cy82c693[] = {
+	{ PCI_VDEVICE(CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693), },
+
+	{ },
 };
 
 static struct pci_driver cy82c693_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= cy82c693,
 	.probe 		= cy82c693_init_one,
 	.remove		= ata_pci_remove_one
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index 95cd1ca..ef18c60 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -305,7 +305,8 @@
 }
 
 static const struct pci_device_id efar_pci_tbl[] = {
-	{ 0x1055, 0x9130, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VDEVICE(EFAR, 0x9130), },
+
 	{ }	/* terminate list */
 };
 
@@ -326,7 +327,6 @@
 	pci_unregister_driver(&efar_pci_driver);
 }
 
-
 module_init(efar_init);
 module_exit(efar_exit);
 
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index cf656ec..6d3e4c0 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -429,7 +429,7 @@
 
 	/* PCI clocking determines the ATA timing values to use */
 	/* info_hpt366 is safe against re-entry so we can scribble on it */
-	switch(reg1 & 0x700) {
+	switch((reg1 & 0x700) >> 8) {
 		case 5:
 			info_hpt366.private_data = &hpt366_40;
 			break;
@@ -444,13 +444,14 @@
 	return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt36x[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
-	{ 0, },
+static const struct pci_device_id hpt36x[] = {
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+
+	{ },
 };
 
 static struct pci_driver hpt36x_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= hpt36x,
 	.probe 		= hpt36x_init_one,
 	.remove		= ata_pci_remove_one
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 10318c0..7350443 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -1219,17 +1219,18 @@
 	return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt37x[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), },
-	{ 0, },
+static const struct pci_device_id hpt37x[] = {
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), },
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
+
+	{ },
 };
 
 static struct pci_driver hpt37x_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= hpt37x,
 	.probe 		= hpt37x_init_one,
 	.remove		= ata_pci_remove_one
@@ -1240,13 +1241,11 @@
 	return pci_register_driver(&hpt37x_pci_driver);
 }
 
-
 static void __exit hpt37x_exit(void)
 {
 	pci_unregister_driver(&hpt37x_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 5c5d4f6..58cfb2b 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -560,16 +560,17 @@
 	return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt3x2n[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N), },
-	{ 0, },
+static const struct pci_device_id hpt3x2n[] = {
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), },
+
+	{ },
 };
 
 static struct pci_driver hpt3x2n_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= hpt3x2n,
 	.probe 		= hpt3x2n_init_one,
 	.remove		= ata_pci_remove_one
@@ -580,13 +581,11 @@
 	return pci_register_driver(&hpt3x2n_pci_driver);
 }
 
-
 static void __exit hpt3x2n_exit(void)
 {
 	pci_unregister_driver(&hpt3x2n_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 1f084ab..3334d72 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -192,13 +192,14 @@
 	return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt3x3[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343), },
-	{ 0, },
+static const struct pci_device_id hpt3x3[] = {
+	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), },
+
+	{ },
 };
 
 static struct pci_driver hpt3x3_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= hpt3x3,
 	.probe 		= hpt3x3_init_one,
 	.remove		= ata_pci_remove_one
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 82a46ff..18ff3e5 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -808,14 +808,15 @@
 	return ata_pci_init_one(pdev, port_info, 2);
 }
 
-static struct pci_device_id it821x[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212), },
-	{ 0, },
+static const struct pci_device_id it821x[] = {
+	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
+	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
+
+	{ },
 };
 
 static struct pci_driver it821x_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= it821x,
 	.probe 		= it821x_init_one,
 	.remove		= ata_pci_remove_one
@@ -826,13 +827,11 @@
 	return pci_register_driver(&it821x_pci_driver);
 }
 
-
 static void __exit it821x_exit(void)
 {
 	pci_unregister_driver(&it821x_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the IT8211/IT8212 IDE RAID controller");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index be3a866..52a2bdf 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -229,11 +229,12 @@
 }
 
 static const struct pci_device_id jmicron_pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
-	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
-	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365},
-	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366},
-	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368},
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365},
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366},
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368},
+
 	{ }	/* terminate list */
 };
 
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 3c65393..9dfe3e9 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -274,11 +274,10 @@
 	dev_set_drvdata(dev, NULL);
 }
 
-
-
 static const struct pci_device_id mpiix[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX), },
-	{ 0, },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), },
+
+	{ },
 };
 
 static struct pci_driver mpiix_pci_driver = {
@@ -293,13 +292,11 @@
 	return pci_register_driver(&mpiix_pci_driver);
 }
 
-
 static void __exit mpiix_exit(void)
 {
 	pci_unregister_driver(&mpiix_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Intel MPIIX");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 76eb9c9..f5672de 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -142,7 +142,8 @@
 }
 
 static const struct pci_device_id netcell_pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_NETCELL, PCI_DEVICE_ID_REVOLUTION), },
+	{ PCI_VDEVICE(NETCELL, PCI_DEVICE_ID_REVOLUTION), },
+
 	{ }	/* terminate list */
 };
 
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 2005a95..2a3dbee 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -200,12 +200,13 @@
 }
 
 static const struct pci_device_id ns87410[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410), },
-	{ 0, },
+	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87410), },
+
+	{ },
 };
 
 static struct pci_driver ns87410_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= ns87410,
 	.probe 		= ns87410_init_one,
 	.remove		= ata_pci_remove_one
@@ -216,13 +217,11 @@
 	return pci_register_driver(&ns87410_pci_driver);
 }
 
-
 static void __exit ns87410_exit(void)
 {
 	pci_unregister_driver(&ns87410_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Nat Semi 87410");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 31a285c..fc947df 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -303,7 +303,8 @@
 }
 
 static const struct pci_device_id oldpiix_pci_tbl[] = {
-	{ PCI_DEVICE(0x8086, 0x1230), },
+	{ PCI_VDEVICE(INTEL, 0x1230), },
+
 	{ }	/* terminate list */
 };
 
@@ -324,7 +325,6 @@
 	pci_unregister_driver(&oldpiix_pci_driver);
 }
 
-
 module_init(oldpiix_init);
 module_exit(oldpiix_exit);
 
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index 57fe21f..a7320ba 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -256,13 +256,14 @@
 }
 
 static const struct pci_device_id opti[] = {
-	{ PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ 0, },
+	{ PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C621), 0 },
+	{ PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 1 },
+
+	{ },
 };
 
 static struct pci_driver opti_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= opti,
 	.probe 		= opti_init_one,
 	.remove		= ata_pci_remove_one
@@ -273,7 +274,6 @@
 	return pci_register_driver(&opti_pci_driver);
 }
 
-
 static void __exit opti_exit(void)
 {
 	pci_unregister_driver(&opti_pci_driver);
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 7296a20..c6906b4 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -512,12 +512,13 @@
 }
 
 static const struct pci_device_id optidma[] = {
-	{ PCI_DEVICE(0x1045, 0xD568), },	/* Opti 82C700 */
-	{ 0, },
+	{ PCI_VDEVICE(OPTI, 0xD568), },		/* Opti 82C700 */
+
+	{ },
 };
 
 static struct pci_driver optidma_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= optidma,
 	.probe 		= optidma_init_one,
 	.remove		= ata_pci_remove_one
@@ -528,13 +529,11 @@
 	return pci_register_driver(&optidma_pci_driver);
 }
 
-
 static void __exit optidma_exit(void)
 {
 	pci_unregister_driver(&optidma_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Opti Firestar/Firestar Plus");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index cb501e1..e93ea27 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -42,7 +42,7 @@
 
 
 #define DRV_NAME "pata_pcmcia"
-#define DRV_VERSION "0.2.9"
+#define DRV_VERSION "0.2.11"
 
 /*
  *	Private data structure to glue stuff together
@@ -355,6 +355,8 @@
 	PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
 	PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
 	PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
+	PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
+	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
 	PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
 	PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
 	PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index bd4ed67..d894d99 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -108,13 +108,14 @@
 };
 
 static const struct pci_device_id pdc2027x_pci_tbl[] = {
-	{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 },
-	{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-	{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 },
-	{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-	{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-	{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-	{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), PDC_UDMA_100 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), PDC_UDMA_133 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), PDC_UDMA_100 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), PDC_UDMA_133 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), PDC_UDMA_133 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), PDC_UDMA_133 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), PDC_UDMA_133 },
+
 	{ }	/* terminate list */
 };
 
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 48f4343..5ba9eb2 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -385,17 +385,18 @@
 	return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id pdc[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0},
-	{ PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1},
-	{ PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1},
-	{ PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2},
-	{ PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2},
-	{ 0, },
+static const struct pci_device_id pdc[] = {
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2 },
+	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2 },
+
+	{ },
 };
 
 static struct pci_driver pdc_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= pdc,
 	.probe 		= pdc_init_one,
 	.remove		= ata_pci_remove_one
@@ -406,13 +407,11 @@
 	return pci_register_driver(&pdc_pci_driver);
 }
 
-
 static void __exit pdc_exit(void)
 {
 	pci_unregister_driver(&pdc_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index c20bcf4..1af83d7 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -300,7 +300,8 @@
 }
 
 static const struct pci_device_id radisys_pci_tbl[] = {
-	{ 0x1331, 0x8201, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VDEVICE(RADISYS, 0x8201), },
+
 	{ }	/* terminate list */
 };
 
@@ -321,7 +322,6 @@
 	pci_unregister_driver(&radisys_pci_driver);
 }
 
-
 module_init(radisys_init);
 module_exit(radisys_exit);
 
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index eccc6fd..4533b63 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -170,20 +170,20 @@
 	return -ENODEV;
 }
 
-static struct pci_device_id pata_rz1000[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), },
-	{ 0, },
+static const struct pci_device_id pata_rz1000[] = {
+	{ PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
+	{ PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), },
+
+	{ },
 };
 
 static struct pci_driver rz1000_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= pata_rz1000,
 	.probe 		= rz1000_init_one,
 	.remove		= ata_pci_remove_one
 };
 
-
 static int __init rz1000_init(void)
 {
 	return pci_register_driver(&rz1000_pci_driver);
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 107e6cd..067d9d2 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -253,13 +253,14 @@
 	return ata_pci_init_one(dev, port_info, 1);
 }
 
-static struct pci_device_id sc1200[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), },
-	{ 0, },
+static const struct pci_device_id sc1200[] = {
+	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_IDE), },
+
+	{ },
 };
 
 static struct pci_driver sc1200_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= sc1200,
 	.probe 		= sc1200_init_one,
 	.remove		= ata_pci_remove_one
@@ -270,13 +271,11 @@
 	return pci_register_driver(&sc1200_pci_driver);
 }
 
-
 static void __exit sc1200_exit(void)
 {
 	pci_unregister_driver(&sc1200_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox, Mark Lord");
 MODULE_DESCRIPTION("low-level driver for the NS/AMD SC1200");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index a5c8d7e..5bbf76e 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -553,13 +553,14 @@
 	return ata_pci_init_one(pdev, port_info, ports);
 }
 
-static struct pci_device_id serverworks[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2},
-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2},
-	{ 0, },
+static const struct pci_device_id serverworks[] = {
+	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
+	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
+	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
+	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2},
+	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2},
+
+	{ },
 };
 
 static struct pci_driver serverworks_pci_driver = {
@@ -574,13 +575,11 @@
 	return pci_register_driver(&serverworks_pci_driver);
 }
 
-
 static void __exit serverworks_exit(void)
 {
 	pci_unregister_driver(&serverworks_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index c8b2e26..4a2b72b 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -348,12 +348,13 @@
 }
 
 static const struct pci_device_id sil680[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), },
-	{ 0, },
+	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },
+
+	{ },
 };
 
 static struct pci_driver sil680_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= sil680,
 	.probe 		= sil680_init_one,
 	.remove		= ata_pci_remove_one
@@ -364,13 +365,11 @@
 	return pci_register_driver(&sil680_pci_driver);
 }
 
-
 static void __exit sil680_exit(void)
 {
 	pci_unregister_driver(&sil680_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for SI680 PATA");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 17791e2..b9ffafb 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -988,8 +988,9 @@
 }
 
 static const struct pci_device_id sis_pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x5513), },	/* SiS 5513 */
-	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x5518), },	/* SiS 5518 */
+	{ PCI_VDEVICE(SI, 0x5513), },	/* SiS 5513 */
+	{ PCI_VDEVICE(SI, 0x5518), },	/* SiS 5518 */
+
 	{ }
 };
 
@@ -1010,7 +1011,6 @@
 	pci_unregister_driver(&sis_pci_driver);
 }
 
-
 module_init(sis_init);
 module_exit(sis_exit);
 
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 5b762ac..08a6dc8 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -351,9 +351,10 @@
 	return ata_pci_init_one(dev, port_info, 1); /* For now */
 }
 
-static struct pci_device_id sl82c105[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), },
-	{ 0, },
+static const struct pci_device_id sl82c105[] = {
+	{ PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), },
+
+	{ },
 };
 
 static struct pci_driver sl82c105_pci_driver = {
@@ -368,13 +369,11 @@
 	return pci_register_driver(&sl82c105_pci_driver);
 }
 
-
 static void __exit sl82c105_exit(void)
 {
 	pci_unregister_driver(&sl82c105_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Sl82c105");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index a954ed9..9640f80 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -248,13 +248,13 @@
 }
 
 static const struct pci_device_id triflex[] = {
-	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE,
-				  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ 0, },
+	{ PCI_VDEVICE(COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE), },
+
+	{ },
 };
 
 static struct pci_driver triflex_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= triflex,
 	.probe 		= triflex_init_one,
 	.remove		= ata_pci_remove_one
@@ -265,13 +265,11 @@
 	return pci_register_driver(&triflex_pci_driver);
 }
 
-
 static void __exit triflex_exit(void)
 {
 	pci_unregister_driver(&triflex_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Compaq Triflex");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 7b5dd23..1e7be9e 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -529,15 +529,16 @@
 }
 
 static const struct pci_device_id via[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
-	{ 0, },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
+
+	{ },
 };
 
 static struct pci_driver via_pci_driver = {
-        .name 		= DRV_NAME,
+	.name 		= DRV_NAME,
 	.id_table	= via,
 	.probe 		= via_init_one,
 	.remove		= ata_pci_remove_one
@@ -548,13 +549,11 @@
 	return pci_register_driver(&via_pci_driver);
 }
 
-
 static void __exit via_exit(void)
 {
 	pci_unregister_driver(&via_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for VIA PATA");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 0e23ecb..81f3d21 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -192,8 +192,7 @@
 };
 
 static const struct pci_device_id adma_ata_pci_tbl[] = {
-	{ PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_1841_idx },
+	{ PCI_VDEVICE(PDC, 0x1841), board_1841_idx },
 
 	{ }	/* terminate list */
 };
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index c01496d..e6aa1a8 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -533,19 +533,20 @@
 };
 
 static const struct pci_device_id mv_pci_tbl[] = {
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x},
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x},
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_5080},
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x},
+	{ PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
+	{ PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
+	{ PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
+	{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
 
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x},
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x},
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6042), 0, 0, chip_6042},
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x},
-	{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x},
+	{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
+	{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
+	{ PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
+	{ PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
+	{ PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
 
-	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x0241), 0, 0, chip_604x},
-	{}			/* terminate list */
+	{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
+
+	{ }			/* terminate list */
 };
 
 static struct pci_driver mv_pci_driver = {
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 8cd730f..d09d20a 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -106,45 +106,32 @@
 };
 
 static const struct pci_device_id nv_pci_tbl[] = {
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, 0x045c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, 0x045d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, 0x045e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, 0x045f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA), NFORCE2 },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA), NFORCE3 },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2), NFORCE3 },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA), CK804 },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, 0x045c), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, 0x045d), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, 0x045e), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, 0x045f), GENERIC },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_STORAGE_RAID<<8, 0xffff00, GENERIC },
-	{ 0, } /* terminate list */
+
+	{ } /* terminate list */
 };
 
 static struct pci_driver nv_pci_driver = {
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index d627812..15c9437 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -234,48 +234,31 @@
 };
 
 static const struct pci_device_id pdc_ata_pci_tbl[] = {
-	{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2037x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2037x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2037x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2037x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2037x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2037x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2057x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2057x },
-	{ PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2037x },
+	{ PCI_VDEVICE(PROMISE, 0x3371), board_2037x },
+	{ PCI_VDEVICE(PROMISE, 0x3570), board_2037x },
+	{ PCI_VDEVICE(PROMISE, 0x3571), board_2037x },
+	{ PCI_VDEVICE(PROMISE, 0x3373), board_2037x },
+	{ PCI_VDEVICE(PROMISE, 0x3375), board_2037x },
+	{ PCI_VDEVICE(PROMISE, 0x3376), board_2037x },
+	{ PCI_VDEVICE(PROMISE, 0x3574), board_2057x },
+	{ PCI_VDEVICE(PROMISE, 0x3d75), board_2057x },
+	{ PCI_VDEVICE(PROMISE, 0x3d73), board_2037x },
 
-	{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20319 },
-	{ PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20319 },
-	{ PCI_VENDOR_ID_PROMISE, 0x3515, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20319 },
-	{ PCI_VENDOR_ID_PROMISE, 0x3519, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20319 },
-	{ PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20319 },
-	{ PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_40518 },
+	{ PCI_VDEVICE(PROMISE, 0x3318), board_20319 },
+	{ PCI_VDEVICE(PROMISE, 0x3319), board_20319 },
+	{ PCI_VDEVICE(PROMISE, 0x3515), board_20319 },
+	{ PCI_VDEVICE(PROMISE, 0x3519), board_20319 },
+	{ PCI_VDEVICE(PROMISE, 0x3d17), board_20319 },
+	{ PCI_VDEVICE(PROMISE, 0x3d18), board_40518 },
 
-	{ PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20619 },
+	{ PCI_VDEVICE(PROMISE, 0x6629), board_20619 },
 
 /* TODO: remove all associated board_20771 code, as it completely
  * duplicates board_2037x code, unless reason for separation can be
  * divined.
  */
 #if 0
-	{ PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20771 },
+	{ PCI_VDEVICE(PROMISE, 0x3570), board_20771 },
 #endif
 
 	{ }	/* terminate list */
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index fa29dfe..7f6cc3c 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -185,8 +185,7 @@
 };
 
 static const struct pci_device_id qs_ata_pci_tbl[] = {
-	{ PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_2068_idx },
+	{ PCI_VDEVICE(PDC, 0x2068), board_2068_idx },
 
 	{ }	/* terminate list */
 };
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index c63dbab..3d9fa1c 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -123,13 +123,14 @@
 
 
 static const struct pci_device_id sil_pci_tbl[] = {
-	{ 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-	{ 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-	{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 },
-	{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
-	{ 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-	{ 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq },
-	{ 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq },
+	{ PCI_VDEVICE(CMD, 0x3112), sil_3112 },
+	{ PCI_VDEVICE(CMD, 0x0240), sil_3112 },
+	{ PCI_VDEVICE(CMD, 0x3512), sil_3512 },
+	{ PCI_VDEVICE(CMD, 0x3114), sil_3114 },
+	{ PCI_VDEVICE(ATI, 0x436e), sil_3112 },
+	{ PCI_VDEVICE(ATI, 0x4379), sil_3112_no_sata_irq },
+	{ PCI_VDEVICE(ATI, 0x437a), sil_3112_no_sata_irq },
+
 	{ }	/* terminate list */
 };
 
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 39cb07b..a951f40 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -344,11 +344,12 @@
 #endif
 
 static const struct pci_device_id sil24_pci_tbl[] = {
-	{ 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
-	{ 0x8086, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
-	{ 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
-	{ 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
-	{ 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
+	{ PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 },
+	{ PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 },
+	{ PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 },
+	{ PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 },
+	{ PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 },
+
 	{ } /* terminate list */
 };
 
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 18d49ff..0738f52 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -67,13 +67,13 @@
 static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id sis_pci_tbl[] = {
-	{ PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
-	{ PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
-	{ PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
+	{ PCI_VDEVICE(SI, 0x180), sis_180 },
+	{ PCI_VDEVICE(SI, 0x181), sis_180 },
+	{ PCI_VDEVICE(SI, 0x182), sis_180 },
+
 	{ }	/* terminate list */
 };
 
-
 static struct pci_driver sis_pci_driver = {
 	.name			= DRV_NAME,
 	.id_table		= sis_pci_tbl,
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index d6d6658..84025a2 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -469,15 +469,15 @@
  * controller
  * */
 static const struct pci_device_id k2_sata_pci_tbl[] = {
-	{ 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-	{ 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-	{ 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-	{ 0x1166, 0x024a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-	{ 0x1166, 0x024b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x0240), 4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x0241), 4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x0242), 8 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x024a), 4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x024b), 4 },
+
 	{ }
 };
 
-
 static struct pci_driver k2_sata_pci_driver = {
 	.name			= DRV_NAME,
 	.id_table		= k2_sata_pci_tbl,
@@ -485,19 +485,16 @@
 	.remove			= ata_pci_remove_one,
 };
 
-
 static int __init k2_sata_init(void)
 {
 	return pci_register_driver(&k2_sata_pci_driver);
 }
 
-
 static void __exit k2_sata_exit(void)
 {
 	pci_unregister_driver(&k2_sata_pci_driver);
 }
 
-
 MODULE_AUTHOR("Benjamin Herrenschmidt");
 MODULE_DESCRIPTION("low-level driver for K2 SATA controller");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 091867e..8c74f2f 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -230,12 +230,11 @@
 };
 
 static const struct pci_device_id pdc_sata_pci_tbl[] = {
-	{ PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_20621 },
+	{ PCI_VDEVICE(PROMISE, 0x6622), board_20621 },
+
 	{ }	/* terminate list */
 };
 
-
 static struct pci_driver pdc_sata_pci_driver = {
 	.name			= DRV_NAME,
 	.id_table		= pdc_sata_pci_tbl,
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index dd76f37..5c603ca 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -61,13 +61,13 @@
 static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id uli_pci_tbl[] = {
-	{ PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
-	{ PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
-	{ PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
+	{ PCI_VDEVICE(AL, 0x5289), uli_5289 },
+	{ PCI_VDEVICE(AL, 0x5287), uli_5287 },
+	{ PCI_VDEVICE(AL, 0x5281), uli_5281 },
+
 	{ }	/* terminate list */
 };
 
-
 static struct pci_driver uli_pci_driver = {
 	.name			= DRV_NAME,
 	.id_table		= uli_pci_tbl,
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index a72a238..f4455a1 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -77,9 +77,9 @@
 static void vt6420_error_handler(struct ata_port *ap);
 
 static const struct pci_device_id svia_pci_tbl[] = {
-	{ 0x1106, 0x0591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
-	{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
-	{ 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },
+	{ PCI_VDEVICE(VIA, 0x0591), vt6420 },
+	{ PCI_VDEVICE(VIA, 0x3149), vt6420 },
+	{ PCI_VDEVICE(VIA, 0x3249), vt6421 },
 
 	{ }	/* terminate list */
 };
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index d0d92f3..273d88f 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -442,16 +442,15 @@
 	return rc;
 }
 
-
 static const struct pci_device_id vsc_sata_pci_tbl[] = {
 	{ PCI_VENDOR_ID_VITESSE, 0x7174,
 	  PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
 	{ PCI_VENDOR_ID_INTEL, 0x3200,
 	  PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
+
 	{ }	/* terminate list */
 };
 
-
 static struct pci_driver vsc_sata_pci_driver = {
 	.name			= DRV_NAME,
 	.id_table		= vsc_sata_pci_tbl,
@@ -459,19 +458,16 @@
 	.remove			= ata_pci_remove_one,
 };
 
-
 static int __init vsc_sata_init(void)
 {
 	return pci_register_driver(&vsc_sata_pci_driver);
 }
 
-
 static void __exit vsc_sata_exit(void)
 {
 	pci_unregister_driver(&vsc_sata_pci_driver);
 }
 
-
 MODULE_AUTHOR("Jeremy Higdon");
 MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller");
 MODULE_LICENSE("GPL");
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
index 6cc93de..ac2c108 100644
--- a/drivers/atm/adummy.c
+++ b/drivers/atm/adummy.c
@@ -113,15 +113,13 @@
 
 	printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
 
-	adummy_dev = (struct adummy_dev *) kmalloc(sizeof(struct adummy_dev),
+	adummy_dev = kzalloc(sizeof(struct adummy_dev),
 						   GFP_KERNEL);
 	if (!adummy_dev) {
-		printk(KERN_ERR DEV_LABEL ": kmalloc() failed\n");
+		printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
 		err = -ENOMEM;
 		goto out;
 	}
-	memset(adummy_dev, 0, sizeof(struct adummy_dev));
-
 	atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
 	if (!atm_dev) {
 		printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 4521a24..da599e6 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -915,8 +915,8 @@
 
 /********** make rate (not quite as much fun as Horizon) **********/
 
-static unsigned int make_rate (unsigned int rate, rounding r,
-			       u16 * bits, unsigned int * actual) {
+static int make_rate (unsigned int rate, rounding r,
+		      u16 * bits, unsigned int * actual) {
   unsigned char exp = -1; // hush gcc
   unsigned int man = -1;  // hush gcc
   
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 38fc054..5f25e5e 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1784,7 +1784,7 @@
 		write_fs (dev, RAM, (1 << (28 - FS155_VPI_BITS - FS155_VCI_BITS)) - 1);
 		dev->nchannels = FS155_NR_CHANNELS;
 	}
-	dev->atm_vccs = kmalloc (dev->nchannels * sizeof (struct atm_vcc *), 
+	dev->atm_vccs = kcalloc (dev->nchannels, sizeof (struct atm_vcc *),
 				 GFP_KERNEL);
 	fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%Zd)\n",
 		    dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *));
@@ -1794,9 +1794,8 @@
 		/* XXX Clean up..... */
 		return 1;
 	}
-	memset (dev->atm_vccs, 0, dev->nchannels * sizeof (struct atm_vcc *));
 
-	dev->tx_inuse = kmalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
+	dev->tx_inuse = kzalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
 	fs_dprintk (FS_DEBUG_ALLOC, "Alloc tx_inuse: %p(%d)\n", 
 		    dev->atm_vccs, dev->nchannels / 8);
 
@@ -1805,8 +1804,6 @@
 		/* XXX Clean up..... */
 		return 1;
 	}
-	memset (dev->tx_inuse, 0, dev->nchannels / 8);
-
 	/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */
 	/* -- RAS2 : FS50 only: Default is OK. */
 
@@ -1893,14 +1890,11 @@
 	if (pci_enable_device(pci_dev)) 
 		goto err_out;
 
-	fs_dev = kmalloc (sizeof (struct fs_dev), GFP_KERNEL);
+	fs_dev = kzalloc (sizeof (struct fs_dev), GFP_KERNEL);
 	fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%Zd)\n",
 		    fs_dev, sizeof (struct fs_dev));
 	if (!fs_dev)
 		goto err_out;
-
-	memset (fs_dev, 0, sizeof (struct fs_dev));
-  
 	atm_dev = atm_dev_register("fs", &ops, -1, NULL);
 	if (!atm_dev)
 		goto err_out_free_fs_dev;
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index f2511b4..b22a914 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -383,14 +383,12 @@
 	}
 	pci_set_drvdata(pci_dev, atm_dev);
 
-	he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev),
+	he_dev = kzalloc(sizeof(struct he_dev),
 							GFP_KERNEL);
 	if (!he_dev) {
 		err = -ENOMEM;
 		goto init_one_failure;
 	}
-	memset(he_dev, 0, sizeof(struct he_dev));
-
 	he_dev->pci_dev = pci_dev;
 	he_dev->atm_dev = atm_dev;
 	he_dev->atm_dev->dev_data = he_dev;
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index d1113e8..209dba1 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2719,7 +2719,7 @@
 		goto out_disable;
 	}
 
-	dev = kmalloc(sizeof(hrz_dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(hrz_dev), GFP_KERNEL);
 	if (!dev) {
 		// perhaps we should be nice: deregister all adapters and abort?
 		PRINTD(DBG_ERR, "out of memory");
@@ -2727,8 +2727,6 @@
 		goto out_release;
 	}
 
-	memset(dev, 0, sizeof(hrz_dev));
-
 	pci_set_drvdata(pci_dev, dev);
 
 	// grab IRQ and install handler - move this someplace more sensible
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index b0369bb..7487f0a 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -642,11 +642,9 @@
 {
 	struct scq_info *scq;
 
-	scq = (struct scq_info *) kmalloc(sizeof(struct scq_info), GFP_KERNEL);
+	scq = kzalloc(sizeof(struct scq_info), GFP_KERNEL);
 	if (!scq)
 		return NULL;
-	memset(scq, 0, sizeof(struct scq_info));
-
 	scq->base = pci_alloc_consistent(card->pcidev, SCQ_SIZE,
 					 &scq->paddr);
 	if (scq->base == NULL) {
@@ -2142,11 +2140,9 @@
 {
 	struct rate_estimator *est;
 
-	est = kmalloc(sizeof(struct rate_estimator), GFP_KERNEL);
+	est = kzalloc(sizeof(struct rate_estimator), GFP_KERNEL);
 	if (!est)
 		return NULL;
-	memset(est, 0, sizeof(*est));
-
 	est->maxcps = pcr < 0 ? -pcr : pcr;
 	est->cps = est->maxcps;
 	est->avcps = est->cps << 5;
@@ -2451,14 +2447,12 @@
 
 	index = VPCI2VC(card, vpi, vci);
 	if (!card->vcs[index]) {
-		card->vcs[index] = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+		card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
 		if (!card->vcs[index]) {
 			printk("%s: can't alloc vc in open()\n", card->name);
 			up(&card->mutex);
 			return -ENOMEM;
 		}
-		memset(card->vcs[index], 0, sizeof(struct vc_map));
-
 		card->vcs[index]->card = card;
 		card->vcs[index]->index = index;
 
@@ -2926,13 +2920,11 @@
 		for (vci = 3; vci < 5; vci++) {
 			index = VPCI2VC(card, vpi, vci);
 
-			vc = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+			vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
 			if (!vc) {
 				printk("%s: can't alloc vc\n", card->name);
 				return -ENOMEM;
 			}
-			memset(vc, 0, sizeof(struct vc_map));
-
 			vc->index = index;
 			card->vcs[index] = vc;
 
@@ -2995,12 +2987,11 @@
 {
 	struct vc_map *vc;
 
-	vc = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+	vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
 	if (!vc) {
 		printk("%s: can't alloc vc\n", card->name);
 		return -ENOMEM;
 	}
-	memset(vc, 0, sizeof(struct vc_map));
 	card->vcs[0] = vc;
 	vc->class = SCHED_UBR0;
 
@@ -3695,14 +3686,12 @@
 		goto err_out_disable_pdev;
 	}
 
-	card = kmalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
+	card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
 	if (!card) {
 		printk("idt77252-%d: can't allocate private data\n", index);
 		err = -ENOMEM;
 		goto err_out_disable_pdev;
 	}
-	memset(card, 0, sizeof(struct idt77252_dev));
-
 	card->revision = revision;
 	card->index = index;
 	card->pcidev = pcidev;
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index fe60a59..b9568e1 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -1482,16 +1482,10 @@
 static inline struct lanai_vcc *new_lanai_vcc(void)
 {
 	struct lanai_vcc *lvcc;
-	lvcc = (struct lanai_vcc *) kmalloc(sizeof(*lvcc), GFP_KERNEL);
+	lvcc =  kzalloc(sizeof(*lvcc), GFP_KERNEL);
 	if (likely(lvcc != NULL)) {
-		lvcc->vbase = NULL;
-		lvcc->rx.atmvcc = lvcc->tx.atmvcc = NULL;
-		lvcc->nref = 0;
-		memset(&lvcc->stats, 0, sizeof lvcc->stats);
-		lvcc->rx.buf.start = lvcc->tx.buf.start = NULL;
 		skb_queue_head_init(&lvcc->tx.backlog);
 #ifdef DEBUG
-		lvcc->tx.unqueue = NULL;
 		lvcc->vci = -1;
 #endif
 	}
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 2c65e82..083c5d3 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -603,9 +603,8 @@
 DPRINTK("start_rx\n");
 	zatm_dev = ZATM_DEV(dev);
 	size = sizeof(struct atm_vcc *)*zatm_dev->chans;
-	zatm_dev->rx_map = (struct atm_vcc **) kmalloc(size,GFP_KERNEL);
+	zatm_dev->rx_map =  kzalloc(size,GFP_KERNEL);
 	if (!zatm_dev->rx_map) return -ENOMEM;
-	memset(zatm_dev->rx_map,0,size);
 	/* set VPI/VCI split (use all VCIs and give what's left to VPIs) */
 	zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);
 	/* prepare free buffer pools */
@@ -801,6 +800,7 @@
 		i = m = 1;
 		zatm_dev->ubr_ref_cnt++;
 		zatm_dev->ubr = shaper;
+		*pcr = 0;
 	}
 	else {
 		if (min) {
@@ -951,9 +951,8 @@
 	skb_queue_head_init(&zatm_vcc->tx_queue);
 	init_waitqueue_head(&zatm_vcc->tx_wait);
 	/* initialize ring */
-	zatm_vcc->ring = kmalloc(RING_SIZE,GFP_KERNEL);
+	zatm_vcc->ring = kzalloc(RING_SIZE,GFP_KERNEL);
 	if (!zatm_vcc->ring) return -ENOMEM;
-	memset(zatm_vcc->ring,0,RING_SIZE);
 	loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;
 	loop[0] = uPD98401_TXPD_V;
 	loop[1] = loop[2] = 0;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 422e31d..17dc222 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -207,8 +207,7 @@
 	  module will be called umem.
 
 	  The umem driver has not yet been allocated a MAJOR number, so
-	  one is chosen dynamically.  Use "devfs" or look in /proc/devices
-	  for the device number
+	  one is chosen dynamically.
 
 config BLK_DEV_UBD
 	bool "Virtual block device"
@@ -407,7 +406,7 @@
 	depends on BLK_DEV_RAM
 	default "1024"
 	help
-	  The default value is 1024 kilobytes.  PAGE_SIZE is a much more
+	  The default value is 1024 bytes.  PAGE_SIZE is a much more
 	  efficient choice however.  The default is kept to ensure initrd
 	  setups function - apparently needed by the rd_load_image routine
 	  that supposes the filesystem in the image uses a 1024 blocksize.
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a6b2aa6..f2904f6 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -62,6 +62,8 @@
 
 #include <asm/uaccess.h>
 
+#define DRIVER_NAME	"pktcdvd"
+
 #if PACKET_DEBUG
 #define DPRINTK(fmt, args...) printk(KERN_NOTICE fmt, ##args)
 #else
@@ -80,7 +82,7 @@
 
 static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
 static struct proc_dir_entry *pkt_proc;
-static int pkt_major;
+static int pktdev_major;
 static struct mutex ctl_mutex;	/* Serialize open/close/setup/teardown */
 static mempool_t *psd_pool;
 
@@ -89,7 +91,7 @@
 {
 	BUG_ON(atomic_read(&pd->cdrw.pending_bios) <= 0);
 	if (atomic_dec_and_test(&pd->cdrw.pending_bios)) {
-		VPRINTK("pktcdvd: queue empty\n");
+		VPRINTK(DRIVER_NAME": queue empty\n");
 		atomic_set(&pd->iosched.attention, 1);
 		wake_up(&pd->wqueue);
 	}
@@ -400,7 +402,7 @@
 	int i;
 	struct request_sense *sense = cgc->sense;
 
-	printk("pktcdvd:");
+	printk(DRIVER_NAME":");
 	for (i = 0; i < CDROM_PACKET_SIZE; i++)
 		printk(" %02x", cgc->cmd[i]);
 	printk(" - ");
@@ -528,7 +530,7 @@
 				need_write_seek = 0;
 			if (need_write_seek && reads_queued) {
 				if (atomic_read(&pd->cdrw.pending_bios) > 0) {
-					VPRINTK("pktcdvd: write, waiting\n");
+					VPRINTK(DRIVER_NAME": write, waiting\n");
 					break;
 				}
 				pkt_flush_cache(pd);
@@ -537,7 +539,7 @@
 		} else {
 			if (!reads_queued && writes_queued) {
 				if (atomic_read(&pd->cdrw.pending_bios) > 0) {
-					VPRINTK("pktcdvd: read, waiting\n");
+					VPRINTK(DRIVER_NAME": read, waiting\n");
 					break;
 				}
 				pd->iosched.writing = 1;
@@ -600,7 +602,7 @@
 		set_bit(PACKET_MERGE_SEGS, &pd->flags);
 		return 0;
 	} else {
-		printk("pktcdvd: cdrom max_phys_segments too small\n");
+		printk(DRIVER_NAME": cdrom max_phys_segments too small\n");
 		return -EIO;
 	}
 }
@@ -1049,7 +1051,7 @@
 	for (f = 0; f < pkt->frames; f++)
 		if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
 			BUG();
-	VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt);
+	VPRINTK(DRIVER_NAME": vcnt=%d\n", pkt->w_bio->bi_vcnt);
 
 	atomic_set(&pkt->io_wait, 1);
 	pkt->w_bio->bi_rw = WRITE;
@@ -1286,7 +1288,7 @@
 
 static void pkt_print_settings(struct pktcdvd_device *pd)
 {
-	printk("pktcdvd: %s packets, ", pd->settings.fp ? "Fixed" : "Variable");
+	printk(DRIVER_NAME": %s packets, ", pd->settings.fp ? "Fixed" : "Variable");
 	printk("%u blocks, ", pd->settings.size >> 2);
 	printk("Mode-%c disc\n", pd->settings.block_mode == 8 ? '1' : '2');
 }
@@ -1471,7 +1473,7 @@
 		/*
 		 * paranoia
 		 */
-		printk("pktcdvd: write mode wrong %d\n", wp->data_block_type);
+		printk(DRIVER_NAME": write mode wrong %d\n", wp->data_block_type);
 		return 1;
 	}
 	wp->packet_size = cpu_to_be32(pd->settings.size >> 2);
@@ -1515,7 +1517,7 @@
 	if (ti->rt == 1 && ti->blank == 0)
 		return 1;
 
-	printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet);
+	printk(DRIVER_NAME": bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet);
 	return 0;
 }
 
@@ -1533,7 +1535,7 @@
 		case 0x12: /* DVD-RAM */
 			return 1;
 		default:
-			VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile);
+			VPRINTK(DRIVER_NAME": Wrong disc profile (%x)\n", pd->mmc3_profile);
 			return 0;
 	}
 
@@ -1542,22 +1544,22 @@
 	 * but i'm not sure, should we leave this to user apps? probably.
 	 */
 	if (di->disc_type == 0xff) {
-		printk("pktcdvd: Unknown disc. No track?\n");
+		printk(DRIVER_NAME": Unknown disc. No track?\n");
 		return 0;
 	}
 
 	if (di->disc_type != 0x20 && di->disc_type != 0) {
-		printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type);
+		printk(DRIVER_NAME": Wrong disc type (%x)\n", di->disc_type);
 		return 0;
 	}
 
 	if (di->erasable == 0) {
-		printk("pktcdvd: Disc not erasable\n");
+		printk(DRIVER_NAME": Disc not erasable\n");
 		return 0;
 	}
 
 	if (di->border_status == PACKET_SESSION_RESERVED) {
-		printk("pktcdvd: Can't write to last track (reserved)\n");
+		printk(DRIVER_NAME": Can't write to last track (reserved)\n");
 		return 0;
 	}
 
@@ -1593,12 +1595,12 @@
 
 	track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */
 	if ((ret = pkt_get_track_info(pd, track, 1, &ti))) {
-		printk("pktcdvd: failed get_track\n");
+		printk(DRIVER_NAME": failed get_track\n");
 		return ret;
 	}
 
 	if (!pkt_writable_track(pd, &ti)) {
-		printk("pktcdvd: can't write to this track\n");
+		printk(DRIVER_NAME": can't write to this track\n");
 		return -EROFS;
 	}
 
@@ -1608,11 +1610,11 @@
 	 */
 	pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2;
 	if (pd->settings.size == 0) {
-		printk("pktcdvd: detected zero packet size!\n");
+		printk(DRIVER_NAME": detected zero packet size!\n");
 		return -ENXIO;
 	}
 	if (pd->settings.size > PACKET_MAX_SECTORS) {
-		printk("pktcdvd: packet size is too big\n");
+		printk(DRIVER_NAME": packet size is too big\n");
 		return -EROFS;
 	}
 	pd->settings.fp = ti.fp;
@@ -1654,7 +1656,7 @@
 			pd->settings.block_mode = PACKET_BLOCK_MODE2;
 			break;
 		default:
-			printk("pktcdvd: unknown data mode\n");
+			printk(DRIVER_NAME": unknown data mode\n");
 			return -EROFS;
 	}
 	return 0;
@@ -1688,10 +1690,10 @@
 	cgc.buflen = cgc.cmd[8] = 2 + ((buf[0] << 8) | (buf[1] & 0xff));
 	ret = pkt_mode_select(pd, &cgc);
 	if (ret) {
-		printk("pktcdvd: write caching control failed\n");
+		printk(DRIVER_NAME": write caching control failed\n");
 		pkt_dump_sense(&cgc);
 	} else if (!ret && set)
-		printk("pktcdvd: enabled write caching on %s\n", pd->name);
+		printk(DRIVER_NAME": enabled write caching on %s\n", pd->name);
 	return ret;
 }
 
@@ -1805,11 +1807,11 @@
 	}
 
 	if (!buf[6] & 0x40) {
-		printk("pktcdvd: Disc type is not CD-RW\n");
+		printk(DRIVER_NAME": Disc type is not CD-RW\n");
 		return 1;
 	}
 	if (!buf[6] & 0x4) {
-		printk("pktcdvd: A1 values on media are not valid, maybe not CDRW?\n");
+		printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n");
 		return 1;
 	}
 
@@ -1829,14 +1831,14 @@
 			*speed = us_clv_to_speed[sp];
 			break;
 		default:
-			printk("pktcdvd: Unknown disc sub-type %d\n",st);
+			printk(DRIVER_NAME": Unknown disc sub-type %d\n",st);
 			return 1;
 	}
 	if (*speed) {
-		printk("pktcdvd: Max. media speed: %d\n",*speed);
+		printk(DRIVER_NAME": Max. media speed: %d\n",*speed);
 		return 0;
 	} else {
-		printk("pktcdvd: Unknown speed %d for sub-type %d\n",sp,st);
+		printk(DRIVER_NAME": Unknown speed %d for sub-type %d\n",sp,st);
 		return 1;
 	}
 }
@@ -1847,7 +1849,7 @@
 	struct request_sense sense;
 	int ret;
 
-	VPRINTK("pktcdvd: Performing OPC\n");
+	VPRINTK(DRIVER_NAME": Performing OPC\n");
 
 	init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
 	cgc.sense = &sense;
@@ -1865,12 +1867,12 @@
 	unsigned int write_speed, media_write_speed, read_speed;
 
 	if ((ret = pkt_probe_settings(pd))) {
-		VPRINTK("pktcdvd: %s failed probe\n", pd->name);
+		VPRINTK(DRIVER_NAME": %s failed probe\n", pd->name);
 		return ret;
 	}
 
 	if ((ret = pkt_set_write_settings(pd))) {
-		DPRINTK("pktcdvd: %s failed saving write settings\n", pd->name);
+		DPRINTK(DRIVER_NAME": %s failed saving write settings\n", pd->name);
 		return -EIO;
 	}
 
@@ -1882,26 +1884,26 @@
 		case 0x13: /* DVD-RW */
 		case 0x1a: /* DVD+RW */
 		case 0x12: /* DVD-RAM */
-			DPRINTK("pktcdvd: write speed %ukB/s\n", write_speed);
+			DPRINTK(DRIVER_NAME": write speed %ukB/s\n", write_speed);
 			break;
 		default:
 			if ((ret = pkt_media_speed(pd, &media_write_speed)))
 				media_write_speed = 16;
 			write_speed = min(write_speed, media_write_speed * 177);
-			DPRINTK("pktcdvd: write speed %ux\n", write_speed / 176);
+			DPRINTK(DRIVER_NAME": write speed %ux\n", write_speed / 176);
 			break;
 	}
 	read_speed = write_speed;
 
 	if ((ret = pkt_set_speed(pd, write_speed, read_speed))) {
-		DPRINTK("pktcdvd: %s couldn't set write speed\n", pd->name);
+		DPRINTK(DRIVER_NAME": %s couldn't set write speed\n", pd->name);
 		return -EIO;
 	}
 	pd->write_speed = write_speed;
 	pd->read_speed = read_speed;
 
 	if ((ret = pkt_perform_opc(pd))) {
-		DPRINTK("pktcdvd: %s Optimum Power Calibration failed\n", pd->name);
+		DPRINTK(DRIVER_NAME": %s Optimum Power Calibration failed\n", pd->name);
 	}
 
 	return 0;
@@ -1929,7 +1931,7 @@
 		goto out_putdev;
 
 	if ((ret = pkt_get_last_written(pd, &lba))) {
-		printk("pktcdvd: pkt_get_last_written failed\n");
+		printk(DRIVER_NAME": pkt_get_last_written failed\n");
 		goto out_unclaim;
 	}
 
@@ -1959,11 +1961,11 @@
 
 	if (write) {
 		if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
-			printk("pktcdvd: not enough memory for buffers\n");
+			printk(DRIVER_NAME": not enough memory for buffers\n");
 			ret = -ENOMEM;
 			goto out_unclaim;
 		}
-		printk("pktcdvd: %lukB available on disc\n", lba << 1);
+		printk(DRIVER_NAME": %lukB available on disc\n", lba << 1);
 	}
 
 	return 0;
@@ -1983,7 +1985,7 @@
 static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
 {
 	if (flush && pkt_flush_cache(pd))
-		DPRINTK("pktcdvd: %s not flushing cache\n", pd->name);
+		DPRINTK(DRIVER_NAME": %s not flushing cache\n", pd->name);
 
 	pkt_lock_door(pd, 0);
 
@@ -2006,7 +2008,7 @@
 	struct pktcdvd_device *pd = NULL;
 	int ret;
 
-	VPRINTK("pktcdvd: entering open\n");
+	VPRINTK(DRIVER_NAME": entering open\n");
 
 	mutex_lock(&ctl_mutex);
 	pd = pkt_find_dev_from_minor(iminor(inode));
@@ -2040,7 +2042,7 @@
 out_dec:
 	pd->refcnt--;
 out:
-	VPRINTK("pktcdvd: failed open (%d)\n", ret);
+	VPRINTK(DRIVER_NAME": failed open (%d)\n", ret);
 	mutex_unlock(&ctl_mutex);
 	return ret;
 }
@@ -2088,7 +2090,7 @@
 
 	pd = q->queuedata;
 	if (!pd) {
-		printk("pktcdvd: %s incorrect request queue\n", bdevname(bio->bi_bdev, b));
+		printk(DRIVER_NAME": %s incorrect request queue\n", bdevname(bio->bi_bdev, b));
 		goto end_io;
 	}
 
@@ -2110,13 +2112,13 @@
 	}
 
 	if (!test_bit(PACKET_WRITABLE, &pd->flags)) {
-		printk("pktcdvd: WRITE for ro device %s (%llu)\n",
+		printk(DRIVER_NAME": WRITE for ro device %s (%llu)\n",
 			pd->name, (unsigned long long)bio->bi_sector);
 		goto end_io;
 	}
 
 	if (!bio->bi_size || (bio->bi_size % CD_FRAMESIZE)) {
-		printk("pktcdvd: wrong bio size\n");
+		printk(DRIVER_NAME": wrong bio size\n");
 		goto end_io;
 	}
 
@@ -2319,7 +2321,7 @@
 	struct block_device *bdev;
 
 	if (pd->pkt_dev == dev) {
-		printk("pktcdvd: Recursive setup not allowed\n");
+		printk(DRIVER_NAME": Recursive setup not allowed\n");
 		return -EBUSY;
 	}
 	for (i = 0; i < MAX_WRITERS; i++) {
@@ -2327,11 +2329,11 @@
 		if (!pd2)
 			continue;
 		if (pd2->bdev->bd_dev == dev) {
-			printk("pktcdvd: %s already setup\n", bdevname(pd2->bdev, b));
+			printk(DRIVER_NAME": %s already setup\n", bdevname(pd2->bdev, b));
 			return -EBUSY;
 		}
 		if (pd2->pkt_dev == dev) {
-			printk("pktcdvd: Can't chain pktcdvd devices\n");
+			printk(DRIVER_NAME": Can't chain pktcdvd devices\n");
 			return -EBUSY;
 		}
 	}
@@ -2354,7 +2356,7 @@
 	atomic_set(&pd->cdrw.pending_bios, 0);
 	pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s", pd->name);
 	if (IS_ERR(pd->cdrw.thread)) {
-		printk("pktcdvd: can't start kernel thread\n");
+		printk(DRIVER_NAME": can't start kernel thread\n");
 		ret = -ENOMEM;
 		goto out_mem;
 	}
@@ -2364,7 +2366,7 @@
 		proc->data = pd;
 		proc->proc_fops = &pkt_proc_fops;
 	}
-	DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
+	DPRINTK(DRIVER_NAME": writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
 	return 0;
 
 out_mem:
@@ -2401,7 +2403,7 @@
 		return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
 
 	default:
-		VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd);
+		VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
 		return -ENOTTY;
 	}
 
@@ -2446,7 +2448,7 @@
 		if (!pkt_devs[idx])
 			break;
 	if (idx == MAX_WRITERS) {
-		printk("pktcdvd: max %d writers supported\n", MAX_WRITERS);
+		printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS);
 		return -EBUSY;
 	}
 
@@ -2470,15 +2472,15 @@
 
 	spin_lock_init(&pd->lock);
 	spin_lock_init(&pd->iosched.lock);
-	sprintf(pd->name, "pktcdvd%d", idx);
+	sprintf(pd->name, DRIVER_NAME"%d", idx);
 	init_waitqueue_head(&pd->wqueue);
 	pd->bio_queue = RB_ROOT;
 
-	disk->major = pkt_major;
+	disk->major = pktdev_major;
 	disk->first_minor = idx;
 	disk->fops = &pktcdvd_ops;
 	disk->flags = GENHD_FL_REMOVABLE;
-	sprintf(disk->disk_name, "pktcdvd%d", idx);
+	sprintf(disk->disk_name, DRIVER_NAME"%d", idx);
 	disk->private_data = pd;
 	disk->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!disk->queue)
@@ -2520,7 +2522,7 @@
 			break;
 	}
 	if (idx == MAX_WRITERS) {
-		DPRINTK("pktcdvd: dev not setup\n");
+		DPRINTK(DRIVER_NAME": dev not setup\n");
 		return -ENXIO;
 	}
 
@@ -2533,7 +2535,7 @@
 	blkdev_put(pd->bdev);
 
 	remove_proc_entry(pd->name, pkt_proc);
-	DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);
+	DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name);
 
 	del_gendisk(pd->disk);
 	blk_cleanup_queue(pd->disk->queue);
@@ -2610,7 +2612,7 @@
 
 static struct miscdevice pkt_misc = {
 	.minor 		= MISC_DYNAMIC_MINOR,
-	.name  		= "pktcdvd",
+	.name  		= DRIVER_NAME,
 	.fops  		= &pkt_ctl_fops
 };
 
@@ -2623,28 +2625,28 @@
 	if (!psd_pool)
 		return -ENOMEM;
 
-	ret = register_blkdev(pkt_major, "pktcdvd");
+	ret = register_blkdev(pktdev_major, DRIVER_NAME);
 	if (ret < 0) {
-		printk("pktcdvd: Unable to register block device\n");
+		printk(DRIVER_NAME": Unable to register block device\n");
 		goto out2;
 	}
-	if (!pkt_major)
-		pkt_major = ret;
+	if (!pktdev_major)
+		pktdev_major = ret;
 
 	ret = misc_register(&pkt_misc);
 	if (ret) {
-		printk("pktcdvd: Unable to register misc device\n");
+		printk(DRIVER_NAME": Unable to register misc device\n");
 		goto out;
 	}
 
 	mutex_init(&ctl_mutex);
 
-	pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
+	pkt_proc = proc_mkdir(DRIVER_NAME, proc_root_driver);
 
 	return 0;
 
 out:
-	unregister_blkdev(pkt_major, "pktcdvd");
+	unregister_blkdev(pktdev_major, DRIVER_NAME);
 out2:
 	mempool_destroy(psd_pool);
 	return ret;
@@ -2652,9 +2654,9 @@
 
 static void __exit pkt_exit(void)
 {
-	remove_proc_entry("pktcdvd", proc_root_driver);
+	remove_proc_entry(DRIVER_NAME, proc_root_driver);
 	misc_deregister(&pkt_misc);
-	unregister_blkdev(pkt_major, "pktcdvd");
+	unregister_blkdev(pktdev_major, DRIVER_NAME);
 	mempool_destroy(psd_pool);
 }
 
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index f2305ee..fdc8f89 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -636,7 +636,7 @@
 	intr = in_8(&sw->intr);
 	err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
 	if ((intr & ERROR_INTR) && fs->state != do_transfer)
-		printk(KERN_ERR "swim3_interrupt, state=%d, dir=%lx, intr=%x, err=%x\n",
+		printk(KERN_ERR "swim3_interrupt, state=%d, dir=%x, intr=%x, err=%x\n",
 		       fs->state, rq_data_dir(fd_req), intr, err);
 	switch (fs->state) {
 	case locating:
@@ -742,7 +742,7 @@
 			if ((stat & ACTIVE) == 0 || resid != 0) {
 				/* musta been an error */
 				printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid);
-				printk(KERN_ERR "  state=%d, dir=%lx, intr=%x, err=%x\n",
+				printk(KERN_ERR "  state=%d, dir=%x, intr=%x, err=%x\n",
 				       fs->state, rq_data_dir(fd_req), intr, err);
 				end_request(fd_req, 0);
 				fs->state = idle;
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 5d8925b..cbb9d0f 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -552,7 +552,8 @@
 static int mm_make_request(request_queue_t *q, struct bio *bio)
 {
 	struct cardinfo *card = q->queuedata;
-	pr_debug("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size);
+	pr_debug("mm_make_request %llu %u\n",
+		 (unsigned long long)bio->bi_sector, bio->bi_size);
 
 	bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/
 	spin_lock_irq(&card->lock);
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index b38c84a..2a0c50d 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1,4 +1,4 @@
-/* linux/drivers/cdrom/cdrom.c. 
+/* linux/drivers/cdrom/cdrom.c
    Copyright (c) 1996, 1997 David A. van Leeuwen.
    Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
    Copyright (c) 1998, 1999 Jens Axboe <axboe@image.dk>
diff --git a/drivers/char/.gitignore b/drivers/char/.gitignore
index 73dfdce..83683a2 100644
--- a/drivers/char/.gitignore
+++ b/drivers/char/.gitignore
@@ -1,3 +1,2 @@
 consolemap_deftbl.c
 defkeymap.c
-qtronixmap.c
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index bde1c66..0e6f35f 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -371,36 +371,6 @@
 	  If you have an Alchemy AU1000 processor (MIPS based) and you want
 	  to use a console on a serial port, say Y.  Otherwise, say N.
 
-config QTRONIX_KEYBOARD
-	bool "Enable Qtronix 990P Keyboard Support"
-	depends on IT8712
-	help
-	  Images of Qtronix keyboards are at
-	  <http://www.qtronix.com/keyboard.html>.
-
-config IT8172_CIR
-	bool
-	depends on QTRONIX_KEYBOARD
-	default y
-
-config IT8172_SCR0
-	bool "Enable Smart Card Reader 0 Support "
-	depends on IT8712
-	help
-	  Say Y here to support smart-card reader 0 (SCR0) on the Integrated
-	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
-	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
-
-config IT8172_SCR1
-	bool "Enable Smart Card Reader 1 Support "
-	depends on IT8712
-	help
-	  Say Y here to support smart-card reader 1 (SCR1) on the Integrated
-	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
-	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
-
 config A2232
 	tristate "Commodore A2232 serial support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 19114df..777cad0 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -102,7 +102,7 @@
 obj-$(CONFIG_TCG_TPM)		+= tpm/
 
 # Files generated that shall be removed upon make clean
-clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
+clean-files := consolemap_deftbl.c defkeymap.c
 
 quiet_cmd_conmk = CONMK   $@
       cmd_conmk = scripts/conmakehash $< > $@
@@ -112,8 +112,6 @@
 
 $(obj)/defkeymap.o:  $(obj)/defkeymap.c
 
-$(obj)/qtronixmap.o: $(obj)/qtronixmap.c
-
 # Uncomment if you're changing the keymap and have an appropriate
 # loadkeys version for the map. By default, we'll use the shipped
 # versions.
@@ -121,7 +119,7 @@
 
 ifdef GENERATE_KEYMAP
 
-$(obj)/defkeymap.c $(obj)/qtronixmap.c: $(obj)/%.c: $(src)/%.map
+$(obj)/defkeymap.c $(obj)/%.c: $(src)/%.map
 	loadkeys --mktable $< > $@.tmp
 	sed -e 's/^static *//' $@.tmp > $@
 	rm $@.tmp
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 22f8cf2..c603bf2 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,6 +1,6 @@
 config AGP
 	tristate "/dev/agpgart (AGP Support)"
-	depends on ALPHA || IA64 || PPC || X86
+	depends on ALPHA || IA64 || PARISC || PPC || X86
 	depends on PCI
 	---help---
 	  AGP (Accelerated Graphics Port) is a bus system mainly used to
@@ -122,6 +122,14 @@
 	  This option gives you AGP GART support for the HP ZX1 chipset
 	  for IA64 processors.
 
+config AGP_PARISC
+	tristate "HP Quicksilver AGP support"
+	depends on AGP && PARISC && 64BIT
+	help
+	  This option gives you AGP GART support for the HP Quicksilver
+	  AGP bus adapter on HP PA-RISC machines (Ok, just on the C8000
+	  workstation...)
+
 config AGP_ALPHA_CORE
 	tristate "Alpha AGP support"
 	depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL)
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
index d33a22f..3e58160 100644
--- a/drivers/char/agp/Makefile
+++ b/drivers/char/agp/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_AGP_ALPHA_CORE)	+= alpha-agp.o
 obj-$(CONFIG_AGP_EFFICEON)	+= efficeon-agp.o
 obj-$(CONFIG_AGP_HP_ZX1)	+= hp-agp.o
+obj-$(CONFIG_AGP_PARISC)	+= parisc-agp.o
 obj-$(CONFIG_AGP_I460)		+= i460-agp.o
 obj-$(CONFIG_AGP_INTEL)		+= intel-agp.o
 obj-$(CONFIG_AGP_NVIDIA)	+= nvidia-agp.o
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
new file mode 100644
index 0000000..17c50b0
--- /dev/null
+++ b/drivers/char/agp/parisc-agp.c
@@ -0,0 +1,416 @@
+/*
+ * HP Quicksilver AGP GART routines
+ *
+ * Copyright (c) 2006, Kyle McMartin <kyle@parisc-linux.org>
+ *
+ * Based on drivers/char/agpgart/hp-agp.c which is
+ * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/klist.h>
+#include <linux/agp_backend.h>
+
+#include <asm-parisc/parisc-device.h>
+#include <asm-parisc/ropes.h>
+
+#include "agp.h"
+
+#define DRVNAME	"quicksilver"
+#define DRVPFX	DRVNAME ": "
+
+#ifndef log2
+#define log2(x)		ffz(~(x))
+#endif
+
+#define AGP8X_MODE_BIT		3
+#define AGP8X_MODE		(1 << AGP8X_MODE_BIT)
+
+static struct _parisc_agp_info {
+	void __iomem *ioc_regs;
+	void __iomem *lba_regs;
+
+	int lba_cap_offset;
+
+	u64 *gatt;
+	u64 gatt_entries;
+
+	u64 gart_base;
+	u64 gart_size;
+
+	int io_page_size;
+	int io_pages_per_kpage;
+} parisc_agp_info;
+
+static struct gatt_mask parisc_agp_masks[] =
+{
+        {
+		.mask = SBA_PDIR_VALID_BIT,
+		.type = 0
+	}
+};
+
+static struct aper_size_info_fixed parisc_agp_sizes[] =
+{
+        {0, 0, 0},              /* filled in by parisc_agp_fetch_size() */
+};
+
+static int
+parisc_agp_fetch_size(void)
+{
+	int size;
+
+	size = parisc_agp_info.gart_size / MB(1);
+	parisc_agp_sizes[0].size = size;
+	agp_bridge->current_size = (void *) &parisc_agp_sizes[0];
+
+	return size;
+}
+
+static int
+parisc_agp_configure(void)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+
+	agp_bridge->gart_bus_addr = info->gart_base;
+	agp_bridge->capndx = info->lba_cap_offset;
+	agp_bridge->mode = readl(info->lba_regs+info->lba_cap_offset+PCI_AGP_STATUS);
+
+	return 0;
+}
+
+static void
+parisc_agp_tlbflush(struct agp_memory *mem)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+
+	writeq(info->gart_base | log2(info->gart_size), info->ioc_regs+IOC_PCOM);
+	readq(info->ioc_regs+IOC_PCOM);	/* flush */
+}
+
+static int
+parisc_agp_create_gatt_table(struct agp_bridge_data *bridge)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+	int i;
+
+	for (i = 0; i < info->gatt_entries; i++) {
+		info->gatt[i] = (unsigned long)agp_bridge->scratch_page;
+	}
+
+	return 0;
+}
+
+static int
+parisc_agp_free_gatt_table(struct agp_bridge_data *bridge)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+
+	info->gatt[0] = SBA_AGPGART_COOKIE;
+
+	return 0;
+}
+
+static int
+parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+	int i, k;
+	off_t j, io_pg_start;
+	int io_pg_count;
+
+	if (type != 0 || mem->type != 0) {
+		return -EINVAL;
+	}
+
+	io_pg_start = info->io_pages_per_kpage * pg_start;
+	io_pg_count = info->io_pages_per_kpage * mem->page_count;
+	if ((io_pg_start + io_pg_count) > info->gatt_entries) {
+		return -EINVAL;
+	}
+
+	j = io_pg_start;
+	while (j < (io_pg_start + io_pg_count)) {
+		if (info->gatt[j])
+			return -EBUSY;
+		j++;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		global_cache_flush();
+		mem->is_flushed = TRUE;
+	}
+
+	for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
+		unsigned long paddr;
+
+		paddr = mem->memory[i];
+		for (k = 0;
+		     k < info->io_pages_per_kpage;
+		     k++, j++, paddr += info->io_page_size) {
+			info->gatt[j] =
+				agp_bridge->driver->mask_memory(agp_bridge,
+					paddr, type);
+		}
+	}
+
+	agp_bridge->driver->tlb_flush(mem);
+
+	return 0;
+}
+
+static int
+parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+	int i, io_pg_start, io_pg_count;
+
+	if (type != 0 || mem->type != 0) {
+		return -EINVAL;
+	}
+
+	io_pg_start = info->io_pages_per_kpage * pg_start;
+	io_pg_count = info->io_pages_per_kpage * mem->page_count;
+	for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
+		info->gatt[i] = agp_bridge->scratch_page;
+	}
+
+	agp_bridge->driver->tlb_flush(mem);
+	return 0;
+}
+
+static unsigned long
+parisc_agp_mask_memory(struct agp_bridge_data *bridge,
+		    unsigned long addr, int type)
+{
+	return SBA_PDIR_VALID_BIT | addr;
+}
+
+static void
+parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+	u32 command;
+
+	command = readl(info->lba_regs + info->lba_cap_offset + PCI_AGP_STATUS);
+
+	command = agp_collect_device_status(bridge, mode, command);
+	command |= 0x00000100;
+
+	writel(command, info->lba_regs + info->lba_cap_offset + PCI_AGP_COMMAND);
+
+	agp_device_command(command, (mode & AGP8X_MODE) != 0);
+}
+
+struct agp_bridge_driver parisc_agp_driver = {
+	.owner			= THIS_MODULE,
+	.size_type		= FIXED_APER_SIZE,
+	.configure		= parisc_agp_configure,
+	.fetch_size		= parisc_agp_fetch_size,
+	.tlb_flush		= parisc_agp_tlbflush,
+	.mask_memory		= parisc_agp_mask_memory,
+	.masks			= parisc_agp_masks,
+	.agp_enable		= parisc_agp_enable,
+	.cache_flush		= global_cache_flush,
+	.create_gatt_table	= parisc_agp_create_gatt_table,
+	.free_gatt_table	= parisc_agp_free_gatt_table,
+	.insert_memory		= parisc_agp_insert_memory,
+	.remove_memory		= parisc_agp_remove_memory,
+	.alloc_by_type		= agp_generic_alloc_by_type,
+	.free_by_type		= agp_generic_free_by_type,
+	.agp_alloc_page		= agp_generic_alloc_page,
+	.agp_destroy_page	= agp_generic_destroy_page,
+	.cant_use_aperture	= 1,
+};
+
+static int __init
+agp_ioc_init(void __iomem *ioc_regs)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+        u64 *iova_base, *io_pdir, io_tlb_ps;
+        int io_tlb_shift;
+
+        printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n");
+
+        info->ioc_regs = ioc_regs;
+
+        io_tlb_ps = readq(info->ioc_regs+IOC_TCNFG);
+        switch (io_tlb_ps) {
+        case 0: io_tlb_shift = 12; break;
+        case 1: io_tlb_shift = 13; break;
+        case 2: io_tlb_shift = 14; break;
+        case 3: io_tlb_shift = 16; break;
+        default:
+                printk(KERN_ERR DRVPFX "Invalid IOTLB page size "
+                       "configuration 0x%llx\n", io_tlb_ps);
+                info->gatt = NULL;
+                info->gatt_entries = 0;
+                return -ENODEV;
+        }
+        info->io_page_size = 1 << io_tlb_shift;
+        info->io_pages_per_kpage = PAGE_SIZE / info->io_page_size;
+
+        iova_base = readq(info->ioc_regs+IOC_IBASE) & ~0x1;
+        info->gart_base = iova_base + PLUTO_IOVA_SIZE - PLUTO_GART_SIZE;
+
+        info->gart_size = PLUTO_GART_SIZE;
+        info->gatt_entries = info->gart_size / info->io_page_size;
+
+        io_pdir = phys_to_virt(readq(info->ioc_regs+IOC_PDIR_BASE));
+        info->gatt = &io_pdir[(PLUTO_IOVA_SIZE/2) >> PAGE_SHIFT];
+
+        if (info->gatt[0] != SBA_AGPGART_COOKIE) {
+                info->gatt = NULL;
+                info->gatt_entries = 0;
+                printk(KERN_ERR DRVPFX "No reserved IO PDIR entry found; "
+                       "GART disabled\n");
+                return -ENODEV;
+        }
+
+        return 0;
+}
+
+static int
+lba_find_capability(int cap)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+        u16 status;
+        u8 pos, id;
+        int ttl = 48;
+
+        status = readw(info->lba_regs + PCI_STATUS);
+        if (!(status & PCI_STATUS_CAP_LIST))
+                return 0;
+        pos = readb(info->lba_regs + PCI_CAPABILITY_LIST);
+        while (ttl-- && pos >= 0x40) {
+                pos &= ~3;
+                id = readb(info->lba_regs + pos + PCI_CAP_LIST_ID);
+                if (id == 0xff)
+                        break;
+                if (id == cap)
+                        return pos;
+                pos = readb(info->lba_regs + pos + PCI_CAP_LIST_NEXT);
+        }
+        return 0;
+}
+
+static int __init
+agp_lba_init(void __iomem *lba_hpa)
+{
+	struct _parisc_agp_info *info = &parisc_agp_info;
+        int cap;
+
+	info->lba_regs = lba_hpa;
+        info->lba_cap_offset = lba_find_capability(PCI_CAP_ID_AGP);
+
+        cap = readl(lba_hpa + info->lba_cap_offset) & 0xff;
+        if (cap != PCI_CAP_ID_AGP) {
+                printk(KERN_ERR DRVPFX "Invalid capability ID 0x%02x at 0x%x\n",
+                       cap, info->lba_cap_offset);
+                return -ENODEV;
+        }
+
+        return 0;
+}
+
+static int __init
+parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
+{
+	struct pci_dev *fake_bridge_dev = NULL;
+	struct agp_bridge_data *bridge;
+	int error = 0;
+
+	fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
+	if (!fake_bridge_dev) {
+		error = -ENOMEM;
+		goto fail;
+	}
+
+	error = agp_ioc_init(ioc_hpa);
+	if (error)
+		goto fail;
+
+	error = agp_lba_init(lba_hpa);
+	if (error)
+		goto fail;
+
+	bridge = agp_alloc_bridge();
+	if (!bridge) {
+		error = -ENOMEM;
+		goto fail;
+	}
+	bridge->driver = &parisc_agp_driver;
+
+	fake_bridge_dev->vendor = PCI_VENDOR_ID_HP;
+	fake_bridge_dev->device = PCI_DEVICE_ID_HP_PCIX_LBA;
+	bridge->dev = fake_bridge_dev;
+
+	error = agp_add_bridge(bridge);
+
+fail:
+	return error;
+}
+
+static struct device *next_device(struct klist_iter *i) {
+	struct klist_node * n = klist_next(i);
+	return n ? container_of(n, struct device, knode_parent) : NULL;
+}
+
+static int
+parisc_agp_init(void)
+{
+	extern struct sba_device *sba_list;
+
+	int err = -1;
+	struct parisc_device *sba = NULL, *lba = NULL;
+	struct lba_device *lbadev = NULL;
+	struct device *dev = NULL;
+	struct klist_iter i;
+
+	if (!sba_list)
+		goto out;
+
+	/* Find our parent Pluto */
+	sba = sba_list->dev;
+	if (!IS_PLUTO(sba)) {
+		printk(KERN_INFO DRVPFX "No Pluto found, so no AGPGART for you.\n");
+		goto out;
+	}
+
+	/* Now search our Pluto for our precious AGP device... */
+	klist_iter_init(&sba->dev.klist_children, &i);
+	while ((dev = next_device(&i))) {
+		struct parisc_device *padev = to_parisc_device(dev);
+		if (IS_QUICKSILVER(padev))
+			lba = padev;
+	}
+	klist_iter_exit(&i);
+
+	if (!lba) {
+		printk(KERN_INFO DRVPFX "No AGP devices found.\n");
+		goto out;
+	}
+
+	lbadev = parisc_get_drvdata(lba);
+
+	/* w00t, let's go find our cookies... */
+	parisc_agp_setup(sba_list->ioc[0].ioc_hpa, lbadev->hba.base_addr);
+
+	return 0;
+
+out:
+	return err;
+}
+
+module_init(parisc_agp_init);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 9d6713a..486f97c 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -112,17 +112,6 @@
 
 #define NR_PORTS ARRAY_SIZE(rs_table)
 
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-
 #include <asm/uaccess.h>
 
 #define serial_isroot()	(capable(CAP_SYS_ADMIN))
@@ -912,7 +901,7 @@
 	if (serial_paranoia_check(info, tty->name, "rs_write"))
 		return 0;
 
-	if (!info->xmit.buf || !tmp_buf)
+	if (!info->xmit.buf)
 		return 0;
 
 	local_save_flags(flags);
@@ -1778,7 +1767,6 @@
 {
 	struct async_struct	*info;
 	int 			retval, line;
-	unsigned long		page;
 
 	line = tty->index;
 	if ((line < 0) || (line >= NR_PORTS)) {
@@ -1798,17 +1786,6 @@
 #endif
 	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
-	if (!tmp_buf) {
-		page = get_zeroed_page(GFP_KERNEL);
-		if (!page) {
-			return -ENOMEM;
-		}
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
 	/*
 	 * If the port is the middle of closing, bail out now
 	 */
@@ -1958,7 +1935,7 @@
 }
 
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
@@ -2090,11 +2067,6 @@
 	  kfree(info);
 	}
 
-	if (tmp_buf) {
-		free_page((unsigned long) tmp_buf);
-		tmp_buf = NULL;
-	}
-
 	release_mem_region(CUSTOM_PHYSADDR+0x30, 4);
 }
 
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index c1c6728..87b2fb5 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -748,18 +748,6 @@
 static int cy_next_channel; /* next minor available */
 
 /*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.  This buffer is
- * allocated when the first cy_open occurs.
- */
-static unsigned char *tmp_buf;
-
-/*
  * This is used to look up the divisor speeds and the timeouts
  * We're normally limited to 15 distinct baud rates.  The extra
  * are accessed via settings in info->flags.
@@ -2466,7 +2454,6 @@
 {
   struct cyclades_port  *info;
   int retval, line;
-  unsigned long page;
 
     line = tty->index;
     if ((line < 0) || (NR_PORTS <= line)){
@@ -2545,15 +2532,6 @@
     printk("cyc:cy_open (%d): incrementing count to %d\n",
         current->pid, info->count);
 #endif
-    if (!tmp_buf) {
-	page = get_zeroed_page(GFP_KERNEL);
-	if (!page)
-	    return -ENOMEM;
-	if (tmp_buf)
-	    free_page(page);
-	else
-	    tmp_buf = (unsigned char *) page;
-    }
 
     /*
      * If the port is the middle of closing, bail out now
@@ -2832,7 +2810,7 @@
         return 0;
     }
         
-    if (!info->xmit_buf || !tmp_buf)
+    if (!info->xmit_buf)
 	return 0;
 
     CY_LOCK(info, flags);
@@ -5205,7 +5183,7 @@
     extra ports are ignored.
  */
 
-static struct tty_operations cy_ops = {
+static const struct tty_operations cy_ops = {
     .open = cy_open,
     .close = cy_close,
     .write = cy_write,
@@ -5490,10 +5468,6 @@
 #endif
         }
     }
-    if (tmp_buf) {
-	free_page((unsigned long) tmp_buf);
-	tmp_buf = NULL;
-    }
 } /* cy_cleanup_module */
 
 module_init(cy_init);
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 86d290e..c3f9558 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -1113,11 +1113,8 @@
 		ch = card_ptr[crd];
 		for (count = 0; count < bd->numports; count++, ch++) 
 		{ /* Begin for each port */
-			if (ch) {
-				if (ch->tty)
-					tty_hangup(ch->tty);
-				kfree(ch->tmp_buf);
-			}
+			if (ch && ch->tty)
+				tty_hangup(ch->tty);
 		} /* End for each port */
 	} /* End for each card */
 	pci_unregister_driver (&epca_driver);
@@ -1125,7 +1122,7 @@
 
 module_exit(epca_module_exit);
 
-static struct tty_operations pc_ops = {
+static const struct tty_operations pc_ops = {
 	.open = pc_open,
 	.close = pc_close,
 	.write = pc_write,
@@ -1635,16 +1632,6 @@
 		init_waitqueue_head(&ch->close_wait);
 
 		spin_unlock_irqrestore(&epca_lock, flags);
-
-		ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
-		if (!ch->tmp_buf) {
-			printk(KERN_ERR "POST FEP INIT : kmalloc failed for port 0x%x\n",i);
-			release_region((int)bd->port, 4);
-			while(i-- > 0)
-				kfree((ch--)->tmp_buf);
-			return;
-		} else
-			memset((void *)ch->tmp_buf,0,ch->txbufsize);
 	} /* End for each port */
 
 	printk(KERN_INFO 
diff --git a/drivers/char/epca.h b/drivers/char/epca.h
index 456d6c8..a297238 100644
--- a/drivers/char/epca.h
+++ b/drivers/char/epca.h
@@ -130,7 +130,6 @@
 	unsigned long  c_oflag;
 	unsigned char __iomem *txptr;
 	unsigned char __iomem *rxptr;
-	unsigned char *tmp_buf;
 	struct board_info           *board;
 	struct board_chan	    __iomem *brdchan;
 	struct digi_struct          digiext;
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index afcd83d..05788c7 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -2376,7 +2376,7 @@
 	return (port_detected);
 }
 
-static struct tty_operations esp_ops = {
+static const struct tty_operations esp_ops = {
 	.open = esp_open,
 	.close = rs_close,
 	.write = rs_write,
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 4711d9b..87127e4 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -33,8 +33,6 @@
 
 #define DEBUG 
 
-static char *                  tmp_buf; 
-
 static int gs_debug;
 
 #ifdef DEBUG
@@ -205,7 +203,7 @@
 	if (!tty) return -EIO;
 
 	port = tty->driver_data;
-	if (!port || !port->xmit_buf || !tmp_buf)
+	if (!port || !port->xmit_buf)
 		return -EIO;
 
 	local_save_flags(flags);
@@ -837,24 +835,9 @@
 int gs_init_port(struct gs_port *port)
 {
 	unsigned long flags;
-	unsigned long page;
 
 	func_enter ();
 
-        if (!tmp_buf) {
-		page = get_zeroed_page(GFP_KERNEL);
-		spin_lock_irqsave (&port->driver_lock, flags); /* Don't expect this to make a difference. */
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-		spin_unlock_irqrestore (&port->driver_lock, flags);
-		if (!tmp_buf) {
-			func_exit ();
-			return -ENOMEM;
-		}
-	}
-
 	if (port->flags & ASYNC_INITIALIZED) {
 		func_exit ();
 		return 0;
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index a76d2c4..4053d1c 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -696,7 +696,7 @@
 	return 0;
 }
 
-static struct tty_operations hvc_ops = {
+static const struct tty_operations hvc_ops = {
 	.open = hvc_open,
 	.close = hvc_close,
 	.write = hvc_write,
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
index 4747729..f144a94 100644
--- a/drivers/char/hvc_iseries.c
+++ b/drivers/char/hvc_iseries.c
@@ -29,6 +29,7 @@
 #include <asm/hvconsole.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
+#include <asm/firmware.h>
 #include <asm/iseries/vio.h>
 #include <asm/iseries/hv_call.h>
 #include <asm/iseries/hv_lp_config.h>
@@ -153,9 +154,7 @@
 	spin_lock_irqsave(&consolelock, flags);
 
 	if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) {
-		spin_lock_irqsave(&consoleloglock, flags);
 		HvCall_writeLogBuffer(buf, count);
-		spin_unlock_irqrestore(&consoleloglock, flags);
 		sent = count;
 		goto done;
 	}
@@ -171,11 +170,8 @@
 
 		len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count;
 
-		if (viochar_is_console(pi)) {
-			spin_lock_irqsave(&consoleloglock, flags);
+		if (viochar_is_console(pi))
 			HvCall_writeLogBuffer(buf, len);
-			spin_unlock_irqrestore(&consoleloglock, flags);
-		}
 
 		init_data_event(viochar, pi->lp);
 
@@ -493,6 +489,9 @@
 	atomic_t wait_flag;
 	int rc;
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -EIO;
+
 	/* +2 for fudge */
 	rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
 			viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
@@ -567,7 +566,7 @@
 
 	for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
 			vty = of_find_node_by_name(vty, "vty")) {
-		uint32_t *vtermno;
+		const uint32_t *vtermno;
 
 		/* We have statically defined space for only a certain number
 		 * of console adapters.
@@ -576,7 +575,7 @@
 				(num_found >= VTTY_PORTS))
 			break;
 
-		vtermno = (uint32_t *)get_property(vty, "reg", NULL);
+		vtermno = get_property(vty, "reg", NULL);
 		if (!vtermno)
 			continue;
 
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index cc95941..f9c0084 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -35,6 +35,7 @@
 #include <asm/hvconsole.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
+#include <asm/firmware.h>
 
 #include "hvc_console.h"
 
@@ -120,6 +121,9 @@
 {
 	int rc;
 
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return -EIO;
+
 	/* Register as a vio device to receive callbacks */
 	rc = vio_register_driver(&hvc_vio_driver);
 
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 4589ff3..0b89bcd 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -1306,7 +1306,7 @@
 	return hvcsd->chars_in_buffer;
 }
 
-static struct tty_operations hvcs_ops = {
+static const struct tty_operations hvcs_ops = {
 	.open = hvcs_open,
 	.close = hvcs_close,
 	.hangup = hvcs_hangup,
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index a89a95f..c07dc58 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1130,7 +1130,7 @@
 }
 
 
-static struct tty_operations hvsi_ops = {
+static const struct tty_operations hvsi_ops = {
 	.open = hvsi_open,
 	.close = hvsi_close,
 	.write = hvsi_write,
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c
index ef71022..3cf4d64 100644
--- a/drivers/char/hw_random/ixp4xx-rng.c
+++ b/drivers/char/hw_random/ixp4xx-rng.c
@@ -1,5 +1,5 @@
 /*
- * drivers/char/rng/ixp4xx-rng.c
+ * drivers/char/hw_random/ixp4xx-rng.c
  *
  * RNG driver for Intel IXP4xx family of NPUs
  *
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index a01d796..e13dd18 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -1,5 +1,5 @@
 /*
- * driver/char/hw_random/omap-rng.c
+ * drivers/char/hw_random/omap-rng.c
  *
  * RNG driver for TI OMAP CPU family
  *
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 331f447..62ef511 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -458,7 +458,7 @@
 }
 #endif /* MODULE */
 
-static struct tty_operations ip2_ops = {
+static const struct tty_operations ip2_ops = {
 	.open            = ip2_open,
 	.close           = ip2_close,
 	.write           = ip2_write,
@@ -779,8 +779,6 @@
 	ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
 	goto out;
 
-out_class:
-	class_destroy(ip2_class);
 out_chrdev:
 	unregister_chrdev(IP2_IPL_MAJOR, "ip2");
 out:
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 908521e..b106c45 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -217,6 +217,11 @@
 	struct list_head link;
 };
 
+#define SI_MAX_PARMS 4
+
+static int force_kipmid[SI_MAX_PARMS];
+static int num_force_kipmid;
+
 static int try_smi_init(struct smi_info *smi);
 
 static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
@@ -908,6 +913,7 @@
 				ipmi_smi_t intf)
 {
 	struct smi_info *new_smi = send_info;
+	int             enable = 0;
 
 	new_smi->intf = intf;
 
@@ -917,10 +923,18 @@
 	mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
 
 	/*
+	 * Check if the user forcefully enabled the daemon.
+	 */
+	if (new_smi->intf_num < num_force_kipmid)
+		enable = force_kipmid[new_smi->intf_num];
+	/*
 	 * The BT interface is efficient enough to not need a thread,
 	 * and there is no need for a thread if we have interrupts.
 	 */
- 	if ((new_smi->si_type != SI_BT) && (!new_smi->irq)) {
+ 	else if ((new_smi->si_type != SI_BT) && (!new_smi->irq))
+		enable = 1;
+
+	if (enable) {
 		new_smi->thread = kthread_run(ipmi_thread, new_smi,
 					      "kipmi%d", new_smi->intf_num);
 		if (IS_ERR(new_smi->thread)) {
@@ -948,7 +962,6 @@
 /* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
    a default IO port, and 1 ACPI/SPMI address.  That sets SI_MAX_DRIVERS */
 
-#define SI_MAX_PARMS 4
 static LIST_HEAD(smi_infos);
 static DEFINE_MUTEX(smi_infos_lock);
 static int smi_num; /* Used to sequence the SMIs */
@@ -1021,6 +1034,10 @@
 		 " the controller.  Normally this is 0x20, but can be"
 		 " overridden by this parm.  This is an array indexed"
 		 " by interface number.");
+module_param_array(force_kipmid, int, &num_force_kipmid, 0);
+MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
+		 " disabled(0).  Normally the IPMI driver auto-detects"
+		 " this, but the value may be overridden by this parm.");
 
 
 #define IPMI_IO_ADDR_SPACE  0
@@ -1734,6 +1751,7 @@
 	int                  rv;
 
 	while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) {
+		memset(&data, 0, sizeof(data));
 		rv = decode_dmi((struct dmi_header *) dev->device_data, &data);
 		if (!rv)
 			try_init_dmi(&data);
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 2e1da63..ea2bbf8 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1550,7 +1550,7 @@
 	board->base = 0;
 }
 
-static struct tty_operations isicom_ops = {
+static const struct tty_operations isicom_ops = {
 	.open			= isicom_open,
 	.close			= isicom_close,
 	.write			= isicom_write,
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 6b4d82a..d6e0315 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -4636,7 +4636,7 @@
 	return rc;
 }
 
-static struct tty_operations stli_ops = {
+static const struct tty_operations stli_ops = {
 	.open = stli_open,
 	.close = stli_close,
 	.write = stli_write,
diff --git a/drivers/char/ite_gpio.c b/drivers/char/ite_gpio.c
deleted file mode 100644
index cde562d..0000000
--- a/drivers/char/ite_gpio.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * FILE NAME ite_gpio.c
- *
- * BRIEF MODULE DESCRIPTION
- *  API for ITE GPIO device.
- *  Driver for ITE GPIO device.
- *
- *  Author: MontaVista Software, Inc.  <source@mvista.com>
- *          Hai-Pao Fan <haipao@mvista.com>
- *
- * Copyright 2001 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE	LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/miscdevice.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/addrspace.h>
-#include <asm/it8172/it8172_int.h>
-#include <linux/sched.h>
-#include <linux/ite_gpio.h>
-
-#define ite_gpio_base 0x14013800
-
-#define	ITE_GPADR	(*(volatile __u8 *)(0x14013800 + KSEG1))
-#define	ITE_GPBDR	(*(volatile __u8 *)(0x14013808 + KSEG1))
-#define	ITE_GPCDR	(*(volatile __u8 *)(0x14013810 + KSEG1))
-#define	ITE_GPACR	(*(volatile __u16 *)(0x14013802 + KSEG1))
-#define	ITE_GPBCR	(*(volatile __u16 *)(0x1401380a + KSEG1))
-#define	ITE_GPCCR	(*(volatile __u16 *)(0x14013812 + KSEG1))
-#define ITE_GPAICR	(*(volatile __u16 *)(0x14013804 + KSEG1))
-#define	ITE_GPBICR	(*(volatile __u16 *)(0x1401380c + KSEG1))
-#define	ITE_GPCICR	(*(volatile __u16 *)(0x14013814 + KSEG1))
-#define	ITE_GPAISR	(*(volatile __u8 *)(0x14013806 + KSEG1))
-#define	ITE_GPBISR	(*(volatile __u8 *)(0x1401380e + KSEG1))
-#define	ITE_GPCISR	(*(volatile __u8 *)(0x14013816 + KSEG1))
-#define	ITE_GCR		(*(volatile __u8 *)(0x14013818 + KSEG1))
-
-#define MAX_GPIO_LINE		21
-static int ite_gpio_irq=IT8172_GPIO_IRQ;
-
-static long ite_irq_counter[MAX_GPIO_LINE];
-wait_queue_head_t ite_gpio_wait[MAX_GPIO_LINE];
-static int ite_gpio_irq_pending[MAX_GPIO_LINE];
-
-static int ite_gpio_debug=0;
-#define DEB(x)  if (ite_gpio_debug>=1) x
-
-int ite_gpio_in(__u32 device, __u32 mask, volatile __u32 *data)
-{
-	DEB(printk("ite_gpio_in mask=0x%x\n",mask)); 
-
-	switch (device) {
-	case ITE_GPIO_PORTA:
-		ITE_GPACR = (__u16)mask;	/* 0xffff */
-		*data = ITE_GPADR;
-		break;
-	case ITE_GPIO_PORTB:
-		ITE_GPBCR = (__u16)mask;	/* 0xffff */
-		*data = ITE_GPBDR;
-		break;
-	case ITE_GPIO_PORTC:
-		ITE_GPCCR = (__u16)mask;	/* 0x03ff */
-		*data = ITE_GPCDR;
-		break;
-	default:
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-
-int ite_gpio_out(__u32 device, __u32 mask, __u32 data)
-{
-	switch (device) {
-	case ITE_GPIO_PORTA:
-		ITE_GPACR = (__u16)mask;	/* 0x5555 */
-		ITE_GPADR = (__u8)data;
-		break;
-	case ITE_GPIO_PORTB:
-		ITE_GPBCR = (__u16)mask;	/* 0x5555 */
-		ITE_GPBDR = (__u8)data;
-		break;
-	case ITE_GPIO_PORTC:
-		ITE_GPCCR = (__u16)mask;	/* 0x0155 */
-		ITE_GPCDR = (__u8)data;
-		break;
-	default:
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int ite_gpio_int_ctrl(__u32 device, __u32 mask, __u32 data)
-{
-	switch (device) {
-	case ITE_GPIO_PORTA:
-		ITE_GPAICR = (ITE_GPAICR & ~mask) | (data & mask);
-		break;
-	case ITE_GPIO_PORTB:
-		ITE_GPBICR = (ITE_GPBICR & ~mask) | (data & mask);
-		break;
-	case ITE_GPIO_PORTC:
-		ITE_GPCICR = (ITE_GPCICR & ~mask) | (data & mask);
-		break;
-	default:
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int ite_gpio_in_status(__u32 device, __u32 mask, volatile __u32 *data)
-{
-	int ret=-1;
-
-	if ((MAX_GPIO_LINE > *data) && (*data >= 0)) 
-		ret=ite_gpio_irq_pending[*data];
- 
-	DEB(printk("ite_gpio_in_status %d ret=%d\n",*data, ret));
-
-	switch (device) {
-	case ITE_GPIO_PORTA:
-		*data = ITE_GPAISR & mask;
-		break;
-	case ITE_GPIO_PORTB:
-		*data = ITE_GPBISR & mask;
-		break;
-	case ITE_GPIO_PORTC:
-		*data = ITE_GPCISR & mask;
-		break;
-	default:
-		return -EFAULT;
-	}
-
-	return ret;
-}
-
-int ite_gpio_out_status(__u32 device, __u32 mask, __u32 data)
-{
-	switch (device) {
-	case ITE_GPIO_PORTA:
-		ITE_GPAISR = (ITE_GPAISR & ~mask) | (data & mask);
-		break;
-	case ITE_GPIO_PORTB:
-		ITE_GPBISR = (ITE_GPBISR & ~mask) | (data & mask);
-		break;
-	case ITE_GPIO_PORTC:
-		ITE_GPCISR = (ITE_GPCISR & ~mask) | (data & mask);
-		break;
-	default:
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int ite_gpio_gen_ctrl(__u32 device, __u32 mask, __u32 data)
-{
-	ITE_GCR = (ITE_GCR & ~mask) | (data & mask);
-
-	return 0;
-}
-
-int ite_gpio_int_wait (__u32 device, __u32 mask, __u32 data)
-{
-	int i,line=0, ret=0;
-	unsigned long flags;
-
-	switch (device) {
-	case ITE_GPIO_PORTA:
-		line = data & mask;
-		break;
-	case ITE_GPIO_PORTB:
-		line = (data & mask) <<8;
-		break;
-	case ITE_GPIO_PORTC:
-		line = (data & mask) <<16;
-		break;
-	}
-	for (i=MAX_GPIO_LINE-1; i >= 0; i--) {
-		if ( (line) & (1 << i))
-			break;
-	}
-
-	DEB(printk("wait device=0x%d mask=0x%x data=0x%x index %d\n", 
-		device, mask, data, i));
-
-	if (line & ~(1<<i))
-		return -EFAULT;
-
-	if (ite_gpio_irq_pending[i]==1)
-		return -EFAULT;
-
-	save_flags (flags);
-	cli();
-	ite_gpio_irq_pending[i] = 1;
-	ret = interruptible_sleep_on_timeout(&ite_gpio_wait[i], 3*HZ);
-	restore_flags (flags);
-	ite_gpio_irq_pending[i] = 0;
-
-	return ret;
-}
-
-EXPORT_SYMBOL(ite_gpio_in);
-EXPORT_SYMBOL(ite_gpio_out);
-EXPORT_SYMBOL(ite_gpio_int_ctrl);
-EXPORT_SYMBOL(ite_gpio_in_status);
-EXPORT_SYMBOL(ite_gpio_out_status);
-EXPORT_SYMBOL(ite_gpio_gen_ctrl);
-EXPORT_SYMBOL(ite_gpio_int_wait);
-
-static int ite_gpio_open(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-
-static int ite_gpio_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-
-static int ite_gpio_ioctl(struct inode *inode, struct file *file,
-	unsigned int cmd, unsigned long arg)
-{
-	static struct ite_gpio_ioctl_data ioctl_data;
-
-	if (copy_from_user(&ioctl_data, (struct ite_gpio_ioctl_data *)arg,
-			sizeof(ioctl_data)))
-		return -EFAULT;
-	if ((ioctl_data.device < ITE_GPIO_PORTA) ||
-			(ioctl_data.device > ITE_GPIO_PORTC) )
-				return -EFAULT;
-
-	switch(cmd) {
-		case ITE_GPIO_IN:
-			if (ite_gpio_in(ioctl_data.device, ioctl_data.mask,
-					   &ioctl_data.data))
-				return -EFAULT;
-
-			if (copy_to_user((struct ite_gpio_ioctl_data *)arg,
-					 &ioctl_data, sizeof(ioctl_data)))
-				return -EFAULT;
-			break;
-
-		case ITE_GPIO_OUT:
-			return ite_gpio_out(ioctl_data.device,
-					ioctl_data.mask, ioctl_data.data);
-			break;
-
-		case ITE_GPIO_INT_CTRL:
-			return ite_gpio_int_ctrl(ioctl_data.device,
-					ioctl_data.mask, ioctl_data.data);
-			break;
-
-		case ITE_GPIO_IN_STATUS:
-			if (ite_gpio_in_status(ioctl_data.device, ioctl_data.mask,
-					&ioctl_data.data))
-				return -EFAULT;
-			if (copy_to_user((struct ite_gpio_ioctl_data *)arg,
-					&ioctl_data, sizeof(ioctl_data))) 
-				return -EFAULT;
-			break;
-
-		case ITE_GPIO_OUT_STATUS:
-			return ite_gpio_out_status(ioctl_data.device,
-					ioctl_data.mask, ioctl_data.data);
-			break;
-
-		case ITE_GPIO_GEN_CTRL:
-			return ite_gpio_gen_ctrl(ioctl_data.device,
-					ioctl_data.mask, ioctl_data.data);
-			break;
-
-		case ITE_GPIO_INT_WAIT:
-			return ite_gpio_int_wait(ioctl_data.device,
-					ioctl_data.mask, ioctl_data.data);
-			break;
-
-		default:
-			return -ENOIOCTLCMD;
-
-	}
-
-	return 0;
-}
-
-static void ite_gpio_irq_handler(int this_irq, void *dev_id,
-	struct pt_regs *regs)
-{
-	int i,line;
-
-	line = ITE_GPCISR & 0x1f;
-	for (i=4; i >=0; i--) {
-		if ( line & (1 << i)) { 
-			++ite_irq_counter[i+16];
-			ite_gpio_irq_pending[i+16] = 2;
-			wake_up_interruptible(&ite_gpio_wait[i+16]);
-
-DEB(printk("interrupt 0x%x %d\n", &ite_gpio_wait[i+16], i+16));
-
-			ITE_GPCISR = ITE_GPCISR & (1<<i);
-			return;
-		}
-	}
-	line = ITE_GPBISR;
-	for (i=7; i >= 0; i--) {
-		if ( line & (1 << i)) {
-			++ite_irq_counter[i+8];
-			ite_gpio_irq_pending[i+8] = 2;
-			wake_up_interruptible(&ite_gpio_wait[i+8]);
-
-DEB(printk("interrupt 0x%x %d\n",ITE_GPBISR, i+8));
-
-			ITE_GPBISR = ITE_GPBISR & (1<<i);
-			return;
-		}
-	}
-	line = ITE_GPAISR;
-	for (i=7; i >= 0; i--) {
-		if ( line & (1 << i)) {
-			++ite_irq_counter[i];
-			ite_gpio_irq_pending[i] = 2;
-			wake_up_interruptible(&ite_gpio_wait[i]);
-
-DEB(printk("interrupt 0x%x %d\n",ITE_GPAISR, i));
-
-			ITE_GPAISR = ITE_GPAISR & (1<<i);
-			return;
-		}
-	}
-}
-
-static const struct file_operations ite_gpio_fops = {
-	.owner		= THIS_MODULE,
-	.ioctl		= ite_gpio_ioctl,
-	.open		= ite_gpio_open,
-	.release	= ite_gpio_release,
-};
-
-static struct miscdevice ite_gpio_miscdev = {
-	MISC_DYNAMIC_MINOR,
-	"ite_gpio",
-	&ite_gpio_fops
-};
-
-int __init ite_gpio_init(void)
-{
-	int i;
-
-	if (misc_register(&ite_gpio_miscdev))
-		return -ENODEV;
-
-	if (!request_region(ite_gpio_base, 0x1c, "ITE GPIO"))
-	{
-		misc_deregister(&ite_gpio_miscdev);
-		return -EIO;
-	}
-
-	/* initialize registers */
-        ITE_GPACR = 0xffff;
-        ITE_GPBCR = 0xffff;
-        ITE_GPCCR = 0xffff;
-        ITE_GPAICR = 0x00ff;
-        ITE_GPBICR = 0x00ff;
-        ITE_GPCICR = 0x00ff;
-        ITE_GCR = 0;
-	
-	for (i = 0; i < MAX_GPIO_LINE; i++) {
-		ite_gpio_irq_pending[i]=0;	
-		init_waitqueue_head(&ite_gpio_wait[i]);
-	}
-
-	if (request_irq(ite_gpio_irq, ite_gpio_irq_handler, IRQF_SHARED, "gpio", 0) < 0) {
-		misc_deregister(&ite_gpio_miscdev);
-		release_region(ite_gpio_base, 0x1c);
-		return 0;
-	}
-
-	printk("GPIO at 0x%x (irq = %d)\n", ite_gpio_base, ite_gpio_irq);
-
-	return 0;
-}	
-
-static void __exit ite_gpio_exit(void)
-{
-	misc_deregister(&ite_gpio_miscdev);
-}
-
-module_init(ite_gpio_init);
-module_exit(ite_gpio_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 3e90aac..e201166 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -108,7 +108,11 @@
 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
 static struct kbd_struct *kbd = kbd_table;
 
-int spawnpid, spawnsig;
+struct vt_spawn_console vt_spawn_con = {
+	.lock = SPIN_LOCK_UNLOCKED,
+	.pid  = NULL,
+	.sig  = 0,
+};
 
 /*
  * Variables exported for vt.c
@@ -578,9 +582,13 @@
 
 static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
 {
-	if (spawnpid)
-		if (kill_proc(spawnpid, spawnsig, 1))
-			spawnpid = 0;
+	spin_lock(&vt_spawn_con.lock);
+	if (vt_spawn_con.pid)
+		if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
+			put_pid(vt_spawn_con.pid);
+			vt_spawn_con.pid = NULL;
+		}
+	spin_unlock(&vt_spawn_con.lock);
 }
 
 static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
@@ -1285,7 +1293,7 @@
  */
 static struct input_handle *kbd_connect(struct input_handler *handler,
 					struct input_dev *dev,
-					struct input_device_id *id)
+					const struct input_device_id *id)
 {
 	struct input_handle *handle;
 	int i;
@@ -1334,7 +1342,7 @@
 	tasklet_enable(&keyboard_tasklet);
 }
 
-static struct input_device_id kbd_ids[] = {
+static const struct input_device_id kbd_ids[] = {
 	{
                 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
                 .evbit = { BIT(EV_KEY) },
@@ -1362,6 +1370,7 @@
 int __init kbd_init(void)
 {
 	int i;
+	int error;
 
         for (i = 0; i < MAX_NR_CONSOLES; i++) {
 		kbd_table[i].ledflagstate = KBD_DEFLEDS;
@@ -1373,7 +1382,9 @@
 		kbd_table[i].kbdmode = VC_XLATE;
 	}
 
-	input_register_handler(&kbd_handler);
+	error = input_register_handler(&kbd_handler);
+	if (error)
+		return error;
 
 	tasklet_enable(&keyboard_tasklet);
 	tasklet_schedule(&keyboard_tasklet);
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index c1a6d3c..b401383 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -281,7 +281,7 @@
 static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);
 static void MoxaSetFifo(int port, int enable);
 
-static struct tty_operations moxa_ops = {
+static const struct tty_operations moxa_ops = {
 	.open = moxa_open,
 	.close = moxa_close,
 	.write = moxa_write,
diff --git a/drivers/char/mwave/README b/drivers/char/mwave/README
index 70f8d19..480251f 100644
--- a/drivers/char/mwave/README
+++ b/drivers/char/mwave/README
@@ -41,10 +41,7 @@
 Accessing the driver
 --------------------
 
-You must also create a node for the driver.  Without devfs:
+You must also create a node for the driver:
   mkdir -p /dev/modems
   mknod --mode=660 /dev/modems/mwave c 10 219
-With devfs:
-  mkdir -p /dev/modems
-  ln -s ../misc/mwave /dev/modems/mwave
 
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 27a6537..8253fca 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -453,7 +453,7 @@
 
 /* above is modified by Victor Yu. 08-15-2002 */
 
-static struct tty_operations mxser_ops = {
+static const struct tty_operations mxser_ops = {
 	.open = mxser_open,
 	.close = mxser_close,
 	.write = mxser_write,
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 7c57ebf..ea1aa77 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -127,9 +127,8 @@
 static void button_sequence_finished (unsigned long parameters)
 {
 #ifdef CONFIG_NWBUTTON_REBOOT		/* Reboot using button is enabled */
-	if (button_press_count == reboot_count) {
-		kill_proc (1, SIGINT, 1);	/* Ask init to reboot us */
-	}
+	if (button_press_count == reboot_count)
+		kill_cad_pid(SIGINT, 1);	/* Ask init to reboot us */
 #endif /* CONFIG_NWBUTTON_REBOOT */
 	button_consume_callbacks (button_press_count);
 	bcount = sprintf (button_output_buffer, "%d\n", button_press_count);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 00f574c..d1ecb2c 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -57,7 +57,6 @@
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <asm/serial.h>
 #include <linux/delay.h>
 #include <linux/ioctl.h>
 
@@ -3010,7 +3009,7 @@
 	.resume		= mgslpc_resume,
 };
 
-static struct tty_operations mgslpc_ops = {
+static const struct tty_operations mgslpc_ops = {
 	.open = mgslpc_open,
 	.close = mgslpc_close,
 	.write = mgslpc_write,
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 34dd4c3..80d3eed 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -224,7 +224,7 @@
         tty->termios->c_cflag |= (CS8 | CREAD);
 }
 
-static struct tty_operations pty_ops = {
+static const struct tty_operations pty_ops = {
 	.open = pty_open,
 	.close = pty_close,
 	.write = pty_write,
diff --git a/drivers/char/qtronixmap.c_shipped b/drivers/char/qtronixmap.c_shipped
deleted file mode 100644
index 1e2b92b..0000000
--- a/drivers/char/qtronixmap.c_shipped
+++ /dev/null
@@ -1,265 +0,0 @@
-
-/* Do not edit this file! It was automatically generated by   */
-/*    loadkeys --mktable defkeymap.map > defkeymap.c          */
-
-#include <linux/types.h>
-#include <linux/keyboard.h>
-#include <linux/kd.h>
-
-u_short plain_map[NR_KEYS] = {
-	0xf200,	0xf060,	0xf031,	0xf032,	0xf033,	0xf034,	0xf035,	0xf036,
-	0xf037,	0xf038,	0xf039,	0xf030,	0xf02d,	0xf03d,	0xf200,	0xf07f,
-	0xf009,	0xfb71,	0xfb77,	0xfb65,	0xfb72,	0xfb74,	0xfb79,	0xfb75,
-	0xfb69,	0xfb6f,	0xfb70,	0xf05b,	0xf05d,	0xf05c,	0xf207,	0xfb61,
-	0xfb73,	0xfb64,	0xfb66,	0xfb67,	0xfb68,	0xfb6a,	0xfb6b,	0xfb6c,
-	0xf03b,	0xf027,	0xf060,	0xf201,	0xf700,	0xf200,	0xfb7a,	0xfb78,
-	0xfb63,	0xfb76,	0xfb62,	0xfb6e,	0xfb6d,	0xf02c,	0xf02e,	0xf02f,
-	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf020,	0xf703,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
-	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
-	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf01b,	0xf200,
-	0xf100,	0xf101,	0xf102,	0xf103,	0xf104,	0xf105,	0xf106,	0xf107,
-	0xf108,	0xf109,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
-};
-
-u_short shift_map[NR_KEYS] = {
-	0xf200,	0xf07e,	0xf021,	0xf040,	0xf023,	0xf024,	0xf025,	0xf05e,
-	0xf026,	0xf02a,	0xf028,	0xf029,	0xf05f,	0xf02b,	0xf200,	0xf07f,
-	0xf009,	0xfb51,	0xfb57,	0xfb45,	0xfb52,	0xfb54,	0xfb59,	0xfb55,
-	0xfb49,	0xfb4f,	0xfb50,	0xf07b,	0xf07d,	0xf07c,	0xf207,	0xfb41,
-	0xfb53,	0xfb44,	0xfb46,	0xfb47,	0xfb48,	0xfb4a,	0xfb4b,	0xfb4c,
-	0xf03a,	0xf022,	0xf07e,	0xf201,	0xf700,	0xf200,	0xfb5a,	0xfb58,
-	0xfb43,	0xfb56,	0xfb42,	0xfb4e,	0xfb4d,	0xf03c,	0xf03e,	0xf03f,
-	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf020,	0xf703,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
-	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf20b,	0xf20a,	0xf200,
-	0xf200,	0xf602,	0xf213,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf01b,	0xf200,
-	0xf10a,	0xf10b,	0xf10c,	0xf10d,	0xf10e,	0xf10f,	0xf110,	0xf111,
-	0xf112,	0xf113,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
-};
-
-u_short altgr_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf040,	0xf200,	0xf024,	0xf200,	0xf200,
-	0xf07b,	0xf05b,	0xf05d,	0xf07d,	0xf05c,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xfb71,	0xfb77,	0xfb65,	0xfb72,	0xfb74,	0xfb79,	0xfb75,
-	0xfb69,	0xfb6f,	0xfb70,	0xf200,	0xf200,	0xf200,	0xf207,	0xfb61,
-	0xfb73,	0xfb64,	0xfb66,	0xfb67,	0xfb68,	0xfb6a,	0xfb6b,	0xfb6c,
-	0xf200,	0xf200,	0xf200,	0xf201,	0xf700,	0xf200,	0xfb7a,	0xfb78,
-	0xfb63,	0xfb76,	0xfb62,	0xfb6e,	0xfb6d,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf200,	0xf703,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
-	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
-	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
-	0xf50c,	0xf50d,	0xf50e,	0xf50f,	0xf510,	0xf511,	0xf512,	0xf513,
-	0xf514,	0xf515,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
-};
-
-u_short ctrl_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf000,	0xf01b,	0xf01c,	0xf01d,	0xf01e,
-	0xf01f,	0xf07f,	0xf200,	0xf200,	0xf01f,	0xf200,	0xf200,	0xf008,
-	0xf200,	0xf011,	0xf017,	0xf005,	0xf012,	0xf014,	0xf019,	0xf015,
-	0xf009,	0xf00f,	0xf010,	0xf01b,	0xf01d,	0xf01c,	0xf207,	0xf001,
-	0xf013,	0xf004,	0xf006,	0xf007,	0xf008,	0xf00a,	0xf00b,	0xf00c,
-	0xf007,	0xf000,	0xf200,	0xf201,	0xf700,	0xf200,	0xf01a,	0xf018,
-	0xf003,	0xf016,	0xf002,	0xf00e,	0xf20e,	0xf07f,	0xf200,	0xf200,
-	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf000,	0xf703,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
-	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
-	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
-	0xf100,	0xf101,	0xf102,	0xf103,	0xf104,	0xf105,	0xf106,	0xf107,
-	0xf108,	0xf109,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
-};
-
-u_short shift_ctrl_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf000,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf01f,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf011,	0xf017,	0xf005,	0xf012,	0xf014,	0xf019,	0xf015,
-	0xf009,	0xf00f,	0xf010,	0xf200,	0xf200,	0xf200,	0xf207,	0xf001,
-	0xf013,	0xf004,	0xf006,	0xf007,	0xf008,	0xf00a,	0xf00b,	0xf00c,
-	0xf200,	0xf200,	0xf200,	0xf201,	0xf700,	0xf200,	0xf01a,	0xf018,
-	0xf003,	0xf016,	0xf002,	0xf00e,	0xf00d,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf200,	0xf703,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
-	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
-	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
-};
-
-u_short alt_map[NR_KEYS] = {
-	0xf200,	0xf81b,	0xf831,	0xf832,	0xf833,	0xf834,	0xf835,	0xf836,
-	0xf837,	0xf838,	0xf839,	0xf830,	0xf82d,	0xf83d,	0xf200,	0xf87f,
-	0xf809,	0xf871,	0xf877,	0xf865,	0xf872,	0xf874,	0xf879,	0xf875,
-	0xf869,	0xf86f,	0xf870,	0xf85b,	0xf85d,	0xf85c,	0xf207,	0xf861,
-	0xf873,	0xf864,	0xf866,	0xf867,	0xf868,	0xf86a,	0xf86b,	0xf83b,
-	0xf827,	0xf860,	0xf200,	0xf80d,	0xf700,	0xf200,	0xf87a,	0xf878,
-	0xf863,	0xf876,	0xf862,	0xf82c,	0xf82e,	0xf82f,	0xf200,	0xf200,
-	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf820,	0xf703,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf210,
-	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
-	0xf200,	0xf211,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
-	0xf500,	0xf501,	0xf502,	0xf503,	0xf504,	0xf505,	0xf506,	0xf507,
-	0xf508,	0xf509,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
-};
-
-u_short ctrl_alt_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf811,	0xf817,	0xf805,	0xf812,	0xf814,	0xf819,	0xf815,
-	0xf809,	0xf80f,	0xf810,	0xf200,	0xf200,	0xf200,	0xf207,	0xf801,
-	0xf813,	0xf804,	0xf806,	0xf807,	0xf808,	0xf80a,	0xf80b,	0xf80c,
-	0xf200,	0xf200,	0xf200,	0xf201,	0xf700,	0xf200,	0xf81a,	0xf818,
-	0xf803,	0xf816,	0xf802,	0xf80e,	0xf80d,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf200,	0xf703,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
-	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
-	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
-	0xf500,	0xf501,	0xf502,	0xf503,	0xf504,	0xf505,	0xf506,	0xf507,
-	0xf508,	0xf509,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
-};
-
-ushort *key_maps[MAX_NR_KEYMAPS] = {
-	plain_map, shift_map, altgr_map, 0,
-	ctrl_map, shift_ctrl_map, 0, 0,
-	alt_map, 0, 0, 0,
-	ctrl_alt_map,	0
-};
-
-unsigned int keymap_count = 7;
-
-
-/*
- * Philosophy: most people do not define more strings, but they who do
- * often want quite a lot of string space. So, we statically allocate
- * the default and allocate dynamically in chunks of 512 bytes.
- */
-
-char func_buf[] = {
-	'\033', '[', '[', 'A', 0, 
-	'\033', '[', '[', 'B', 0, 
-	'\033', '[', '[', 'C', 0, 
-	'\033', '[', '[', 'D', 0, 
-	'\033', '[', '[', 'E', 0, 
-	'\033', '[', '1', '7', '~', 0, 
-	'\033', '[', '1', '8', '~', 0, 
-	'\033', '[', '1', '9', '~', 0, 
-	'\033', '[', '2', '0', '~', 0, 
-	'\033', '[', '2', '1', '~', 0, 
-	'\033', '[', '2', '3', '~', 0, 
-	'\033', '[', '2', '4', '~', 0, 
-	'\033', '[', '2', '5', '~', 0, 
-	'\033', '[', '2', '6', '~', 0, 
-	'\033', '[', '2', '8', '~', 0, 
-	'\033', '[', '2', '9', '~', 0, 
-	'\033', '[', '3', '1', '~', 0, 
-	'\033', '[', '3', '2', '~', 0, 
-	'\033', '[', '3', '3', '~', 0, 
-	'\033', '[', '3', '4', '~', 0, 
-	'\033', '[', '1', '~', 0, 
-	'\033', '[', '2', '~', 0, 
-	'\033', '[', '3', '~', 0, 
-	'\033', '[', '4', '~', 0, 
-	'\033', '[', '5', '~', 0, 
-	'\033', '[', '6', '~', 0, 
-	'\033', '[', 'M', 0, 
-	'\033', '[', 'P', 0, 
-};
-
-
-char *funcbufptr = func_buf;
-int funcbufsize = sizeof(func_buf);
-int funcbufleft = 0;          /* space left */
-
-char *func_table[MAX_NR_FUNC] = {
-	func_buf + 0,
-	func_buf + 5,
-	func_buf + 10,
-	func_buf + 15,
-	func_buf + 20,
-	func_buf + 25,
-	func_buf + 31,
-	func_buf + 37,
-	func_buf + 43,
-	func_buf + 49,
-	func_buf + 55,
-	func_buf + 61,
-	func_buf + 67,
-	func_buf + 73,
-	func_buf + 79,
-	func_buf + 85,
-	func_buf + 91,
-	func_buf + 97,
-	func_buf + 103,
-	func_buf + 109,
-	func_buf + 115,
-	func_buf + 120,
-	func_buf + 125,
-	func_buf + 130,
-	func_buf + 135,
-	func_buf + 140,
-	func_buf + 145,
-	0,
-	0,
-	func_buf + 149,
-	0,
-};
-
-struct kbdiacr accent_table[MAX_DIACR] = {
-	{'`', 'A', 'À'},	{'`', 'a', 'à'},
-	{'\'', 'A', 'Á'},	{'\'', 'a', 'á'},
-	{'^', 'A', 'Â'},	{'^', 'a', 'â'},
-	{'~', 'A', 'Ã'},	{'~', 'a', 'ã'},
-	{'"', 'A', 'Ä'},	{'"', 'a', 'ä'},
-	{'O', 'A', 'Å'},	{'o', 'a', 'å'},
-	{'0', 'A', 'Å'},	{'0', 'a', 'å'},
-	{'A', 'A', 'Å'},	{'a', 'a', 'å'},
-	{'A', 'E', 'Æ'},	{'a', 'e', 'æ'},
-	{',', 'C', 'Ç'},	{',', 'c', 'ç'},
-	{'`', 'E', 'È'},	{'`', 'e', 'è'},
-	{'\'', 'E', 'É'},	{'\'', 'e', 'é'},
-	{'^', 'E', 'Ê'},	{'^', 'e', 'ê'},
-	{'"', 'E', 'Ë'},	{'"', 'e', 'ë'},
-	{'`', 'I', 'Ì'},	{'`', 'i', 'ì'},
-	{'\'', 'I', 'Í'},	{'\'', 'i', 'í'},
-	{'^', 'I', 'Î'},	{'^', 'i', 'î'},
-	{'"', 'I', 'Ï'},	{'"', 'i', 'ï'},
-	{'-', 'D', 'Ð'},	{'-', 'd', 'ð'},
-	{'~', 'N', 'Ñ'},	{'~', 'n', 'ñ'},
-	{'`', 'O', 'Ò'},	{'`', 'o', 'ò'},
-	{'\'', 'O', 'Ó'},	{'\'', 'o', 'ó'},
-	{'^', 'O', 'Ô'},	{'^', 'o', 'ô'},
-	{'~', 'O', 'Õ'},	{'~', 'o', 'õ'},
-	{'"', 'O', 'Ö'},	{'"', 'o', 'ö'},
-	{'/', 'O', 'Ø'},	{'/', 'o', 'ø'},
-	{'`', 'U', 'Ù'},	{'`', 'u', 'ù'},
-	{'\'', 'U', 'Ú'},	{'\'', 'u', 'ú'},
-	{'^', 'U', 'Û'},	{'^', 'u', 'û'},
-	{'"', 'U', 'Ü'},	{'"', 'u', 'ü'},
-	{'\'', 'Y', 'Ý'},	{'\'', 'y', 'ý'},
-	{'T', 'H', 'Þ'},	{'t', 'h', 'þ'},
-	{'s', 's', 'ß'},	{'"', 'y', 'ÿ'},
-	{'s', 'z', 'ß'},	{'i', 'j', 'ÿ'},
-};
-
-unsigned int accent_table_size = 68;
diff --git a/drivers/char/qtronixmap.map b/drivers/char/qtronixmap.map
deleted file mode 100644
index 8d1ff5c..0000000
--- a/drivers/char/qtronixmap.map
+++ /dev/null
@@ -1,287 +0,0 @@
-# Default kernel keymap. This uses 7 modifier combinations.
-keymaps 0-2,4-5,8,12
-# Change the above line into
-#	keymaps 0-2,4-6,8,12
-# in case you want the entries
-#	altgr   control keycode  83 = Boot            
-#	altgr   control keycode 111 = Boot            
-# below.
-#
-# In fact AltGr is used very little, and one more keymap can
-# be saved by mapping AltGr to Alt (and adapting a few entries):
-# keycode 100 = Alt
-#
-keycode   1 = grave        asciitilde
-	alt     keycode   1 = Meta_Escape     
-keycode   2 = one              exclam          
-	alt     keycode   2 = Meta_one        
-keycode   3 = two              at               at              
-	control	keycode   3 = nul             
-	shift	control	keycode   3 = nul             
-	alt	keycode   3 = Meta_two        
-keycode   4 = three            numbersign      
-	control keycode   4 = Escape          
-	alt     keycode   4 = Meta_three      
-keycode   5 = four             dollar           dollar          
-	control keycode   5 = Control_backslash
-	alt     keycode   5 = Meta_four       
-keycode   6 = five             percent         
-	control keycode   6 = Control_bracketright
-	alt     keycode   6 = Meta_five       
-keycode   7 = six              asciicircum     
-	control keycode   7 = Control_asciicircum
-	alt     keycode   7 = Meta_six        
-keycode   8 = seven            ampersand        braceleft       
-	control keycode   8 = Control_underscore
-	alt     keycode   8 = Meta_seven      
-keycode   9 = eight            asterisk         bracketleft     
-	control keycode   9 = Delete          
-	alt     keycode   9 = Meta_eight      
-keycode  10 = nine             parenleft        bracketright    
-	alt     keycode  10 = Meta_nine       
-keycode  11 = zero             parenright       braceright      
-	alt     keycode  11 = Meta_zero       
-keycode  12 = minus            underscore       backslash       
-	control	keycode  12 = Control_underscore
-	shift	control	keycode  12 = Control_underscore
-	alt	keycode  12 = Meta_minus      
-keycode  13 = equal            plus            
-	alt     keycode  13 = Meta_equal      
-keycode  15 = Delete           Delete          
-	control keycode  15 = BackSpace
-	alt     keycode  15 = Meta_Delete     
-keycode  16 = Tab              Tab             
-	alt     keycode  16 = Meta_Tab        
-keycode  17 = q               
-keycode  18 = w               
-keycode  19 = e
-keycode  20 = r               
-keycode  21 = t               
-keycode  22 = y               
-keycode  23 = u	 
-keycode  24 = i               
-keycode  25 = o               
-keycode  26 = p               
-keycode  27 = bracketleft      braceleft       
-	control keycode  27 = Escape          
-	alt     keycode  27 = Meta_bracketleft
-keycode  28 = bracketright     braceright
-	control keycode  28 = Control_bracketright
-	alt     keycode  28 = Meta_bracketright
-keycode  29 = backslash        bar             
-	control keycode  29 = Control_backslash
-	alt     keycode  29 = Meta_backslash  
-keycode  30 = Caps_Lock
-keycode  31 = a               
-keycode  32 = s
-keycode  33 = d
-keycode  34 = f               
-keycode  35 = g               
-keycode  36 = h               
-keycode  37 = j               
-keycode  38 = k               
-keycode  39 = l               
-keycode  40 = semicolon        colon           
-	alt     keycode  39 = Meta_semicolon  
-keycode  41 = apostrophe       quotedbl        
-	control keycode  40 = Control_g       
-	alt     keycode  40 = Meta_apostrophe 
-keycode  42 = grave            asciitilde      
-	control keycode  41 = nul             
-	alt     keycode  41 = Meta_grave      
-keycode  43 = Return          
-	alt     keycode  43 = Meta_Control_m  
-keycode  44 = Shift               
-keycode  46 = z
-keycode  47 = x               
-keycode  48 = c
-keycode  49 = v               
-keycode  50 = b               
-keycode  51 = n
-keycode  52 = m
-keycode  53 = comma            less            
-	alt     keycode  51 = Meta_comma      
-keycode  54 = period           greater         
-	control keycode  52 = Compose         
-	alt     keycode  52 = Meta_period     
-keycode  55 = slash            question        
-	control keycode  53 = Delete          
-	alt     keycode  53 = Meta_slash      
-keycode  57 = Shift
-keycode  58 = Control
-keycode  60 = Alt
-keycode  61 = space            space           
-	control keycode  61 = nul             
-	alt     keycode  61 = Meta_space      
-keycode  62 = Alt
-
-keycode 75 = Insert          
-keycode 76 = Delete          
-
-keycode 83 = Up              
-keycode 84 = Down              
-
-keycode 85 = Prior           
-	shift   keycode 85 = Scroll_Backward 
-keycode 86 = Next            
-	shift   keycode 86 = Scroll_Forward  
-keycode 89 = Right           
-	alt     keycode 89 = Incr_Console
-keycode 79 = Left            
-	alt     keycode 79 = Decr_Console
-
-keycode  90 = Num_Lock
-	shift   keycode  90 = Bare_Num_Lock
-
-keycode 91 = minus
-keycode 92 = plus
-keycode 93 = KP_Multiply
-keycode 94 = period
-keycode 95 = KP_Divide
-
-keycode 107 = Select          
-keycode 108 = Down            
-
-keycode 110 = Escape           Escape          
-	alt     keycode   1 = Meta_Escape     
-
-keycode  112 = F1              F11              Console_13      
-	control keycode  112 = F1              
-	alt     keycode  112 = Console_1       
-	control alt     keycode  112 = Console_1       
-keycode  113 = F2              F12              Console_14      
-	control keycode  113 = F2              
-	alt     keycode  113 = Console_2       
-	control alt     keycode  113 = Console_2       
-keycode  114 = F3              F13              Console_15      
-	control keycode  114 = F3              
-	alt     keycode  114 = Console_3       
-	control alt     keycode  114 = Console_3       
-keycode  115 = F4              F14              Console_16      
-	control keycode  115 = F4              
-	alt     keycode  115 = Console_4       
-	control alt     keycode  115 = Console_4       
-keycode  116 = F5              F15              Console_17      
-	control keycode  116 = F5              
-	alt     keycode  116 = Console_5       
-	control alt     keycode  116 = Console_5       
-keycode  117 = F6              F16              Console_18      
-	control keycode  117 = F6              
-	alt     keycode  117 = Console_6       
-	control alt     keycode  117 = Console_6       
-keycode  118 = F7              F17              Console_19      
-	control keycode  118 = F7              
-	alt     keycode  118 = Console_7       
-	control alt     keycode  118 = Console_7       
-keycode  119 = F8              F18              Console_20      
-	control keycode  119 = F8              
-	alt     keycode  119 = Console_8       
-	control alt     keycode  119 = Console_8       
-keycode  120 = F9              F19              Console_21      
-	control keycode  120 = F9              
-	alt     keycode  120 = Console_9       
-	control alt     keycode  120 = Console_9       
-keycode  121 = F10             F20              Console_22      
-	control keycode  121 = F10             
-	alt     keycode  121 = Console_10      
-	control alt     keycode  121 = Console_10      
-	
-keycode 126 = Pause           
-
-
-string F1 = "\033[[A"
-string F2 = "\033[[B"
-string F3 = "\033[[C"
-string F4 = "\033[[D"
-string F5 = "\033[[E"
-string F6 = "\033[17~"
-string F7 = "\033[18~"
-string F8 = "\033[19~"
-string F9 = "\033[20~"
-string F10 = "\033[21~"
-string F11 = "\033[23~"
-string F12 = "\033[24~"
-string F13 = "\033[25~"
-string F14 = "\033[26~"
-string F15 = "\033[28~"
-string F16 = "\033[29~"
-string F17 = "\033[31~"
-string F18 = "\033[32~"
-string F19 = "\033[33~"
-string F20 = "\033[34~"
-string Find = "\033[1~"
-string Insert = "\033[2~"
-string Remove = "\033[3~"
-string Select = "\033[4~"
-string Prior = "\033[5~"
-string Next = "\033[6~"
-string Macro = "\033[M"
-string Pause = "\033[P"
-compose '`' 'A' to 'À'
-compose '`' 'a' to 'à'
-compose '\'' 'A' to 'Á'
-compose '\'' 'a' to 'á'
-compose '^' 'A' to 'Â'
-compose '^' 'a' to 'â'
-compose '~' 'A' to 'Ã'
-compose '~' 'a' to 'ã'
-compose '"' 'A' to 'Ä'
-compose '"' 'a' to 'ä'
-compose 'O' 'A' to 'Å'
-compose 'o' 'a' to 'å'
-compose '0' 'A' to 'Å'
-compose '0' 'a' to 'å'
-compose 'A' 'A' to 'Å'
-compose 'a' 'a' to 'å'
-compose 'A' 'E' to 'Æ'
-compose 'a' 'e' to 'æ'
-compose ',' 'C' to 'Ç'
-compose ',' 'c' to 'ç'
-compose '`' 'E' to 'È'
-compose '`' 'e' to 'è'
-compose '\'' 'E' to 'É'
-compose '\'' 'e' to 'é'
-compose '^' 'E' to 'Ê'
-compose '^' 'e' to 'ê'
-compose '"' 'E' to 'Ë'
-compose '"' 'e' to 'ë'
-compose '`' 'I' to 'Ì'
-compose '`' 'i' to 'ì'
-compose '\'' 'I' to 'Í'
-compose '\'' 'i' to 'í'
-compose '^' 'I' to 'Î'
-compose '^' 'i' to 'î'
-compose '"' 'I' to 'Ï'
-compose '"' 'i' to 'ï'
-compose '-' 'D' to 'Ð'
-compose '-' 'd' to 'ð'
-compose '~' 'N' to 'Ñ'
-compose '~' 'n' to 'ñ'
-compose '`' 'O' to 'Ò'
-compose '`' 'o' to 'ò'
-compose '\'' 'O' to 'Ó'
-compose '\'' 'o' to 'ó'
-compose '^' 'O' to 'Ô'
-compose '^' 'o' to 'ô'
-compose '~' 'O' to 'Õ'
-compose '~' 'o' to 'õ'
-compose '"' 'O' to 'Ö'
-compose '"' 'o' to 'ö'
-compose '/' 'O' to 'Ø'
-compose '/' 'o' to 'ø'
-compose '`' 'U' to 'Ù'
-compose '`' 'u' to 'ù'
-compose '\'' 'U' to 'Ú'
-compose '\'' 'u' to 'ú'
-compose '^' 'U' to 'Û'
-compose '^' 'u' to 'û'
-compose '"' 'U' to 'Ü'
-compose '"' 'u' to 'ü'
-compose '\'' 'Y' to 'Ý'
-compose '\'' 'y' to 'ý'
-compose 'T' 'H' to 'Þ'
-compose 't' 'h' to 'þ'
-compose 's' 's' to 'ß'
-compose '"' 'y' to 'ÿ'
-compose 's' 'z' to 'ß'
-compose 'i' 'j' to 'ÿ'
diff --git a/drivers/char/random.c b/drivers/char/random.c
index b430a12..07f47a0 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -889,8 +889,8 @@
 
 	do_gettimeofday(&tv);
 	add_entropy_words(r, (__u32 *)&tv, sizeof(tv)/4);
-	add_entropy_words(r, (__u32 *)&system_utsname,
-			  sizeof(system_utsname)/4);
+	add_entropy_words(r, (__u32 *)utsname(),
+			  sizeof(*(utsname()))/4);
 }
 
 static int __init rand_initialize(void)
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 3fa80aa..202a3b0 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -727,7 +727,7 @@
 	return &vpdp;
 }
 
-static struct tty_operations rio_ops = {
+static const struct tty_operations rio_ops = {
 	.open = riotopen,
 	.close = gs_close,
 	.write = gs_write,
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 06b9f78..b0ab3f2 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -81,7 +81,6 @@
 
 static struct riscom_board * IRQ_to_board[16];
 static struct tty_driver *riscom_driver;
-static unsigned char * tmp_buf;
 
 static unsigned long baud_table[] =  {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
@@ -1124,7 +1123,7 @@
 	
 	bp = port_Board(port);
 
-	if (!tty || !port->xmit_buf || !tmp_buf)
+	if (!tty || !port->xmit_buf)
 		return 0;
 
 	save_flags(flags);
@@ -1583,7 +1582,7 @@
 	}
 }
 
-static struct tty_operations riscom_ops = {
+static const struct tty_operations riscom_ops = {
 	.open  = rc_open,
 	.close = rc_close,
 	.write = rc_write,
@@ -1612,11 +1611,6 @@
 	if (!riscom_driver)	
 		return -ENOMEM;
 	
-	if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
-		printk(KERN_ERR "rc: Couldn't get free page.\n");
-		put_tty_driver(riscom_driver);
-		return 1;
-	}
 	memset(IRQ_to_board, 0, sizeof(IRQ_to_board));
 	riscom_driver->owner = THIS_MODULE;
 	riscom_driver->name = "ttyL";
@@ -1629,7 +1623,6 @@
 	riscom_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(riscom_driver, &riscom_ops);
 	if ((error = tty_register_driver(riscom_driver)))  {
-		free_page((unsigned long)tmp_buf);
 		put_tty_driver(riscom_driver);
 		printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
 				"error = %d\n",
@@ -1657,7 +1650,6 @@
 
 	save_flags(flags);
 	cli();
-	free_page((unsigned long)tmp_buf);
 	tty_unregister_driver(riscom_driver);
 	put_tty_driver(riscom_driver);
 	restore_flags(flags);
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 0ac1318..bac8005 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -2334,7 +2334,7 @@
 	return (1);
 }
 
-static struct tty_operations rocket_ops = {
+static const struct tty_operations rocket_ops = {
 	.open = rp_open,
 	.close = rp_close,
 	.write = rp_write,
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 510bd3e..65c751d 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -661,7 +661,7 @@
 	}
 }
 
-static struct tty_operations a2232_ops = {
+static const struct tty_operations a2232_ops = {
 	.open = a2232_open,
 	.close = gs_close,
 	.write = gs_write,
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 21a710c..f4809c8 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -119,17 +119,6 @@
 #define NR_PORTS        ARRAY_SIZE(cy_port)
 
 /*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf = 0;
-
-/*
  * This is used to look up the divisor speeds and the timeouts
  * We're normally limited to 15 distinct baud rates.  The extra
  * are accessed via settings in info->flags.
@@ -1132,7 +1121,7 @@
     if (serial_paranoia_check(info, tty->name, "cy_put_char"))
 	return;
 
-    if (!tty || !info->xmit_buf)
+    if (!info->xmit_buf)
 	return;
 
     local_irq_save(flags);
@@ -1198,7 +1187,7 @@
 	return 0;
     }
 	
-    if (!tty || !info->xmit_buf || !tmp_buf){
+    if (!info->xmit_buf){
         return 0;
     }
 
@@ -1983,13 +1972,6 @@
     tty->driver_data = info;
     info->tty = tty;
 
-    if (!tmp_buf) {
-	tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
-	if (!tmp_buf){
-	    return -ENOMEM;
-        }
-    }
-
     /*
      * Start up serial port
      */
@@ -2158,7 +2140,7 @@
 					rcor >> 5, rbpr);
 } /* serial_console_init */
 
-static struct tty_operations cy_ops = {
+static const struct tty_operations cy_ops = {
 	.open = cy_open,
 	.close = cy_close,
 	.write = cy_write,
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index d12d4f6..864854c 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -220,7 +220,7 @@
 			       " Sending SIGPWR to init...\n");
 
 		/* give a SIGPWR signal to init proc */
-		kill_proc(1, SIGPWR, 0);
+		kill_cad_pid(SIGPWR, 0);
 	} else {
 		/* print to system log */
 		printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index f52c7c3..902c48d 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2363,7 +2363,7 @@
 	func_exit();
 }
 
-static struct tty_operations sx_ops = {
+static const struct tty_operations sx_ops = {
 	.open  = sx_open,
 	.close = sx_close,
 	.write = sx_write,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 3beb220..bd71153 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -2993,7 +2993,7 @@
 	return(rc);
 }
 
-static struct tty_operations stl_ops = {
+static const struct tty_operations stl_ops = {
 	.open = stl_open,
 	.close = stl_close,
 	.write = stl_write,
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index e1cd2bc..57e31e5 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2226,7 +2226,7 @@
 	return 1;
 }
 
-static struct tty_operations sx_ops = {
+static const struct tty_operations sx_ops = {
 	.break_ctl = sx_break,
 	.open	= sx_open,
 	.close = gs_close,
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 78b1b1a..38d9498 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -87,7 +87,6 @@
 
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <asm/serial.h>
 
 #include <linux/delay.h>
 #include <linux/ioctl.h>
@@ -4360,7 +4359,7 @@
 
 }	/* end of mgsl_allocate_device()*/
 
-static struct tty_operations mgsl_ops = {
+static const struct tty_operations mgsl_ops = {
 	.open = mgsl_open,
 	.close = mgsl_close,
 	.write = mgsl_write,
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 78bc851..bdc7cb2 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -3441,7 +3441,7 @@
 {
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
 	.open = open,
 	.close = close,
 	.write = write,
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 66f3754..6eb75dc 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -3929,7 +3929,7 @@
 	}
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
 	.open = open,
 	.close = close,
 	.write = write,
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index d30dc09..9df0ca1 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -224,14 +224,16 @@
 {
 	int i;
 	int seq[] = { 0x00, 0x20, 0x10, 0x30 };
+	int data;
 
 	for (i = 3; i >= 0; i--) {
 		outbyte(3, minor);
 		outbyte(i, minor);
 		udelay(delay);
+		data = inbyte(minor) & 0x30;
 		pr_debug("tipar: Probing -> %i: 0x%02x 0x%02x\n", i,
-			data & 0x30, seq[i]);
-		if ((inbyte(minor) & 0x30) != seq[i]) {
+			data, seq[i]);
+		if (data != seq[i]) {
 			outbyte(3, minor);
 			return -1;
 		}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 33374177..e90ea39 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -3680,7 +3680,8 @@
 	kfree(driver);
 }
 
-void tty_set_operations(struct tty_driver *driver, struct tty_operations *op)
+void tty_set_operations(struct tty_driver *driver,
+			const struct tty_operations *op)
 {
 	driver->open = op->open;
 	driver->close = op->close;
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index f3efeaf..a362ee9 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -1047,7 +1047,7 @@
 			0, 0, 0, 0);
 }
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
 	.open = viotty_open,
 	.close = viotty_close,
 	.write = viotty_write,
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index bfe5ea9..c2ca31e 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -113,7 +113,7 @@
 };
 
 
-static struct tty_operations scc_ops = {
+static const struct tty_operations scc_ops = {
 	.open	= scc_open,
 	.close = gs_close,
 	.write = gs_write,
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index fb75da9..8e4413f 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -106,7 +106,8 @@
 #define MAX_NR_CON_DRIVER 16
 
 #define CON_DRIVER_FLAG_MODULE 1
-#define CON_DRIVER_FLAG_INIT 2
+#define CON_DRIVER_FLAG_INIT   2
+#define CON_DRIVER_FLAG_ATTR   4
 
 struct con_driver {
 	const struct consw *con;
@@ -138,14 +139,6 @@
 extern void vcs_make_sysfs(struct tty_struct *tty);
 extern void vcs_remove_sysfs(struct tty_struct *tty);
 
-extern void console_map_init(void);
-#ifdef CONFIG_PROM_CONSOLE
-extern void prom_con_init(void);
-#endif
-#ifdef CONFIG_MDA_CONSOLE
-extern int mda_console_init(void);
-#endif
-
 struct vc vc_cons [MAX_NR_CONSOLES];
 
 #ifndef VT_SINGLE_DRIVER
@@ -903,6 +896,7 @@
 	if (vc_cons_allocated(currcons)) {
 		struct vc_data *vc = vc_cons[currcons].d;
 		vc->vc_sw->con_deinit(vc);
+		put_pid(vc->vt_pid);
 		module_put(vc->vc_sw->owner);
 		if (vc->vc_kmalloced)
 			kfree(vc->vc_screenbuf);
@@ -2674,7 +2668,7 @@
 }
 console_initcall(con_init);
 
-static struct tty_operations con_ops = {
+static const struct tty_operations con_ops = {
 	.open = con_open,
 	.close = con_close,
 	.write = con_write,
@@ -3069,22 +3063,37 @@
 static int vtconsole_init_class_device(struct con_driver *con)
 {
 	int i;
+	int error = 0;
 
+	con->flag |= CON_DRIVER_FLAG_ATTR;
 	class_set_devdata(con->class_dev, con);
-	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_create_file(con->class_dev,
+	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+		error = class_device_create_file(con->class_dev,
 					 &class_device_attrs[i]);
+		if (error)
+			break;
+	}
 
-	return 0;
+	if (error) {
+		while (--i >= 0)
+			class_device_remove_file(con->class_dev,
+					 &class_device_attrs[i]);
+		con->flag &= ~CON_DRIVER_FLAG_ATTR;
+	}
+
+	return error;
 }
 
 static void vtconsole_deinit_class_device(struct con_driver *con)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_remove_file(con->class_dev,
-					 &class_device_attrs[i]);
+	if (con->flag & CON_DRIVER_FLAG_ATTR) {
+		for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+			class_device_remove_file(con->class_dev,
+						 &class_device_attrs[i]);
+		con->flag &= ~CON_DRIVER_FLAG_ATTR;
+	}
 }
 
 /**
@@ -3183,6 +3192,7 @@
 	} else {
 		vtconsole_init_class_device(con_driver);
 	}
+
 err:
 	release_console_sem();
 	module_put(owner);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index a53e382..ac5d60e 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -645,13 +645,16 @@
 	 */
 	case KDSIGACCEPT:
 	{
-		extern int spawnpid, spawnsig;
 		if (!perm || !capable(CAP_KILL))
 		  return -EPERM;
 		if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
 		  return -EINVAL;
-		spawnpid = current->pid;
-		spawnsig = arg;
+
+		spin_lock_irq(&vt_spawn_con.lock);
+		put_pid(vt_spawn_con.pid);
+		vt_spawn_con.pid = get_pid(task_pid(current));
+		vt_spawn_con.sig = arg;
+		spin_unlock_irq(&vt_spawn_con.lock);
 		return 0;
 	}
 
@@ -669,7 +672,7 @@
 		vc->vt_mode = tmp;
 		/* the frsig is ignored, so we set it to 0 */
 		vc->vt_mode.frsig = 0;
-		vc->vt_pid = current->pid;
+		put_pid(xchg(&vc->vt_pid, get_pid(task_pid(current))));
 		/* no switch is required -- saw@shade.msu.ru */
 		vc->vt_newvt = -1;
 		release_console_sem();
@@ -1060,7 +1063,7 @@
 	vc->vt_mode.relsig = 0;
 	vc->vt_mode.acqsig = 0;
 	vc->vt_mode.frsig = 0;
-	vc->vt_pid = -1;
+	put_pid(xchg(&vc->vt_pid, NULL));
 	vc->vt_newvt = -1;
 	if (!in_interrupt())    /* Via keyboard.c:SAK() - akpm */
 		reset_palette(vc);
@@ -1111,7 +1114,7 @@
 		 * tell us if the process has gone or something else
 		 * is awry
 		 */
-		if (kill_proc(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
+		if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
 		/*
 		 * The controlling process has died, so we revert back to
 		 * normal operation. In this case, we'll also change back
@@ -1171,7 +1174,7 @@
 		 * tell us if the process has gone or something else
 		 * is awry
 		 */
-		if (kill_proc(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
+		if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
 			/*
 			 * It worked. Mark the vt to switch to and
 			 * return. The process needs to send us a
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 77ab7e0..89e46d6d 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -172,6 +172,17 @@
 	  Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog.  Say 'Y' here to
 	  enable the OMAP1610/OMAP1710 watchdog timer.
 
+config PNX4008_WATCHDOG
+	tristate "PNX4008 Watchdog"
+	depends on WATCHDOG && ARCH_PNX4008
+	help
+	  Say Y here if to include support for the watchdog timer
+	  in the PNX4008 processor.
+	  This driver can be built as a module by choosing M. The module
+	  will be called pnx4008_wdt.
+
+	  Say N if you are unsure.
+
 # X86 (i386 + ia64 + x86_64) Architecture
 
 config ACQUIRE_WDT
@@ -305,6 +316,27 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called i8xx_tco.
 
+config ITCO_WDT
+	tristate "Intel TCO Timer/Watchdog (EXPERIMENTAL)"
+	depends on WATCHDOG && (X86 || IA64) && PCI && EXPERIMENTAL
+	---help---
+	  Hardware driver for the intel TCO timer based watchdog devices.
+	  These drivers are included in the Intel 82801 I/O Controller
+	  Hub family 'from ICH0 up to ICH7) and in the Intel 6300ESB
+	  controller hub.
+
+	  The TCO (Total Cost of Ownership) timer is a watchdog timer
+	  that will reboot the machine after its second expiration. The
+	  expiration time can be configured with the "heartbeat" parameter.
+
+	  On some motherboards the driver may fail to reset the chipset's
+	  NO_REBOOT flag which prevents the watchdog from rebooting the
+	  machine. If this is the case you will get a kernel message like
+	  "failed to reset NO_REBOOT flag, reboot disabled by hardware".
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iTCO_wdt.
+
 config SC1200_WDT
 	tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
 	depends on WATCHDOG && X86
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 5099f8b..7f70aba 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -33,6 +33,7 @@
 obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
 obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
 obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
+obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
 
 # X86 (i386 + ia64 + x86_64) Architecture
 obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
@@ -46,6 +47,7 @@
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
 obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
 obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
+obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
 obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
index c77fe3c..154d67e 100644
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/char/watchdog/acquirewdt.c
@@ -183,7 +183,7 @@
 	}
 
 	default:
-	  return -ENOIOCTLCMD;
+	  return -ENOTTY;
 	}
 }
 
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
index 8069be4..9d73276 100644
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/char/watchdog/advantechwdt.c
@@ -176,7 +176,7 @@
 	}
 
 	default:
-	  return -ENOIOCTLCMD;
+	  return -ENOTTY;
 	}
 	return 0;
 }
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index c5c94e4..01b0d13 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -236,7 +236,7 @@
 			return put_user(timeout, p);
 
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 }
 
@@ -330,17 +330,20 @@
 	u32 wdog;
 
 	/* Check for a 1535 series bridge */
-	pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
+	pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
 	if(pdev == NULL)
 		return -ENODEV;
+	pci_dev_put(pdev);
 
 	/* Check for the a 7101 PMU */
-	pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
+	pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
 	if(pdev == NULL)
 		return -ENODEV;
 
-	if(pci_enable_device(pdev))
+	if(pci_enable_device(pdev)) {
+		pci_dev_put(pdev);
 		return -EIO;
+	}
 
 	ali_pci = pdev;
 
@@ -447,6 +450,7 @@
 	/* Deregister */
 	unregister_reboot_notifier(&ali_notifier);
 	misc_deregister(&ali_miscdev);
+	pci_dev_put(ali_pci);
 }
 
 module_init(watchdog_init);
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index ffd7684..5948863 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -277,7 +277,7 @@
 		case WDIOC_GETTIMEOUT:
 			return put_user(timeout, p);
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 }
 
@@ -333,6 +333,7 @@
 	/* Deregister */
 	misc_deregister(&wdt_miscdev);
 	unregister_reboot_notifier(&wdt_notifier);
+	pci_dev_put(alim7101_pmu);
 }
 
 static int __init alim7101_wdt_init(void)
@@ -342,7 +343,8 @@
 	char tmp;
 
 	printk(KERN_INFO PFX "Steve Hill <steve@navaho.co.uk>.\n");
-	alim7101_pmu = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,NULL);
+	alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+		NULL);
 	if (!alim7101_pmu) {
 		printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n");
 		return -EBUSY;
@@ -351,21 +353,23 @@
 	/* Set the WDT in the PMU to 1 second */
 	pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02);
 
-	ali1543_south = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+	ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+		NULL);
 	if (!ali1543_south) {
 		printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n");
-		return -EBUSY;
+		goto err_out;
 	}
 	pci_read_config_byte(ali1543_south, 0x5e, &tmp);
+	pci_dev_put(ali1543_south);
 	if ((tmp & 0x1e) == 0x00) {
 		if (!use_gpio) {
 			printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'.  If this is a cobalt board, set the 'use_gpio' module parameter.\n");
-			return -EBUSY;
+			goto err_out;
 		} 
 		nowayout = 1;
 	} else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
 		printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
-		return -EBUSY;
+		goto err_out;
 	}
 
 	if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */
@@ -404,6 +408,7 @@
 err_out_miscdev:
 	misc_deregister(&wdt_miscdev);
 err_out:
+	pci_dev_put(alim7101_pmu);
 	return rc;
 }
 
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c
index cc26671..4e7a114 100644
--- a/drivers/char/watchdog/at91_wdt.c
+++ b/drivers/char/watchdog/at91_wdt.c
@@ -168,7 +168,7 @@
 			return 0;
 
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 }
 
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index e3cefc5..4889022 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -125,7 +125,7 @@
 			return -EINVAL;
 		return 0;
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 
 	return 0;
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index 04c7e49..00bdabb 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -183,7 +183,7 @@
 			}
 			break;
 		default:
-    			return -ENOIOCTLCMD;
+    			return -ENOTTY;
 	}
 	return 0;
 }
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c
index 77c8a95..01cf123 100644
--- a/drivers/char/watchdog/ep93xx_wdt.c
+++ b/drivers/char/watchdog/ep93xx_wdt.c
@@ -144,7 +144,7 @@
 ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		 unsigned long arg)
 {
-	int ret = -ENOIOCTLCMD;
+	int ret = -ENOTTY;
 
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index 62dbccb..4f42697 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -240,7 +240,7 @@
 
 	switch(cmd) {
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 
 	case WDIOC_GETSUPPORT:
 		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
index 870539e..fb64df4 100644
--- a/drivers/char/watchdog/i6300esb.c
+++ b/drivers/char/watchdog/i6300esb.c
@@ -315,7 +315,7 @@
                         return put_user(heartbeat, p);
 
                 default:
-                        return -ENOIOCTLCMD;
+                        return -ENOTTY;
         }
 }
 
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index 8385dd3..e0627d7 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -356,7 +356,7 @@
 		}
 
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 }
 
@@ -406,18 +406,18 @@
  * want to register another driver on the same PCI id.
  */
 static struct pci_device_id i8xx_tco_pci_tbl[] = {
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1,	PCI_ANY_ID, PCI_ANY_ID, },
-	{ 0, },			/* End of list */
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1) },
+	{ },			/* End of list */
 };
 MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl);
 
@@ -434,12 +434,11 @@
 	 *      Find the PCI device
 	 */
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	for_each_pci_dev(dev)
 		if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
 			i8xx_tco_pci = dev;
 			break;
 		}
-	}
 
 	if (i8xx_tco_pci) {
 		/*
@@ -454,6 +453,7 @@
 		/* Something's wrong here, ACPIBASE has to be set */
 		if (badr == 0x0001 || badr == 0x0000) {
 			printk (KERN_ERR PFX "failed to get TCOBASE address\n");
+			pci_dev_put(i8xx_tco_pci);
 			return 0;
 		}
 
@@ -465,6 +465,7 @@
 			pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
 			if (val1 & 0x02) {
 				printk (KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+				pci_dev_put(i8xx_tco_pci);
 				return 0;	/* Cannot reset NO_REBOOT bit */
 			}
 		}
@@ -476,6 +477,7 @@
 		if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) {
 			printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
 				SMI_EN + 1);
+			pci_dev_put(i8xx_tco_pci);
 			return 0;
 		}
 		val1 = inb (SMI_EN + 1);
@@ -542,6 +544,7 @@
 unreg_region:
 	release_region (TCOBASE, 0x10);
 out:
+	pci_dev_put(i8xx_tco_pci);
 	return ret;
 }
 
@@ -555,6 +558,8 @@
 	misc_deregister (&i8xx_tco_miscdev);
 	unregister_reboot_notifier(&i8xx_tco_notifier);
 	release_region (TCOBASE, 0x10);
+
+	pci_dev_put(i8xx_tco_pci);
 }
 
 module_init(watchdog_init);
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
new file mode 100644
index 0000000..8f89948
--- /dev/null
+++ b/drivers/char/watchdog/iTCO_wdt.c
@@ -0,0 +1,735 @@
+/*
+ *	intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
+ *
+ *	(c) Copyright 2006 Wim Van Sebroeck <wim@iguana.be>.
+ *
+ *	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.
+ *
+ *	Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
+ *	provide warranty for any of this software. This material is
+ *	provided "AS-IS" and at no charge.
+ *
+ *	The TCO watchdog is implemented in the following I/O controller hubs:
+ *	(See the intel documentation on http://developer.intel.com.)
+ *	82801AA  (ICH)       : document number 290655-003, 290677-014,
+ *	82801AB  (ICHO)      : document number 290655-003, 290677-014,
+ *	82801BA  (ICH2)      : document number 290687-002, 298242-027,
+ *	82801BAM (ICH2-M)    : document number 290687-002, 298242-027,
+ *	82801CA  (ICH3-S)    : document number 290733-003, 290739-013,
+ *	82801CAM (ICH3-M)    : document number 290716-001, 290718-007,
+ *	82801DB  (ICH4)      : document number 290744-001, 290745-020,
+ *	82801DBM (ICH4-M)    : document number 252337-001, 252663-005,
+ *	82801E   (C-ICH)     : document number 273599-001, 273645-002,
+ *	82801EB  (ICH5)      : document number 252516-001, 252517-003,
+ *	82801ER  (ICH5R)     : document number 252516-001, 252517-003,
+ *	82801FB  (ICH6)      : document number 301473-002, 301474-007,
+ *	82801FR  (ICH6R)     : document number 301473-002, 301474-007,
+ *	82801FBM (ICH6-M)    : document number 301473-002, 301474-007,
+ *	82801FW  (ICH6W)     : document number 301473-001, 301474-007,
+ *	82801FRW (ICH6RW)    : document number 301473-001, 301474-007,
+ *	82801GB  (ICH7)      : document number 307013-002, 307014-009,
+ *	82801GR  (ICH7R)     : document number 307013-002, 307014-009,
+ *	82801GDH (ICH7DH)    : document number 307013-002, 307014-009,
+ *	82801GBM (ICH7-M)    : document number 307013-002, 307014-009,
+ *	82801GHM (ICH7-M DH) : document number 307013-002, 307014-009,
+ *	6300ESB  (6300ESB)   : document number 300641-003
+ */
+
+/*
+ *	Includes, defines, variables, module parameters, ...
+ */
+
+/* Module and version information */
+#define DRV_NAME        "iTCO_wdt"
+#define DRV_VERSION     "1.00"
+#define DRV_RELDATE     "30-Jul-2006"
+#define PFX		DRV_NAME ": "
+
+/* Includes */
+#include <linux/config.h>		/* For CONFIG_WATCHDOG_NOWAYOUT/... */
+#include <linux/module.h>		/* For module specific items */
+#include <linux/moduleparam.h>		/* For new moduleparam's */
+#include <linux/types.h>		/* For standard types (like size_t) */
+#include <linux/errno.h>		/* For the -ENODEV/... values */
+#include <linux/kernel.h>		/* For printk/panic/... */
+#include <linux/miscdevice.h>		/* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
+#include <linux/watchdog.h>		/* For the watchdog specific items */
+#include <linux/init.h>			/* For __init/__exit/... */
+#include <linux/fs.h>			/* For file operations */
+#include <linux/platform_device.h>	/* For platform_driver framework */
+#include <linux/pci.h>			/* For pci functions */
+#include <linux/ioport.h>		/* For io-port access */
+#include <linux/spinlock.h>		/* For spin_lock/spin_unlock/... */
+
+#include <asm/uaccess.h>		/* For copy_to_user/put_user/... */
+#include <asm/io.h>			/* For inb/outb/... */
+
+/* TCO related info */
+enum iTCO_chipsets {
+	TCO_ICH = 0,	/* ICH */
+	TCO_ICH0,	/* ICH0 */
+	TCO_ICH2,	/* ICH2 */
+	TCO_ICH2M,	/* ICH2-M */
+	TCO_ICH3,	/* ICH3-S */
+	TCO_ICH3M,	/* ICH3-M */
+	TCO_ICH4,	/* ICH4 */
+	TCO_ICH4M,	/* ICH4-M */
+	TCO_CICH,	/* C-ICH */
+	TCO_ICH5,	/* ICH5 & ICH5R */
+	TCO_6300ESB,	/* 6300ESB */
+	TCO_ICH6,	/* ICH6 & ICH6R */
+	TCO_ICH6M,	/* ICH6-M */
+	TCO_ICH6W,	/* ICH6W & ICH6RW */
+	TCO_ICH7,	/* ICH7 & ICH7R */
+	TCO_ICH7M,	/* ICH7-M */
+	TCO_ICH7MDH,	/* ICH7-M DH */
+};
+
+static struct {
+	char *name;
+	unsigned int iTCO_version;
+} iTCO_chipset_info[] __devinitdata = {
+	{"ICH", 1},
+	{"ICH0", 1},
+	{"ICH2", 1},
+	{"ICH2-M", 1},
+	{"ICH3-S", 1},
+	{"ICH3-M", 1},
+	{"ICH4", 1},
+	{"ICH4-M", 1},
+	{"C-ICH", 1},
+	{"ICH5 or ICH5R", 1},
+	{"6300ESB", 1},
+	{"ICH6 or ICH6R", 2},
+	{"ICH6-M", 2},
+	{"ICH6W or ICH6RW", 2},
+	{"ICH7 or ICH7R", 2},
+	{"ICH7-M", 2},
+	{"ICH7-M DH", 2},
+	{NULL,0}
+};
+
+/*
+ * This data only exists for exporting the supported PCI ids
+ * via MODULE_DEVICE_TABLE.  We do not actually register a
+ * pci_driver, because the I/O Controller Hub has also other
+ * functions that probably will be registered by other drivers.
+ */
+static struct pci_device_id iTCO_wdt_pci_tbl[] = {
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH     },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH0    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH2    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH2M   },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH3    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH3M   },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH4    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH4M   },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_CICH    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH5    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_6300ESB },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH6    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH6M   },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH6W   },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M   },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH },
+	{ 0, },			/* End of list */
+};
+MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
+
+/* Address definitions for the TCO */
+#define	TCOBASE		iTCO_wdt_private.ACPIBASE + 0x60	/* TCO base address                */
+#define	SMI_EN		iTCO_wdt_private.ACPIBASE + 0x30	/* SMI Control and Enable Register */
+
+#define TCO_RLD		TCOBASE + 0x00	/* TCO Timer Reload and Current Value */
+#define TCOv1_TMR	TCOBASE + 0x01	/* TCOv1 Timer Initial Value	*/
+#define	TCO_DAT_IN	TCOBASE + 0x02	/* TCO Data In Register		*/
+#define	TCO_DAT_OUT	TCOBASE + 0x03	/* TCO Data Out Register	*/
+#define	TCO1_STS	TCOBASE + 0x04	/* TCO1 Status Register		*/
+#define	TCO2_STS	TCOBASE + 0x06	/* TCO2 Status Register		*/
+#define TCO1_CNT	TCOBASE + 0x08	/* TCO1 Control Register	*/
+#define TCO2_CNT	TCOBASE + 0x0a	/* TCO2 Control Register	*/
+#define TCOv2_TMR	TCOBASE + 0x12	/* TCOv2 Timer Initial Value	*/
+
+/* internal variables */
+static unsigned long is_active;
+static char expect_release;
+static struct {				/* this is private data for the iTCO_wdt device */
+	unsigned int iTCO_version;	/* TCO version/generation */
+	unsigned long ACPIBASE;		/* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
+	unsigned long __iomem *gcs;	/* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2) */
+	spinlock_t io_lock;		/* the lock for io operations */
+	struct pci_dev *pdev;		/* the PCI-device */
+} iTCO_wdt_private;
+
+static struct platform_device *iTCO_wdt_platform_device;	/* the watchdog platform device */
+
+/* module parameters */
+#define WATCHDOG_HEARTBEAT 30	/* 30 sec default heartbeat */
+static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Some TCO specific functions
+ */
+
+static inline unsigned int seconds_to_ticks(int seconds)
+{
+	/* the internal timer is stored as ticks which decrement
+	 * every 0.6 seconds */
+	return (seconds * 10) / 6;
+}
+
+static void iTCO_wdt_set_NO_REBOOT_bit(void)
+{
+	u32 val32;
+
+	/* Set the NO_REBOOT bit: this disables reboots */
+	if (iTCO_wdt_private.iTCO_version == 2) {
+		val32 = readl(iTCO_wdt_private.gcs);
+		val32 |= 0x00000020;
+		writel(val32, iTCO_wdt_private.gcs);
+	} else if (iTCO_wdt_private.iTCO_version == 1) {
+		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
+		val32 |= 0x00000002;
+		pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
+	}
+}
+
+static int iTCO_wdt_unset_NO_REBOOT_bit(void)
+{
+	int ret = 0;
+	u32 val32;
+
+	/* Unset the NO_REBOOT bit: this enables reboots */
+	if (iTCO_wdt_private.iTCO_version == 2) {
+		val32 = readl(iTCO_wdt_private.gcs);
+		val32 &= 0xffffffdf;
+		writel(val32, iTCO_wdt_private.gcs);
+
+		val32 = readl(iTCO_wdt_private.gcs);
+		if (val32 & 0x00000020)
+			ret = -EIO;
+	} else if (iTCO_wdt_private.iTCO_version == 1) {
+		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
+		val32 &= 0xfffffffd;
+		pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
+
+		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
+		if (val32 & 0x00000002)
+			ret = -EIO;
+	}
+
+	return ret; /* returns: 0 = OK, -EIO = Error */
+}
+
+static int iTCO_wdt_start(void)
+{
+	unsigned int val;
+
+	spin_lock(&iTCO_wdt_private.io_lock);
+
+	/* disable chipset's NO_REBOOT bit */
+	if (iTCO_wdt_unset_NO_REBOOT_bit()) {
+		printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+		return -EIO;
+	}
+
+	/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */
+	val = inw(TCO1_CNT);
+	val &= 0xf7ff;
+	outw(val, TCO1_CNT);
+	val = inw(TCO1_CNT);
+	spin_unlock(&iTCO_wdt_private.io_lock);
+
+	if (val & 0x0800)
+		return -1;
+	return 0;
+}
+
+static int iTCO_wdt_stop(void)
+{
+	unsigned int val;
+
+	spin_lock(&iTCO_wdt_private.io_lock);
+
+	/* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */
+	val = inw(TCO1_CNT);
+	val |= 0x0800;
+	outw(val, TCO1_CNT);
+	val = inw(TCO1_CNT);
+
+	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+	iTCO_wdt_set_NO_REBOOT_bit();
+
+	spin_unlock(&iTCO_wdt_private.io_lock);
+
+	if ((val & 0x0800) == 0)
+		return -1;
+	return 0;
+}
+
+static int iTCO_wdt_keepalive(void)
+{
+	spin_lock(&iTCO_wdt_private.io_lock);
+
+	/* Reload the timer by writing to the TCO Timer Counter register */
+	if (iTCO_wdt_private.iTCO_version == 2) {
+		outw(0x01, TCO_RLD);
+	} else if (iTCO_wdt_private.iTCO_version == 1) {
+		outb(0x01, TCO_RLD);
+	}
+
+	spin_unlock(&iTCO_wdt_private.io_lock);
+	return 0;
+}
+
+static int iTCO_wdt_set_heartbeat(int t)
+{
+	unsigned int val16;
+	unsigned char val8;
+	unsigned int tmrval;
+
+	tmrval = seconds_to_ticks(t);
+	/* from the specs: */
+	/* "Values of 0h-3h are ignored and should not be attempted" */
+	if (tmrval < 0x04)
+		return -EINVAL;
+	if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) ||
+	    ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
+		return -EINVAL;
+
+	/* Write new heartbeat to watchdog */
+	if (iTCO_wdt_private.iTCO_version == 2) {
+		spin_lock(&iTCO_wdt_private.io_lock);
+		val16 = inw(TCOv2_TMR);
+		val16 &= 0xfc00;
+		val16 |= tmrval;
+		outw(val16, TCOv2_TMR);
+		val16 = inw(TCOv2_TMR);
+		spin_unlock(&iTCO_wdt_private.io_lock);
+
+		if ((val16 & 0x3ff) != tmrval)
+			return -EINVAL;
+	} else if (iTCO_wdt_private.iTCO_version == 1) {
+		spin_lock(&iTCO_wdt_private.io_lock);
+		val8 = inb(TCOv1_TMR);
+		val8 &= 0xc0;
+		val8 |= (tmrval & 0xff);
+		outb(val8, TCOv1_TMR);
+		val8 = inb(TCOv1_TMR);
+		spin_unlock(&iTCO_wdt_private.io_lock);
+
+		if ((val8 & 0x3f) != tmrval)
+			return -EINVAL;
+	}
+
+	heartbeat = t;
+	return 0;
+}
+
+static int iTCO_wdt_get_timeleft (int *time_left)
+{
+	unsigned int val16;
+	unsigned char val8;
+
+	/* read the TCO Timer */
+	if (iTCO_wdt_private.iTCO_version == 2) {
+		spin_lock(&iTCO_wdt_private.io_lock);
+		val16 = inw(TCO_RLD);
+		val16 &= 0x3ff;
+		spin_unlock(&iTCO_wdt_private.io_lock);
+
+		*time_left = (val16 * 6) / 10;
+	} else if (iTCO_wdt_private.iTCO_version == 1) {
+		spin_lock(&iTCO_wdt_private.io_lock);
+		val8 = inb(TCO_RLD);
+		val8 &= 0x3f;
+		spin_unlock(&iTCO_wdt_private.io_lock);
+
+		*time_left = (val8 * 6) / 10;
+	}
+	return 0;
+}
+
+/*
+ *	/dev/watchdog handling
+ */
+
+static int iTCO_wdt_open (struct inode *inode, struct file *file)
+{
+	/* /dev/watchdog can only be opened once */
+	if (test_and_set_bit(0, &is_active))
+		return -EBUSY;
+
+	/*
+	 *      Reload and activate timer
+	 */
+	iTCO_wdt_keepalive();
+	iTCO_wdt_start();
+	return nonseekable_open(inode, file);
+}
+
+static int iTCO_wdt_release (struct inode *inode, struct file *file)
+{
+	/*
+	 *      Shut off the timer.
+	 */
+	if (expect_release == 42) {
+		iTCO_wdt_stop();
+	} else {
+		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+		iTCO_wdt_keepalive();
+	}
+	clear_bit(0, &is_active);
+	expect_release = 0;
+	return 0;
+}
+
+static ssize_t iTCO_wdt_write (struct file *file, const char __user *data,
+			      size_t len, loff_t * ppos)
+{
+	/* See if we got the magic character 'V' and reload the timer */
+	if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			/* note: just in case someone wrote the magic character
+			 * five months ago... */
+			expect_release = 0;
+
+			/* scan to see whether or not we got the magic character */
+			for (i = 0; i != len; i++) {
+				char c;
+				if (get_user(c, data+i))
+					return -EFAULT;
+				if (c == 'V')
+					expect_release = 42;
+			}
+		}
+
+		/* someone wrote to us, we should reload the timer */
+		iTCO_wdt_keepalive();
+	}
+	return len;
+}
+
+static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg)
+{
+	int new_options, retval = -EINVAL;
+	int new_heartbeat;
+	int time_left;
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	static struct watchdog_info ident = {
+		.options =		WDIOF_SETTIMEOUT |
+					WDIOF_KEEPALIVEPING |
+					WDIOF_MAGICCLOSE,
+		.firmware_version =	0,
+		.identity =		DRV_NAME,
+	};
+
+	switch (cmd) {
+		case WDIOC_GETSUPPORT:
+			return copy_to_user(argp, &ident,
+				sizeof (ident)) ? -EFAULT : 0;
+
+		case WDIOC_GETSTATUS:
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0, p);
+
+		case WDIOC_KEEPALIVE:
+			iTCO_wdt_keepalive();
+			return 0;
+
+		case WDIOC_SETOPTIONS:
+		{
+			if (get_user(new_options, p))
+				return -EFAULT;
+
+			if (new_options & WDIOS_DISABLECARD) {
+				iTCO_wdt_stop();
+				retval = 0;
+			}
+
+			if (new_options & WDIOS_ENABLECARD) {
+				iTCO_wdt_keepalive();
+				iTCO_wdt_start();
+				retval = 0;
+			}
+
+			return retval;
+		}
+
+		case WDIOC_SETTIMEOUT:
+		{
+			if (get_user(new_heartbeat, p))
+				return -EFAULT;
+
+			if (iTCO_wdt_set_heartbeat(new_heartbeat))
+				return -EINVAL;
+
+			iTCO_wdt_keepalive();
+			/* Fall */
+		}
+
+		case WDIOC_GETTIMEOUT:
+			return put_user(heartbeat, p);
+
+		case WDIOC_GETTIMELEFT:
+		{
+			if (iTCO_wdt_get_timeleft(&time_left))
+				return -EINVAL;
+
+			return put_user(time_left, p);
+		}
+
+		default:
+			return -ENOTTY;
+	}
+}
+
+/*
+ *	Kernel Interfaces
+ */
+
+static struct file_operations iTCO_wdt_fops = {
+	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
+	.write =	iTCO_wdt_write,
+	.ioctl =	iTCO_wdt_ioctl,
+	.open =		iTCO_wdt_open,
+	.release =	iTCO_wdt_release,
+};
+
+static struct miscdevice iTCO_wdt_miscdev = {
+	.minor =	WATCHDOG_MINOR,
+	.name =		"watchdog",
+	.fops =		&iTCO_wdt_fops,
+};
+
+/*
+ *	Init & exit routines
+ */
+
+static int iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, struct platform_device *dev)
+{
+	int ret;
+	u32 base_address;
+	unsigned long RCBA;
+	unsigned long val32;
+
+	/*
+	 *      Find the ACPI/PM base I/O address which is the base
+	 *      for the TCO registers (TCOBASE=ACPIBASE + 0x60)
+	 *      ACPIBASE is bits [15:7] from 0x40-0x43
+	 */
+	pci_read_config_dword(pdev, 0x40, &base_address);
+	base_address &= 0x00007f80;
+	if (base_address == 0x00000000) {
+		/* Something's wrong here, ACPIBASE has to be set */
+		printk(KERN_ERR PFX "failed to get TCOBASE address\n");
+		pci_dev_put(pdev);
+		return -ENODEV;
+	}
+	iTCO_wdt_private.iTCO_version = iTCO_chipset_info[ent->driver_data].iTCO_version;
+	iTCO_wdt_private.ACPIBASE = base_address;
+	iTCO_wdt_private.pdev = pdev;
+
+	/* Get the Memory-Mapped GCS register, we need it for the NO_REBOOT flag (TCO v2) */
+	/* To get access to it you have to read RCBA from PCI Config space 0xf0
+	   and use it as base. GCS = RCBA + ICH6_GCS(0x3410). */
+	if (iTCO_wdt_private.iTCO_version == 2) {
+		pci_read_config_dword(pdev, 0xf0, &base_address);
+		RCBA = base_address & 0xffffc000;
+		iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410),4);
+	}
+
+	/* Check chipset's NO_REBOOT bit */
+	if (iTCO_wdt_unset_NO_REBOOT_bit()) {
+		printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+		ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
+		goto out;
+	}
+
+	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+	iTCO_wdt_set_NO_REBOOT_bit();
+
+	/* Set the TCO_EN bit in SMI_EN register */
+	if (!request_region(SMI_EN, 4, "iTCO_wdt")) {
+		printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n",
+			SMI_EN );
+		ret = -EIO;
+		goto out;
+	}
+	val32 = inl(SMI_EN);
+	val32 &= 0xffffdfff;	/* Turn off SMI clearing watchdog */
+	outl(val32, SMI_EN);
+	release_region(SMI_EN, 4);
+
+	/* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */
+	if (!request_region (TCOBASE, 0x20, "iTCO_wdt")) {
+		printk (KERN_ERR PFX "I/O address 0x%04lx already in use\n",
+			TCOBASE);
+		ret = -EIO;
+		goto out;
+	}
+
+	printk(KERN_INFO PFX "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
+		iTCO_chipset_info[ent->driver_data].name,
+		iTCO_chipset_info[ent->driver_data].iTCO_version,
+		TCOBASE);
+
+	/* Clear out the (probably old) status */
+	outb(0, TCO1_STS);
+	outb(3, TCO2_STS);
+
+	/* Make sure the watchdog is not running */
+	iTCO_wdt_stop();
+
+	/* Check that the heartbeat value is within it's range ; if not reset to the default */
+	if (iTCO_wdt_set_heartbeat(heartbeat)) {
+		iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
+		printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39 (TCO v1) or 613 (TCO v2), using %d\n",
+			heartbeat);
+	}
+
+	ret = misc_register(&iTCO_wdt_miscdev);
+	if (ret != 0) {
+		printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+			WATCHDOG_MINOR, ret);
+		goto unreg_region;
+	}
+
+	printk (KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
+		heartbeat, nowayout);
+
+	return 0;
+
+unreg_region:
+	release_region (TCOBASE, 0x20);
+out:
+	if (iTCO_wdt_private.iTCO_version == 2)
+		iounmap(iTCO_wdt_private.gcs);
+	pci_dev_put(iTCO_wdt_private.pdev);
+	iTCO_wdt_private.ACPIBASE = 0;
+	return ret;
+}
+
+static void iTCO_wdt_cleanup(void)
+{
+	/* Stop the timer before we leave */
+	if (!nowayout)
+		iTCO_wdt_stop();
+
+	/* Deregister */
+	misc_deregister(&iTCO_wdt_miscdev);
+	release_region(TCOBASE, 0x20);
+	if (iTCO_wdt_private.iTCO_version == 2)
+		iounmap(iTCO_wdt_private.gcs);
+	pci_dev_put(iTCO_wdt_private.pdev);
+	iTCO_wdt_private.ACPIBASE = 0;
+}
+
+static int iTCO_wdt_probe(struct platform_device *dev)
+{
+	int found = 0;
+	struct pci_dev *pdev = NULL;
+	const struct pci_device_id *ent;
+
+	spin_lock_init(&iTCO_wdt_private.io_lock);
+
+	for_each_pci_dev(pdev) {
+		ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
+		if (ent) {
+			if (!(iTCO_wdt_init(pdev, ent, dev))) {
+				found++;
+				break;
+			}
+		}
+	}
+
+	if (!found) {
+		printk(KERN_INFO PFX "No card detected\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int iTCO_wdt_remove(struct platform_device *dev)
+{
+	if (iTCO_wdt_private.ACPIBASE)
+		iTCO_wdt_cleanup();
+
+	return 0;
+}
+
+static void iTCO_wdt_shutdown(struct platform_device *dev)
+{
+	iTCO_wdt_stop();
+}
+
+#define iTCO_wdt_suspend NULL
+#define iTCO_wdt_resume  NULL
+
+static struct platform_driver iTCO_wdt_driver = {
+	.probe          = iTCO_wdt_probe,
+	.remove         = iTCO_wdt_remove,
+	.shutdown       = iTCO_wdt_shutdown,
+	.suspend        = iTCO_wdt_suspend,
+	.resume         = iTCO_wdt_resume,
+	.driver         = {
+		.owner  = THIS_MODULE,
+		.name   = DRV_NAME,
+	},
+};
+
+static int __init iTCO_wdt_init_module(void)
+{
+	int err;
+
+	printk(KERN_INFO PFX "Intel TCO WatchDog Timer Driver v%s (%s)\n",
+		DRV_VERSION, DRV_RELDATE);
+
+	err = platform_driver_register(&iTCO_wdt_driver);
+	if (err)
+		return err;
+
+	iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+	if (IS_ERR(iTCO_wdt_platform_device)) {
+		err = PTR_ERR(iTCO_wdt_platform_device);
+		goto unreg_platform_driver;
+	}
+
+	return 0;
+
+unreg_platform_driver:
+	platform_driver_unregister(&iTCO_wdt_driver);
+	return err;
+}
+
+static void __exit iTCO_wdt_cleanup_module(void)
+{
+	platform_device_unregister(iTCO_wdt_platform_device);
+	platform_driver_unregister(&iTCO_wdt_driver);
+	printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
+}
+
+module_init(iTCO_wdt_init_module);
+module_exit(iTCO_wdt_cleanup_module);
+
+MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
+MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
index fd95f73..c1ed209 100644
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/char/watchdog/ib700wdt.c
@@ -199,7 +199,7 @@
 	  break;
 
 	default:
-	  return -ENOIOCTLCMD;
+	  return -ENOTTY;
 	}
 	return 0;
 }
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
index 26ceee7..dd6760f 100644
--- a/drivers/char/watchdog/ibmasr.c
+++ b/drivers/char/watchdog/ibmasr.c
@@ -295,7 +295,7 @@
 		}
 	}
 
-	return -ENOIOCTLCMD;
+	return -ENOTTY;
 }
 
 static int asr_open(struct inode *inode, struct file *file)
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
index dacc1c2..0bc2393 100644
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/char/watchdog/indydog.c
@@ -112,7 +112,7 @@
 
 	switch (cmd) {
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			if (copy_to_user((struct watchdog_info *)arg,
 					 &ident, sizeof(ident)))
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index 6929088..fd955db 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -1,5 +1,5 @@
 /*
- * drivers/watchdog/ixp2000_wdt.c
+ * drivers/char/watchdog/ixp2000_wdt.c
  *
  * Watchdog driver for Intel IXP2000 network processors
  *
@@ -107,7 +107,7 @@
 ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 			unsigned long arg)
 {
-	int ret = -ENOIOCTLCMD;
+	int ret = -ENOTTY;
 	int time;
 
 	switch (cmd) {
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c
index 9db5cf2..5864bb8 100644
--- a/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/drivers/char/watchdog/ixp4xx_wdt.c
@@ -1,5 +1,5 @@
 /*
- * drivers/watchdog/ixp4xx_wdt.c
+ * drivers/char/watchdog/ixp4xx_wdt.c
  *
  * Watchdog driver for Intel IXP4xx network processors
  *
@@ -102,7 +102,7 @@
 ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 			unsigned long arg)
 {
-	int ret = -ENOIOCTLCMD;
+	int ret = -ENOTTY;
 	int time;
 
 	switch (cmd) {
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 23734e0..276577d 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -329,7 +329,7 @@
 			break;
 
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 
 	return 0;
@@ -426,8 +426,7 @@
 	printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n");
 
 	ret = zf_get_ZFL_version();
-	printk("%#x\n", ret);
-	if((!ret) || (ret != 0xffff)){
+	if ((!ret) || (ret == 0xffff)) {
 		printk(KERN_WARNING PFX ": no ZF-Logic found\n");
 		return -ENODEV;
 	}
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index ae94332..c2dac0a 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -185,7 +185,7 @@
 			mixcomwd_ping();
 			break;
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 	return 0;
 }
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c
index a480903..18ca752 100644
--- a/drivers/char/watchdog/mpc83xx_wdt.c
+++ b/drivers/char/watchdog/mpc83xx_wdt.c
@@ -125,7 +125,7 @@
 	case WDIOC_GETTIMEOUT:
 		return put_user(timeout_sec, p);
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 }
 
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c
index 35dd9e6..8aaed10 100644
--- a/drivers/char/watchdog/mpc8xx_wdt.c
+++ b/drivers/char/watchdog/mpc8xx_wdt.c
@@ -126,7 +126,7 @@
 		break;
 
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 
 	return 0;
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index 54b3c56..02d336a 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -221,7 +221,7 @@
 	} uarg;
 
 	if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg))
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 
 	if (_IOC_DIR(cmd) & _IOC_WRITE) {
 		ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd));
@@ -271,7 +271,7 @@
 		break;
 
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 
 	if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 5c8fab3..b887cdb 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -160,7 +160,7 @@
 		break;
 
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 
 	return 0;
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index cd7d1b6..6f8515d 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -572,7 +572,7 @@
 
 	switch(cmd) {
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 
 	case WDIOC_GETSUPPORT:
 		if(copy_to_user(argp, &ident, sizeof(ident)))
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index c7cfd6d..2de6e49 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -541,7 +541,7 @@
 		}
 
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 }
 
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index b7ae73d..77662cb 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -445,7 +445,7 @@
 		}
 
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 }
 
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c
new file mode 100644
index 0000000..db2731b
--- /dev/null
+++ b/drivers/char/watchdog/pnx4008_wdt.c
@@ -0,0 +1,362 @@
+/*
+ * drivers/char/watchdog/pnx4008_wdt.c
+ *
+ * Watchdog driver for PNX4008 board
+ *
+ * Authors: Dmitry Chigirev <source@mvista.com>,
+ * 	    Vitaly Wool <vitalywool@gmail.com>
+ * Based on sa1100 driver,
+ * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * 2005-2006 (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.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define MODULE_NAME "PNX4008-WDT: "
+
+/* WatchDog Timer - Chapter 23 Page 207 */
+
+#define DEFAULT_HEARTBEAT 19
+#define MAX_HEARTBEAT     60
+
+/* Watchdog timer register set definition */
+#define WDTIM_INT(p)     ((p) + 0x0)
+#define WDTIM_CTRL(p)    ((p) + 0x4)
+#define WDTIM_COUNTER(p) ((p) + 0x8)
+#define WDTIM_MCTRL(p)   ((p) + 0xC)
+#define WDTIM_MATCH0(p)  ((p) + 0x10)
+#define WDTIM_EMR(p)     ((p) + 0x14)
+#define WDTIM_PULSE(p)   ((p) + 0x18)
+#define WDTIM_RES(p)     ((p) + 0x1C)
+
+/* WDTIM_INT bit definitions */
+#define MATCH_INT      1
+
+/* WDTIM_CTRL bit definitions */
+#define COUNT_ENAB     1
+#define RESET_COUNT    (1<<1)
+#define DEBUG_EN       (1<<2)
+
+/* WDTIM_MCTRL bit definitions */
+#define MR0_INT        1
+#undef  RESET_COUNT0
+#define RESET_COUNT0   (1<<2)
+#define STOP_COUNT0    (1<<2)
+#define M_RES1         (1<<3)
+#define M_RES2         (1<<4)
+#define RESFRC1        (1<<5)
+#define RESFRC2        (1<<6)
+
+/* WDTIM_EMR bit definitions */
+#define EXT_MATCH0      1
+#define MATCH_OUTPUT_HIGH (2<<4)	/*a MATCH_CTRL setting */
+
+/* WDTIM_RES bit definitions */
+#define WDOG_RESET      1	/* read only */
+
+#define WDOG_COUNTER_RATE 13000000	/*the counter clock is 13 MHz fixed */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+static int heartbeat = DEFAULT_HEARTBEAT;
+
+static spinlock_t io_lock;
+static unsigned long wdt_status;
+#define WDT_IN_USE        0
+#define WDT_OK_TO_CLOSE   1
+#define WDT_REGION_INITED 2
+#define WDT_DEVICE_INITED 3
+
+static unsigned long boot_status;
+
+static struct resource	*wdt_mem;
+static void __iomem	*wdt_base;
+struct clk		*wdt_clk;
+
+static void wdt_enable(void)
+{
+	spin_lock(&io_lock);
+
+	if (wdt_clk)
+		clk_set_rate(wdt_clk, 1);
+
+	/* stop counter, initiate counter reset */
+	__raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
+	/*wait for reset to complete. 100% guarantee event */
+	while (__raw_readl(WDTIM_COUNTER(wdt_base)))
+		cpu_relax();
+	/* internal and external reset, stop after that */
+	__raw_writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0,
+		WDTIM_MCTRL(wdt_base));
+	/* configure match output */
+	__raw_writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base));
+	/* clear interrupt, just in case */
+	__raw_writel(MATCH_INT, WDTIM_INT(wdt_base));
+	/* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */
+	__raw_writel(0xFFFF, WDTIM_PULSE(wdt_base));
+	__raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base));
+	/*enable counter, stop when debugger active */
+	__raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base));
+
+	spin_unlock(&io_lock);
+}
+
+static void wdt_disable(void)
+{
+	spin_lock(&io_lock);
+
+	__raw_writel(0, WDTIM_CTRL(wdt_base));	/*stop counter */
+	if (wdt_clk)
+		clk_set_rate(wdt_clk, 0);
+
+	spin_unlock(&io_lock);
+}
+
+static int pnx4008_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+		return -EBUSY;
+
+	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+	wdt_enable();
+
+	return nonseekable_open(inode, file);
+}
+
+static ssize_t
+pnx4008_wdt_write(struct file *file, const char *data, size_t len,
+		  loff_t * ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+			for (i = 0; i != len; i++) {
+				char c;
+
+				if (get_user(c, data + i))
+					return -EFAULT;
+				if (c == 'V')
+					set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+			}
+		}
+		wdt_enable();
+	}
+
+	return len;
+}
+
+static struct watchdog_info ident = {
+	.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
+	    WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+	.identity = "PNX4008 Watchdog",
+};
+
+static int
+pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		  unsigned long arg)
+{
+	int ret = -ENOTTY;
+	int time;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		ret = copy_to_user((struct watchdog_info *)arg, &ident,
+				   sizeof(ident)) ? -EFAULT : 0;
+		break;
+
+	case WDIOC_GETSTATUS:
+		ret = put_user(0, (int *)arg);
+		break;
+
+	case WDIOC_GETBOOTSTATUS:
+		ret = put_user(boot_status, (int *)arg);
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		ret = get_user(time, (int *)arg);
+		if (ret)
+			break;
+
+		if (time <= 0 || time > MAX_HEARTBEAT) {
+			ret = -EINVAL;
+			break;
+		}
+
+		heartbeat = time;
+		wdt_enable();
+		/* Fall through */
+
+	case WDIOC_GETTIMEOUT:
+		ret = put_user(heartbeat, (int *)arg);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		wdt_enable();
+		ret = 0;
+		break;
+	}
+	return ret;
+}
+
+static int pnx4008_wdt_release(struct inode *inode, struct file *file)
+{
+	if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status))
+		printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
+
+	wdt_disable();
+	clear_bit(WDT_IN_USE, &wdt_status);
+	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+	return 0;
+}
+
+static struct file_operations pnx4008_wdt_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.write = pnx4008_wdt_write,
+	.ioctl = pnx4008_wdt_ioctl,
+	.open = pnx4008_wdt_open,
+	.release = pnx4008_wdt_release,
+};
+
+static struct miscdevice pnx4008_wdt_miscdev = {
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &pnx4008_wdt_fops,
+};
+
+static int pnx4008_wdt_probe(struct platform_device *pdev)
+{
+	int ret = 0, size;
+	struct resource *res;
+
+	spin_lock_init(&io_lock);
+
+	if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
+		heartbeat = DEFAULT_HEARTBEAT;
+
+	printk(KERN_INFO MODULE_NAME
+		"PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		printk(KERN_INFO MODULE_NAME
+			"failed to get memory region resouce\n");
+		return -ENOENT;
+	}
+
+	size = res->end - res->start + 1;
+	wdt_mem = request_mem_region(res->start, size, pdev->name);
+
+	if (wdt_mem == NULL) {
+		printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
+		return -ENOENT;
+	}
+	wdt_base = (void __iomem *)IO_ADDRESS(res->start);
+
+	wdt_clk = clk_get(&pdev->dev, "wdt_ck");
+	if (!wdt_clk) {
+		release_resource(wdt_mem);
+		kfree(wdt_mem);
+		goto out;
+	} else
+		clk_set_rate(wdt_clk, 1);
+
+	ret = misc_register(&pnx4008_wdt_miscdev);
+	if (ret < 0) {
+		printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
+		release_resource(wdt_mem);
+		kfree(wdt_mem);
+		clk_set_rate(wdt_clk, 0);
+	} else {
+		boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
+		    WDIOF_CARDRESET : 0;
+		wdt_disable();		/*disable for now */
+		set_bit(WDT_DEVICE_INITED, &wdt_status);
+	}
+
+out:
+	return ret;
+}
+
+static int pnx4008_wdt_remove(struct platform_device *pdev)
+{
+	misc_deregister(&pnx4008_wdt_miscdev);
+	if (wdt_clk) {
+		clk_set_rate(wdt_clk, 0);
+		clk_put(wdt_clk);
+		wdt_clk = NULL;
+	}
+	if (wdt_mem) {
+		release_resource(wdt_mem);
+		kfree(wdt_mem);
+		wdt_mem = NULL;
+	}
+	return 0;
+}
+
+static struct platform_driver platform_wdt_driver = {
+	.driver = {
+		.name = "watchdog",
+	},
+	.probe = pnx4008_wdt_probe,
+	.remove = pnx4008_wdt_remove,
+};
+
+static int __init pnx4008_wdt_init(void)
+{
+	return platform_driver_register(&platform_wdt_driver);
+}
+
+static void __exit pnx4008_wdt_exit(void)
+{
+	return platform_driver_unregister(&platform_wdt_driver);
+}
+
+module_init(pnx4008_wdt_init);
+module_exit(pnx4008_wdt_exit);
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("PNX4008 Watchdog Driver");
+
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat,
+		 "Watchdog heartbeat period in seconds from 1 to "
+		 __MODULE_STRING(MAX_HEARTBEAT) ", default "
+		 __MODULE_STRING(DEFAULT_HEARTBEAT));
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+		 "Set to 1 to keep watchdog running after device release");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index be978e8..b36a04a 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -62,7 +62,7 @@
 #define CONFIG_S3C2410_WATCHDOG_ATBOOT		(0)
 #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME	(15)
 
-static int nowayout = WATCHDOG_NOWAYOUT;
+static int nowayout	= WATCHDOG_NOWAYOUT;
 static int tmr_margin	= CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;
 static int tmr_atboot	= CONFIG_S3C2410_WATCHDOG_ATBOOT;
 static int soft_noboot	= 0;
@@ -213,11 +213,10 @@
 	if(down_trylock(&open_lock))
 		return -EBUSY;
 
-	if (nowayout) {
+	if (nowayout)
 		__module_get(THIS_MODULE);
-	} else {
-		allow_close = CLOSE_STATE_ALLOW;
-	}
+
+	allow_close = CLOSE_STATE_NOT;
 
 	/* start the timer */
 	s3c2410wdt_start();
@@ -230,6 +229,7 @@
 	 *	Shut off the timer.
 	 * 	Lock it in if it's a module and we set nowayout
 	 */
+
 	if (allow_close == CLOSE_STATE_ALLOW) {
 		s3c2410wdt_stop();
 	} else {
@@ -288,7 +288,7 @@
 
 	switch (cmd) {
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 
 		case WDIOC_GETSUPPORT:
 			return copy_to_user(argp, &s3c2410_wdt_ident,
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index 1fc16d9..33c1137 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -90,7 +90,7 @@
 static int sa1100dog_ioctl(struct inode *inode, struct file *file,
 	unsigned int cmd, unsigned long arg)
 {
-	int ret = -ENOIOCTLCMD;
+	int ret = -ENOTTY;
 	int time;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
index 4663c2f..c7b2045 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -235,7 +235,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 		case WDIOC_GETSTATUS:
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
index bfc475d..8882b42 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -141,7 +141,7 @@
 
 		return retval;
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 }
 
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index 7c3cf29..d8d0f28 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -180,7 +180,7 @@
 
 	switch (cmd) {
 		default:
-			return -ENOIOCTLCMD;	/* Keep Pavel Machek amused ;) */
+			return -ENOTTY;
 
 		case WDIOC_GETSUPPORT:
 			if (copy_to_user(argp, &ident, sizeof ident))
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 2c7c9db..caec37b 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -290,7 +290,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 		case WDIOC_GETSTATUS:
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
index c561299..fc0e034 100644
--- a/drivers/char/watchdog/scx200_wdt.c
+++ b/drivers/char/watchdog/scx200_wdt.c
@@ -166,7 +166,7 @@
 
 	switch (cmd) {
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	case WDIOC_GETSUPPORT:
 		if(copy_to_user(argp, &ident, sizeof(ident)))
 			return -EFAULT;
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
index e5b8c64..dc40362 100644
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/char/watchdog/shwdt.c
@@ -360,7 +360,7 @@
 
 			return retval;
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 
 	return 0;
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index ef8da51..4067e1f 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -203,7 +203,7 @@
 	};
 	switch (cmd) {
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user(argp, &ident,
 				sizeof(ident)) ? -EFAULT : 0;
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index 13f16d4..b4adc52 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -223,7 +223,7 @@
 	}
 
 	default:
-	  return -ENOIOCTLCMD;
+	  return -ENOTTY;
 	}
 	return 0;
 }
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
index ccf6c09..b0e5f84 100644
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/char/watchdog/w83877f_wdt.c
@@ -252,7 +252,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 		case WDIOC_GETSTATUS:
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
index 98f4e17..2c8d5d8 100644
--- a/drivers/char/watchdog/w83977f_wdt.c
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -393,7 +393,7 @@
 	switch(cmd)
 	{
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 
 	case WDIOC_GETSUPPORT:
 		return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0;
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
index 2bb6a9d..163e028 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -174,7 +174,7 @@
 	}
 
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 	return 0;
 }
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
index 5c38cdf..1d64e27 100644
--- a/drivers/char/watchdog/wdrtas.c
+++ b/drivers/char/watchdog/wdrtas.c
@@ -385,7 +385,7 @@
 		return put_user(wdrtas_interval, argp);
 
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	}
 }
 
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
index 70be81e..13f23f4 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -341,7 +341,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/char/watchdog/wdt285.c
index 6555fb8..89a249e 100644
--- a/drivers/char/watchdog/wdt285.c
+++ b/drivers/char/watchdog/wdt285.c
@@ -137,7 +137,7 @@
 	       unsigned long arg)
 {
 	unsigned int new_margin;
-	int ret = -ENOIOCTLCMD;
+	int ret = -ENOTTY;
 
 	switch(cmd) {
 	case WDIOC_GETSUPPORT:
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index a0935bc..6253041 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -361,7 +361,7 @@
 	switch(cmd)
 	{
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 
 	case WDIOC_GETSUPPORT:
 		return copy_to_user(uarg.ident, &ident,
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index 5918ca2..74d8cf8 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -386,7 +386,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 
diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c
index d418b82..22915cc 100644
--- a/drivers/clocksource/scx200_hrt.c
+++ b/drivers/clocksource/scx200_hrt.c
@@ -63,7 +63,7 @@
 
 static int __init init_hrt_clocksource(void)
 {
-	/* Make sure scx200 has initializedd the configuration block */
+	/* Make sure scx200 has initialized the configuration block */
 	if (!scx200_cb_present())
 		return -ENODEV;
 
@@ -76,7 +76,7 @@
 	}
 
 	/* write timer config */
-	outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0,
+	outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
 	     scx200_cb_base + SCx200_TMCNFG_OFFSET);
 
 	if (mhz27) {
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 2caaf71..86e69b7 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -52,8 +52,14 @@
  * The mutex locks both lists.
  */
 static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
-static BLOCKING_NOTIFIER_HEAD(cpufreq_transition_notifier_list);
+static struct srcu_notifier_head cpufreq_transition_notifier_list;
 
+static int __init init_cpufreq_transition_notifier_list(void)
+{
+	srcu_init_notifier_head(&cpufreq_transition_notifier_list);
+	return 0;
+}
+core_initcall(init_cpufreq_transition_notifier_list);
 
 static LIST_HEAD(cpufreq_governor_list);
 static DEFINE_MUTEX (cpufreq_governor_mutex);
@@ -262,14 +268,14 @@
 				freqs->old = policy->cur;
 			}
 		}
-		blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
+		srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
 				CPUFREQ_PRECHANGE, freqs);
 		adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
 		break;
 
 	case CPUFREQ_POSTCHANGE:
 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
-		blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
+		srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
 				CPUFREQ_POSTCHANGE, freqs);
 		if (likely(policy) && likely(policy->cpu == freqs->cpu))
 			policy->cur = freqs->new;
@@ -1049,7 +1055,7 @@
 		freqs.old = cpu_policy->cur;
 		freqs.new = cur_freq;
 
-		blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
+		srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
 				    CPUFREQ_SUSPENDCHANGE, &freqs);
 		adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
 
@@ -1130,7 +1136,7 @@
 			freqs.old = cpu_policy->cur;
 			freqs.new = cur_freq;
 
-			blocking_notifier_call_chain(
+			srcu_notifier_call_chain(
 					&cpufreq_transition_notifier_list,
 					CPUFREQ_RESUMECHANGE, &freqs);
 			adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
@@ -1176,7 +1182,7 @@
 
 	switch (list) {
 	case CPUFREQ_TRANSITION_NOTIFIER:
-		ret = blocking_notifier_chain_register(
+		ret = srcu_notifier_chain_register(
 				&cpufreq_transition_notifier_list, nb);
 		break;
 	case CPUFREQ_POLICY_NOTIFIER:
@@ -1208,7 +1214,7 @@
 
 	switch (list) {
 	case CPUFREQ_TRANSITION_NOTIFIER:
-		ret = blocking_notifier_chain_unregister(
+		ret = srcu_notifier_chain_unregister(
 				&cpufreq_transition_notifier_list, nb);
 		break;
 	case CPUFREQ_POLICY_NOTIFIER:
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 731c3d5..88f4621 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -64,7 +64,7 @@
 	help
 	 Say m if you want to have the option of updating the BIOS for your
 	 DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
-	 supporting application to comunicate with the BIOS regarding the new
+	 supporting application to communicate with the BIOS regarding the new
 	 image for the image update to take effect.
 	 See <file:Documentation/dell_rbu.txt> for more details on the driver.
 
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 23b0866..fc17599 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -227,7 +227,7 @@
 	int packet_length;
 	u8 *temp;
 	u8 *end = (u8 *) data + length;
-	pr_debug("packetize_data: data length %d\n", length);
+	pr_debug("packetize_data: data length %zd\n", length);
 	if (!rbu_data.packetsize) {
 		printk(KERN_WARNING
 			"dell_rbu: packetsize not specified\n");
@@ -249,7 +249,7 @@
 		if ((rc = create_packet(temp, packet_length)))
 			return rc;
 
-		pr_debug("%lu:%lu\n", temp, (end - temp));
+		pr_debug("%p:%lu\n", temp, (end - temp));
 		temp += packet_length;
 	}
 
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index b4502ed6..5c261e1 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/i386/kernel/edd.c
+ * linux/drivers/firmware/edd.c
  *  Copyright (C) 2002, 2003, 2004 Dell Inc.
  *  by Matt Domsch <Matt_Domsch@dell.com>
  *  disk signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 0d96679..510816c 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -333,10 +333,10 @@
 
 	  This driver is a light version of i2c-parport.  It doesn't depend
 	  on the parport driver, and uses direct I/O access instead.  This
-	  might be prefered on embedded systems where wasting memory for
+	  might be preferred on embedded systems where wasting memory for
 	  the clean but heavy parport handling is not an option.  The
 	  drawback is a reduced portability and the impossibility to
-	  dasiy-chain other parallel port devices.
+	  daisy-chain other parallel port devices.
 	  
 	  Don't say Y here if you said Y or M to i2c-parport.  Saying M to
 	  both is possible but both modules should not be loaded at the same
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 5bccb5d..80d4ba1 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -1,5 +1,5 @@
 /*
- * drivers/i2c/i2c-ibm_iic.c
+ * drivers/i2c/busses/i2c-ibm_iic.c
  *
  * Support for the IIC peripheral on IBM PPC 4xx
  *
diff --git a/drivers/i2c/busses/i2c-ibm_iic.h b/drivers/i2c/busses/i2c-ibm_iic.h
index 2b3219d..59d7b43 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.h
+++ b/drivers/i2c/busses/i2c-ibm_iic.h
@@ -1,5 +1,5 @@
 /*
- * drivers/i2c/i2c-ibm_iic.h
+ * drivers/i2c/busses/i2c-ibm_iic.h
  *
  * Support for the IIC peripheral on IBM PPC 4xx
  * 
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
index ab57325..1ce01fb 100644
--- a/drivers/i2c/busses/i2c-ixp4xx.c
+++ b/drivers/i2c/busses/i2c-ixp4xx.c
@@ -1,5 +1,5 @@
 /*
- * drivers/i2c/i2c-adap-ixp4xx.c
+ * drivers/i2c/busses/i2c-ixp4xx.c
  *
  * Intel's IXP4xx XScale NPU chipsets (IXP420, 421, 422, 425) do not have
  * an on board I2C controller but provide 16 GPIO pins that are often
diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
index 8b65a5c..8ddbae4 100644
--- a/drivers/i2c/busses/scx200_i2c.c
+++ b/drivers/i2c/busses/scx200_i2c.c
@@ -1,4 +1,4 @@
-/* linux/drivers/i2c/scx200_i2c.c 
+/* linux/drivers/i2c/busses/scx200_i2c.c
 
    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
 
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 69d627b..0c68d0f 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -56,7 +56,7 @@
 
 config IDE_MAX_HWIFS
 	int "Max IDE interfaces"
-	depends on ALPHA || SUPERH || IA64
+	depends on ALPHA || SUPERH || IA64 || EMBEDDED
 	default 4
 	help
 	  This is the maximum number of IDE hardware interfaces that will
@@ -594,6 +594,12 @@
 	  ide-probe at boot. It is reported to support DVD II drives, by the
 	  manufacturer.
 
+config BLK_DEV_JMICRON
+	tristate "JMicron JMB36x support"
+	help
+	  Basic support for the JMicron ATA controllers. For full support
+	  use the libata drivers.
+
 config BLK_DEV_SC1200
 	tristate "National SCx200 chipset support"
 	help
@@ -608,15 +614,6 @@
 	  the kernel to change PIO, DMA and UDMA speeds and to configure
 	  the chip to optimum performance.
 
-config BLK_DEV_IT8172
-	bool "IT8172 IDE support"
-	depends on (MIPS_ITE8172 || MIPS_IVR)
-	help
-	  Say Y here to support the on-board IDE controller on the Integrated
-	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
-	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
-
 config BLK_DEV_IT821X
 	tristate "IT821X IDE support"
 	help
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 1595599..608ca87 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -1,5 +1,5 @@
 /*
- * drivers/ide/ide-h8300.c
+ * drivers/ide/h8300/ide-h8300.c
  * H8/300 generic IDE interface
  */
 
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index c3546fe..56efed6 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -145,14 +145,12 @@
 {
 	for ( ; drive_table->id_model ; drive_table++)
 		if ((!strcmp(drive_table->id_model, id->model)) &&
-		    ((strstr(drive_table->id_firmware, id->fw_rev)) ||
+		    ((strstr(id->fw_rev, drive_table->id_firmware)) ||
 		     (!strcmp(drive_table->id_firmware, "ALL"))))
 			return 1;
 	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ide_in_drive_list);
-
 /**
  *	ide_dma_intr	-	IDE DMA interrupt handler
  *	@drive: the drive the interrupt is for
@@ -798,26 +796,23 @@
 
 static int ide_release_iomio_dma(ide_hwif_t *hwif)
 {
-	if ((hwif->dma_extra) && (hwif->channel == 0))
-		release_region((hwif->dma_base + 16), hwif->dma_extra);
 	release_region(hwif->dma_base, 8);
-	if (hwif->dma_base2)
-		release_region(hwif->dma_base, 8);
+	if (hwif->extra_ports)
+		release_region(hwif->extra_base, hwif->extra_ports);
 	return 1;
 }
 
 /*
  * Needed for allowing full modular support of ide-driver
  */
-int ide_release_dma (ide_hwif_t *hwif)
+int ide_release_dma(ide_hwif_t *hwif)
 {
+	ide_release_dma_engine(hwif);
+
 	if (hwif->mmio == 2)
 		return 1;
-	if (hwif->chipset == ide_etrax100)
-		return 1;
-
-	ide_release_dma_engine(hwif);
-	return ide_release_iomio_dma(hwif);
+	else
+		return ide_release_iomio_dma(hwif);
 }
 
 static int ide_allocate_dma_engine(ide_hwif_t *hwif)
@@ -829,10 +824,9 @@
 	if (hwif->dmatable_cpu)
 		return 0;
 
-	printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n",
-			hwif->cds->name, !hwif->dmatable_cpu ? " CPU" : "");
+	printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n",
+	       hwif->cds->name);
 
-	ide_release_dma_engine(hwif);
 	return 1;
 }
 
@@ -840,9 +834,7 @@
 {
 	printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
 
-	hwif->dma_base = base;
-	if (hwif->cds->extra && hwif->channel == 0)
-		hwif->dma_extra = hwif->cds->extra;
+ 	hwif->dma_base = base;
 
 	if(hwif->mate)
 		hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
@@ -854,29 +846,33 @@
 static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
 	printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx",
-		hwif->name, base, base + ports - 1);
+	       hwif->name, base, base + ports - 1);
+
 	if (!request_region(base, ports, hwif->name)) {
 		printk(" -- Error, ports in use.\n");
 		return 1;
 	}
+
 	hwif->dma_base = base;
-	if ((hwif->cds->extra) && (hwif->channel == 0)) {
-		request_region(base+16, hwif->cds->extra, hwif->cds->name);
-		hwif->dma_extra = hwif->cds->extra;
-	}
-	
-	if(hwif->mate)
-		hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
-	else
-		hwif->dma_master = base;
-	if (hwif->dma_base2) {
-		if (!request_region(hwif->dma_base2, ports, hwif->name))
-		{
-			printk(" -- Error, secondary ports in use.\n");
-			release_region(base, ports);
-			return 1;
+
+	if (hwif->cds->extra) {
+		hwif->extra_base = base + (hwif->channel ? 8 : 16);
+
+		if (!hwif->mate || !hwif->mate->extra_ports) {
+			if (!request_region(hwif->extra_base,
+					    hwif->cds->extra, hwif->cds->name)) {
+				printk(" -- Error, extra ports in use.\n");
+				release_region(base, ports);
+				return 1;
+			}
+			hwif->extra_ports = hwif->cds->extra;
 		}
 	}
+
+	if(hwif->mate)
+		hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base;
+	else
+		hwif->dma_master = base;
 	return 0;
 }
 
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 38479a29..ba6039b 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -59,8 +59,6 @@
 {
 	int ret = 1;
 
-	BUG_ON(!blk_rq_started(rq));
-
 	/*
 	 * if failfast is set on a request, override number of sectors and
 	 * complete the whole request right now
@@ -82,7 +80,8 @@
 
 	if (!end_that_request_first(rq, uptodate, nr_sectors)) {
 		add_disk_randomness(rq->rq_disk);
-		blkdev_dequeue_request(rq);
+		if (!list_empty(&rq->queuelist))
+			blkdev_dequeue_request(rq);
 		HWGROUP(drive)->rq = NULL;
 		end_that_request_last(rq, uptodate);
 		ret = 0;
@@ -135,7 +134,8 @@
 	ide_pm_flush_cache	= ide_pm_state_start_suspend,
 	idedisk_pm_standby,
 
-	idedisk_pm_idle		= ide_pm_state_start_resume,
+	idedisk_pm_restore_pio	= ide_pm_state_start_resume,
+	idedisk_pm_idle,
 	ide_pm_restore_dma,
 };
 
@@ -156,7 +156,10 @@
 	case idedisk_pm_standby:	/* Suspend step 2 (standby) complete */
 		pm->pm_step = ide_pm_state_completed;
 		break;
-	case idedisk_pm_idle:		/* Resume step 1 (idle) complete */
+	case idedisk_pm_restore_pio:	/* Resume step 1 complete */
+		pm->pm_step = idedisk_pm_idle;
+		break;
+	case idedisk_pm_idle:		/* Resume step 2 (idle) complete */
 		pm->pm_step = ide_pm_restore_dma;
 		break;
 	}
@@ -170,8 +173,11 @@
 	memset(args, 0, sizeof(*args));
 
 	if (drive->media != ide_disk) {
-		/* skip idedisk_pm_idle for ATAPI devices */
-		if (pm->pm_step == idedisk_pm_idle)
+		/*
+		 * skip idedisk_pm_restore_pio and idedisk_pm_idle for ATAPI
+		 * devices
+		 */
+		if (pm->pm_step == idedisk_pm_restore_pio)
 			pm->pm_step = ide_pm_restore_dma;
 	}
 
@@ -198,13 +204,19 @@
 		args->handler	   = &task_no_data_intr;
 		return do_rw_taskfile(drive, args);
 
-	case idedisk_pm_idle:		/* Resume step 1 (idle) */
+	case idedisk_pm_restore_pio:	/* Resume step 1 (restore PIO) */
+		if (drive->hwif->tuneproc != NULL)
+			drive->hwif->tuneproc(drive, 255);
+		ide_complete_power_step(drive, rq, 0, 0);
+		return ide_stopped;
+
+	case idedisk_pm_idle:		/* Resume step 2 (idle) */
 		args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
 		args->command_type = IDE_DRIVE_TASK_NO_DATA;
 		args->handler = task_no_data_intr;
 		return do_rw_taskfile(drive, args);
 
-	case ide_pm_restore_dma:	/* Resume step 2 (restore DMA) */
+	case ide_pm_restore_dma:	/* Resume step 3 (restore DMA) */
 		/*
 		 * Right now, all we do is call hwif->ide_dma_check(drive),
 		 * we could be smarter and check for current xfer_speed
@@ -1346,6 +1358,10 @@
 	 * make sure request is sane
 	 */
 	rq = HWGROUP(drive)->rq;
+
+	if (!rq)
+		goto out;
+
 	HWGROUP(drive)->rq = NULL;
 
 	rq->errors = 0;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 77703ac..badde63 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -998,6 +998,7 @@
 	}
 	/* done polling */
 	hwgroup->polling = 0;
+	hwgroup->resetting = 0;
 	return ide_stopped;
 }
 
@@ -1057,6 +1058,7 @@
 		}
 	}
 	hwgroup->polling = 0;	/* done polling */
+	hwgroup->resetting = 0; /* done reset attempt */
 	return ide_stopped;
 }
 
@@ -1143,6 +1145,7 @@
 
 	/* For an ATAPI device, first try an ATAPI SRST. */
 	if (drive->media != ide_disk && !do_not_try_atapi) {
+		hwgroup->resetting = 1;
 		pre_reset(drive);
 		SELECT_DRIVE(drive);
 		udelay (20);
@@ -1168,6 +1171,7 @@
 		return ide_stopped;
 	}
 
+	hwgroup->resetting = 1;
 	/*
 	 * Note that we also set nIEN while resetting the device,
 	 * to mask unwanted interrupts from the interface during the reset.
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 850ef63..8237d89 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -71,75 +71,96 @@
 /**
  *	ide_dma_speed	-	compute DMA speed
  *	@drive: drive
- *	@mode; intended mode
+ *	@mode:	modes available
  *
  *	Checks the drive capabilities and returns the speed to use
- *	for the transfer. Returns -1 if the requested mode is unknown
- *	(eg PIO)
+ *	for the DMA transfer.  Returns 0 if the drive is incapable
+ *	of DMA transfers.
  */
  
 u8 ide_dma_speed(ide_drive_t *drive, u8 mode)
 {
 	struct hd_driveid *id   = drive->id;
 	ide_hwif_t *hwif	= HWIF(drive);
+	u8 ultra_mask, mwdma_mask, swdma_mask;
 	u8 speed = 0;
 
 	if (drive->media != ide_disk && hwif->atapi_dma == 0)
 		return 0;
 
-	switch(mode) {
-		case 0x04:
-			if ((id->dma_ultra & 0x0040) &&
-			    (id->dma_ultra & hwif->ultra_mask))
-				{ speed = XFER_UDMA_6; break; }
-		case 0x03:
-			if ((id->dma_ultra & 0x0020) &&
-			    (id->dma_ultra & hwif->ultra_mask))
-				{ speed = XFER_UDMA_5; break; }
-		case 0x02:
-			if ((id->dma_ultra & 0x0010) &&
-			    (id->dma_ultra & hwif->ultra_mask))
-				{ speed = XFER_UDMA_4; break; }
-			if ((id->dma_ultra & 0x0008) &&
-			    (id->dma_ultra & hwif->ultra_mask))
-				{ speed = XFER_UDMA_3; break; }
-		case 0x01:
-			if ((id->dma_ultra & 0x0004) &&
-			    (id->dma_ultra & hwif->ultra_mask))
-				{ speed = XFER_UDMA_2; break; }
-			if ((id->dma_ultra & 0x0002) &&
-			    (id->dma_ultra & hwif->ultra_mask))
-				{ speed = XFER_UDMA_1; break; }
-			if ((id->dma_ultra & 0x0001) &&
-			    (id->dma_ultra & hwif->ultra_mask))
-				{ speed = XFER_UDMA_0; break; }
-		case 0x00:
-			if ((id->dma_mword & 0x0004) &&
-			    (id->dma_mword & hwif->mwdma_mask))
-				{ speed = XFER_MW_DMA_2; break; }
-			if ((id->dma_mword & 0x0002) &&
-			    (id->dma_mword & hwif->mwdma_mask))
-				{ speed = XFER_MW_DMA_1; break; }
-			if ((id->dma_mword & 0x0001) &&
-			    (id->dma_mword & hwif->mwdma_mask))
-				{ speed = XFER_MW_DMA_0; break; }
-			if ((id->dma_1word & 0x0004) &&
-			    (id->dma_1word & hwif->swdma_mask))
-				{ speed = XFER_SW_DMA_2; break; }
-			if ((id->dma_1word & 0x0002) &&
-			    (id->dma_1word & hwif->swdma_mask))
-				{ speed = XFER_SW_DMA_1; break; }
-			if ((id->dma_1word & 0x0001) &&
-			    (id->dma_1word & hwif->swdma_mask))
-				{ speed = XFER_SW_DMA_0; break; }
-	}
+	/* Capable of UltraDMA modes? */
+	ultra_mask = id->dma_ultra & hwif->ultra_mask;
 
-//	printk("%s: %s: mode 0x%02x, speed 0x%02x\n",
-//		__FUNCTION__, drive->name, mode, speed);
+	if (!(id->field_valid & 4))
+		mode = 0;	/* fallback to MW/SW DMA if no UltraDMA */
+
+	switch (mode) {
+	case 4:
+		if (ultra_mask & 0x40) {
+			speed = XFER_UDMA_6;
+			break;
+		}
+	case 3:
+		if (ultra_mask & 0x20) {
+			speed = XFER_UDMA_5;
+			break;
+		}
+	case 2:
+		if (ultra_mask & 0x10) {
+			speed = XFER_UDMA_4;
+			break;
+		}
+		if (ultra_mask & 0x08) {
+			speed = XFER_UDMA_3;
+			break;
+		}
+	case 1:
+		if (ultra_mask & 0x04) {
+			speed = XFER_UDMA_2;
+			break;
+		}
+		if (ultra_mask & 0x02) {
+			speed = XFER_UDMA_1;
+			break;
+		}
+		if (ultra_mask & 0x01) {
+			speed = XFER_UDMA_0;
+			break;
+		}
+	case 0:
+		mwdma_mask = id->dma_mword & hwif->mwdma_mask;
+
+		if (mwdma_mask & 0x04) {
+			speed = XFER_MW_DMA_2;
+			break;
+		}
+		if (mwdma_mask & 0x02) {
+			speed = XFER_MW_DMA_1;
+			break;
+		}
+		if (mwdma_mask & 0x01) {
+			speed = XFER_MW_DMA_0;
+			break;
+		}
+
+		swdma_mask = id->dma_1word & hwif->swdma_mask;
+
+		if (swdma_mask & 0x04) {
+			speed = XFER_SW_DMA_2;
+			break;
+		}
+		if (swdma_mask & 0x02) {
+			speed = XFER_SW_DMA_1;
+			break;
+		}
+		if (swdma_mask & 0x01) {
+			speed = XFER_SW_DMA_0;
+			break;
+		}
+	}
 
 	return speed;
 }
-
 EXPORT_SYMBOL(ide_dma_speed);
 
 
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 9cadf01..dad9c47 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -623,6 +623,8 @@
 
 static void hwif_register (ide_hwif_t *hwif)
 {
+	int ret;
+
 	/* register with global device tree */
 	strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE);
 	hwif->gendev.driver_data = hwif;
@@ -634,7 +636,10 @@
 			hwif->gendev.parent = NULL;
 	}
 	hwif->gendev.release = hwif_release_dev;
-	device_register(&hwif->gendev);
+	ret = device_register(&hwif->gendev);
+	if (ret < 0)
+		printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
+			__FUNCTION__, ret);
 }
 
 static int wait_hwif_ready(ide_hwif_t *hwif)
@@ -884,13 +889,19 @@
 
 	if (hwif->present) {
 		u16 unit = 0;
+		int ret;
+
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
 			ide_drive_t *drive = &hwif->drives[unit];
 			/* For now don't attach absent drives, we may
 			   want them on default or a new "empty" class
 			   for hotplug reprobing ? */
 			if (drive->present) {
-				device_register(&drive->gendev);
+				ret = device_register(&drive->gendev);
+				if (ret < 0)
+					printk(KERN_WARNING "IDE: %s: "
+						"device_register error: %d\n",
+						__FUNCTION__, ret);
 			}
 		}
 	}
@@ -1409,8 +1420,14 @@
 			if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
 				hwif->chipset = ide_generic;
 			for (unit = 0; unit < MAX_DRIVES; ++unit)
-				if (hwif->drives[unit].present)
-					device_register(&hwif->drives[unit].gendev);
+				if (hwif->drives[unit].present) {
+					int ret = device_register(
+						&hwif->drives[unit].gendev);
+					if (ret < 0)
+						printk(KERN_WARNING "IDE: %s: "
+							"device_register error: %d\n",
+							__FUNCTION__, ret);
+				}
 		}
 	}
 	return 0;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 41b74b1..aa049da 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -326,15 +326,24 @@
 {
 	struct device *dev = &drive->gendev;
 	int ret = 1;
+	int err;
 
 	down_write(&dev->bus->subsys.rwsem);
 	device_release_driver(dev);
 	/* FIXME: device can still be in use by previous driver */
 	strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
-	device_attach(dev);
+	err = device_attach(dev);
+	if (err < 0)
+		printk(KERN_WARNING "IDE: %s: device_attach error: %d\n",
+			__FUNCTION__, err);
 	drive->driver_req[0] = 0;
-	if (dev->driver == NULL)
-		device_attach(dev);
+	if (dev->driver == NULL) {
+		err = device_attach(dev);
+		if (err < 0)
+			printk(KERN_WARNING
+				"IDE: %s: device_attach(2) error: %d\n",
+				__FUNCTION__, err);
+	}
 	if (dev->driver && !strcmp(dev->driver->name, driver))
 		ret = 0;
 	up_write(&dev->bus->subsys.rwsem);
@@ -526,7 +535,12 @@
 
 static int ide_drivers_show(struct seq_file *s, void *p)
 {
-	bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+	int err;
+
+	err = bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+	if (err < 0)
+		printk(KERN_WARNING "IDE: %s: bus_for_each_drv error: %d\n",
+			__FUNCTION__, err);
 	return 0;
 }
 
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 2b1a138..287a662 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -450,7 +450,7 @@
  *	@hwif: hwif to update
  *	@tmp_hwif: template
  *
- *	Restore hwif to a previous state by copying most settngs
+ *	Restore hwif to a previous state by copying most settings
  *	from the template.
  */
 
@@ -539,9 +539,10 @@
 	hwif->dma_vendor3		= tmp_hwif->dma_vendor3;
 	hwif->dma_prdtable		= tmp_hwif->dma_prdtable;
 
-	hwif->dma_extra			= tmp_hwif->dma_extra;
 	hwif->config_data		= tmp_hwif->config_data;
 	hwif->select_data		= tmp_hwif->select_data;
+	hwif->extra_base		= tmp_hwif->extra_base;
+	hwif->extra_ports		= tmp_hwif->extra_ports;
 	hwif->autodma			= tmp_hwif->autodma;
 	hwif->udma_four			= tmp_hwif->udma_four;
 	hwif->no_dsc			= tmp_hwif->no_dsc;
@@ -550,7 +551,7 @@
 }
 
 /**
- *	ide_unregister		-	free an ide interface
+ *	ide_unregister		-	free an IDE interface
  *	@index: index of interface (will change soon to a pointer)
  *
  *	Perform the final unregister of an IDE interface. At the moment
@@ -563,8 +564,8 @@
  *	deadlocking the IDE layer. The shutdown callback is called
  *	before we take the lock and free resources. It is up to the
  *	caller to be sure there is no pending I/O here, and that
- *	the interfce will not be reopened (present/vanishing locking
- *	isnt yet done btw). After we commit to the final kill we
+ *	the interface will not be reopened (present/vanishing locking
+ *	isn't yet done BTW). After we commit to the final kill we
  *	call the cleanup callback with the ide locks held.
  *
  *	Unregister restores the hwif structures to the default state.
@@ -674,6 +675,9 @@
 		hwif->dma_status = 0;
 		hwif->dma_vendor3 = 0;
 		hwif->dma_prdtable = 0;
+
+		hwif->extra_base  = 0;
+		hwif->extra_ports = 0;
 	}
 
 	/* copy original settings */
@@ -1360,6 +1364,11 @@
 
 			spin_lock_irqsave(&ide_lock, flags);
 
+			if (HWGROUP(drive)->resetting) {
+				spin_unlock_irqrestore(&ide_lock, flags);
+				return -EBUSY;
+			}
+
 			ide_abort(drive, "drive reset");
 
 			BUG_ON(HWGROUP(drive)->handler);
@@ -1993,10 +2002,16 @@
  */
 static int __init ide_init(void)
 {
+	int ret;
+
 	printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
 	system_bus_speed = ide_system_bus_speed();
 
-	bus_register(&ide_bus_type);
+	ret = bus_register(&ide_bus_type);
+	if (ret < 0) {
+		printk(KERN_WARNING "IDE: bus_register error: %d\n", ret);
+		return ret;
+	}
 
 	init_ide_data();
 
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 602797a..bef4759 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -120,7 +120,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -398,12 +398,17 @@
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
 	PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
+	PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
 	PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
 	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
 	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
 	PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
+	PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
+	PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
+	PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
 	PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
 	PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
+	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
 	PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
 	PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
 	PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index f35d684..fef0896 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -12,8 +12,8 @@
 obj-$(CONFIG_BLK_DEV_HPT34X)		+= hpt34x.o
 obj-$(CONFIG_BLK_DEV_HPT366)		+= hpt366.o
 #obj-$(CONFIG_BLK_DEV_HPT37X)		+= hpt37x.o
-obj-$(CONFIG_BLK_DEV_IT8172)		+= it8172.o
 obj-$(CONFIG_BLK_DEV_IT821X)		+= it821x.o
+obj-$(CONFIG_BLK_DEV_JMICRON)		+= jmicron.o
 obj-$(CONFIG_BLK_DEV_NS87415)		+= ns87415.o
 obj-$(CONFIG_BLK_DEV_OPTI621)		+= opti621.o
 obj-$(CONFIG_BLK_DEV_PDC202XX_OLD)	+= pdc202xx_old.o
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 380bb28..ae405fa 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -222,23 +222,23 @@
 	unsigned long flags;
 
 	dev = NULL;
-	while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
 		switch (dev->device) {
 			case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
-				master_0 = dev;
+				master_0 = pci_dev_get(dev);
 				break;
 			case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
-				cs5530_0 = dev;
+				cs5530_0 = pci_dev_get(dev);
 				break;
 		}
 	}
 	if (!master_0) {
 		printk(KERN_ERR "%s: unable to locate PCI MASTER function\n", name);
-		return 0;
+		goto out;
 	}
 	if (!cs5530_0) {
 		printk(KERN_ERR "%s: unable to locate CS5530 LEGACY function\n", name);
-		return 0;
+		goto out;
 	}
 
 	spin_lock_irqsave(&ide_lock, flags);
@@ -296,6 +296,9 @@
 
 	spin_unlock_irqrestore(&ide_lock, flags);
 
+out:
+	pci_dev_put(master_0);
+	pci_dev_put(cs5530_0);
 	return 0;
 }
 
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 120929f..64330c4 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -281,7 +281,7 @@
 
 	/* select primary or secondary channel */
 	if (hwif->index > 0) {  /* drive is on the secondary channel */
-		dev = pci_find_slot(dev->bus->number, dev->devfn+1);
+		dev = pci_get_slot(dev->bus, dev->devfn+1);
 		if (!dev) {
 			printk(KERN_ERR "%s: tune_drive: "
 				"Cannot find secondary interface!\n",
@@ -500,8 +500,9 @@
 	   Function 1 is primary IDE channel, function 2 - secondary. */
         if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
 	    PCI_FUNC(dev->devfn) == 1) {
-		dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
+		dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
 		ret = ide_setup_pci_devices(dev, dev2, d);
+		/* We leak pci refs here but thats ok - we can't be unloaded */
 	}
 	return ret;
 }
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 78810ba..0cb7b9b 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -41,15 +41,8 @@
 
 static int ide_generic_all;		/* Set to claim all devices */
 
-#ifndef MODULE
-static int __init ide_generic_all_on(char *unused)
-{
-	ide_generic_all = 1;
-	printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
-	return 1;
-}
-__setup("all-generic-ide", ide_generic_all_on);
-#endif
+module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
+MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
 static void __devinit init_hwif_generic (ide_hwif_t *hwif)
 {
diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
deleted file mode 100644
index 0fc89fa..0000000
--- a/drivers/ide/pci/it8172.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *      IT8172 IDE controller support
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *              stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/it8172/it8172_int.h>
-
-/*
- * Prototypes
- */
-static u8 it8172_ratemask (ide_drive_t *drive)
-{
-	return 1;
-}
-
-static void it8172_tune_drive (ide_drive_t *drive, u8 pio)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	int is_slave		= (&hwif->drives[1] == drive);
-	unsigned long flags;
-	u16 drive_enables;
-	u32 drive_timing;
-
-	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-	spin_lock_irqsave(&ide_lock, flags);
-	pci_read_config_word(dev, 0x40, &drive_enables);
-	pci_read_config_dword(dev, 0x44, &drive_timing);
-
-	/*
-	 * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
-	 * are being left at the default values of 8 PCI clocks (242 nsec
-	 * for a 33 MHz clock). These can be safely shortened at higher
-	 * PIO modes. The DIOR/DIOW pulse width and recovery times only
-	 * apply to PIO modes, not to the DMA modes.
-	 */
-
-	/*
-	 * Enable port 0x44. The IT8172G spec is confused; it calls
-	 * this register the "Slave IDE Timing Register", but in fact,
-	 * it controls timing for both master and slave drives.
-	 */
-	drive_enables |= 0x4000;
-
-	if (is_slave) {
-		drive_enables &= 0xc006;
-		if (pio > 1)
-			/* enable prefetch and IORDY sample-point */
-			drive_enables |= 0x0060;
-	} else {
-		drive_enables &= 0xc060;
-		if (pio > 1)
-			/* enable prefetch and IORDY sample-point */
-			drive_enables |= 0x0006;
-	}
-
-	pci_write_config_word(dev, 0x40, drive_enables);
-	spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-static u8 it8172_dma_2_pio (u8 xfer_rate)
-{
-	switch(xfer_rate) {
-		case XFER_UDMA_5:
-		case XFER_UDMA_4:
-		case XFER_UDMA_3:
-		case XFER_UDMA_2:
-		case XFER_UDMA_1:
-		case XFER_UDMA_0:
-		case XFER_MW_DMA_2:
-		case XFER_PIO_4:
-			return 4;
-		case XFER_MW_DMA_1:
-		case XFER_PIO_3:
-			return 3;
-		case XFER_SW_DMA_2:
-		case XFER_PIO_2:
-			return 2;
-		case XFER_MW_DMA_0:
-		case XFER_SW_DMA_1:
-		case XFER_SW_DMA_0:
-		case XFER_PIO_1:
-		case XFER_PIO_0:
-		case XFER_PIO_SLOW:
-		default:
-			return 0;
-	}
-}
-
-static int it8172_tune_chipset (ide_drive_t *drive, u8 xferspeed)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	u8 speed	= ide_rate_filter(it8172_ratemask(drive), xferspeed);
-	int a_speed		= 3 << (drive->dn * 4);
-	int u_flag		= 1 << drive->dn;
-	int u_speed		= 0;
-	u8 reg48, reg4a;
-
-	pci_read_config_byte(dev, 0x48, &reg48);
-	pci_read_config_byte(dev, 0x4a, &reg4a);
-
-    /*
-     * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec
-     * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA
-     * transfers on some drives, even though both numbers meet the minimum
-     * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively.
-     * So the faster times are just commented out here. The good news is
-     * that the slower cycle time has very little affect on transfer
-     * performance.
-     */
-    
-	switch(speed) {
-		case XFER_UDMA_4:
-		case XFER_UDMA_2:	//u_speed = 2 << (drive->dn * 4); break;
-		case XFER_UDMA_5:
-		case XFER_UDMA_3:
-		case XFER_UDMA_1:	//u_speed = 1 << (drive->dn * 4); break;
-		case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
-		case XFER_MW_DMA_2:
-		case XFER_MW_DMA_1:
-		case XFER_MW_DMA_0:
-		case XFER_SW_DMA_2:	break;
-		case XFER_PIO_4:
-		case XFER_PIO_3:
-		case XFER_PIO_2:
-		case XFER_PIO_0:	break;
-		default:		return -1;
-	}
-
-	if (speed >= XFER_UDMA_0) {
-		pci_write_config_byte(dev, 0x48, reg48 | u_flag);
-		reg4a &= ~a_speed;
-		pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
-	} else {
-		pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
-		pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
-	}
-
-	it8172_tune_drive(drive, it8172_dma_2_pio(speed));
-	return (ide_config_drive_speed(drive, speed));
-}
-
-static int it8172_config_chipset_for_dma (ide_drive_t *drive)
-{
-	u8 speed = ide_dma_speed(drive, it8172_ratemask(drive));
-
-	if (!(speed)) {
-		u8 tspeed = ide_get_best_pio_mode(drive, 255, 4, NULL);
-		speed = it8172_dma_2_pio(XFER_PIO_0 + tspeed);
-	}
-
-	(void) it8172_tune_chipset(drive, speed);
-	return ide_dma_enable(drive);
-}
-
-static int it8172_config_drive_xfer_rate (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
-	drive->init_speed = 0;
-
-	if (id && (id->capability & 1) && drive->autodma) {
-
-		if (ide_use_dma(drive)) {
-			if (it8172_config_chipset_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		it8172_tune_drive(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
-}
-
-static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name)
-{
-	unsigned char progif;
-    
-	/*
-	 * Place both IDE interfaces into PCI "native" mode
-	 */
-	pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
-	pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05);    
-
-	return IT8172_IDE_IRQ;
-}
-
-
-static void __devinit init_hwif_it8172 (ide_hwif_t *hwif)
-{
-	struct pci_dev* dev = hwif->pci_dev;
-	unsigned long cmdBase, ctrlBase;
-    
-	hwif->autodma = 0;
-	hwif->tuneproc = &it8172_tune_drive;
-	hwif->speedproc = &it8172_tune_chipset;
-
-	cmdBase = dev->resource[0].start;
-	ctrlBase = dev->resource[1].start;
-    
-	ide_init_hwif_ports(&hwif->hw, cmdBase, ctrlBase | 2, NULL);
-	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
-	hwif->noprobe = 0;
-
-	if (!hwif->dma_base) {
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
-		return;
-	}
-
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x07;
-	hwif->mwdma_mask = 0x06;
-	hwif->swdma_mask = 0x04;
-
-	hwif->ide_dma_check = &it8172_config_drive_xfer_rate;
-	if (!noautodma)
-		hwif->autodma = 1;
-	hwif->drives[0].autodma = hwif->autodma;
-	hwif->drives[1].autodma = hwif->autodma;
-}
-
-static ide_pci_device_t it8172_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "IT8172G",
-		.init_chipset	= init_chipset_it8172,
-		.init_hwif	= init_hwif_it8172,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x00,0x00,0x00}, {0x40,0x00,0x01}},
-		.bootable	= ON_BOARD,
-	}
-};
-
-static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-        if ((!(PCI_FUNC(dev->devfn) & 1) ||
-            (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))))
-		return -ENODEV; /* IT8172 is more than an IDE controller */
-	return ide_setup_pci_device(dev, &it8172_chipsets[id->driver_data]);
-}
-
-static struct pci_device_id it8172_pci_tbl[] = {
-	{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ 0, },
-};
-MODULE_DEVICE_TABLE(pci, it8172_pci_tbl);
-
-static struct pci_driver driver = {
-	.name		= "IT8172_IDE",
-	.id_table	= it8172_pci_tbl,
-	.probe		= it8172_init_one,
-};
-
-static int it8172_ide_init(void)
-{
-	return ide_pci_register_driver(&driver);
-}
-
-module_init(it8172_ide_init);
-
-MODULE_AUTHOR("SteveL@mvista.com");
-MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE");
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
new file mode 100644
index 0000000..68c74bb
--- /dev/null
+++ b/drivers/ide/pci/jmicron.c
@@ -0,0 +1,269 @@
+
+/*
+ * Copyright (C) 2006		Red Hat <alan@redhat.com>
+ *
+ *  May be copied or modified under the terms of the GNU General Public License
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+typedef enum {
+	PORT_PATA0 = 0,
+	PORT_PATA1 = 1,
+	PORT_SATA = 2,
+} port_type;
+
+/**
+ *	jmicron_ratemask	-	Compute available modes
+ *	@drive: IDE drive
+ *
+ *	Compute the available speeds for the devices on the interface. This
+ *	is all modes to ATA133 clipped by drive cable setup.
+ */
+
+static u8 jmicron_ratemask(ide_drive_t *drive)
+{
+	u8 mode	= 4;
+	if (!eighty_ninty_three(drive))
+		mode = min(mode, (u8)1);
+	return mode;
+}
+
+/**
+ *	ata66_jmicron		-	Cable check
+ *	@hwif: IDE port
+ *
+ *	Return 1 if the cable is 80pin
+ */
+
+static int __devinit ata66_jmicron(ide_hwif_t *hwif)
+{
+	struct pci_dev *pdev = hwif->pci_dev;
+
+	u32 control;
+	u32 control5;
+
+	int port = hwif->channel;
+	port_type port_map[2];
+
+	pci_read_config_dword(pdev, 0x40, &control);
+
+	/* There are two basic mappings. One has the two SATA ports merged
+	   as master/slave and the secondary as PATA, the other has only the
+	   SATA port mapped */
+	if (control & (1 << 23)) {
+		port_map[0] = PORT_SATA;
+		port_map[1] = PORT_PATA0;
+	} else {
+		port_map[0] = PORT_SATA;
+		port_map[1] = PORT_SATA;
+	}
+
+	/* The 365/366 may have this bit set to map the second PATA port
+	   as the internal primary channel */
+	pci_read_config_dword(pdev, 0x80, &control5);
+	if (control5 & (1<<24))
+		port_map[0] = PORT_PATA1;
+
+	/* The two ports may then be logically swapped by the firmware */
+	if (control & (1 << 22))
+		port = port ^ 1;
+
+	/*
+	 *	Now we know which physical port we are talking about we can
+	 *	actually do our cable checking etc. Thankfully we don't need
+	 *	to do the plumbing for other cases.
+	 */
+	switch (port_map[port])
+	{
+	case PORT_PATA0:
+		if (control & (1 << 3))	/* 40/80 pin primary */
+			return 1;
+		return 0;
+	case PORT_PATA1:
+		if (control5 & (1 << 19))	/* 40/80 pin secondary */
+			return 0;
+		return 1;
+	case PORT_SATA:
+		return 1;
+	}
+}
+
+static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted)
+{
+	return;
+}
+
+/**
+ *	config_jmicron_chipset_for_pio	-	set drive timings
+ *	@drive: drive to tune
+ *	@speed we want
+ *
+ */
+
+static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+	u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+	if (set_speed)
+		(void) ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *	jmicron_tune_chipset	-	set controller timings
+ *	@drive: Drive to set up
+ *	@xferspeed: speed we want to achieve
+ *
+ *	As the JMicron snoops for timings all we actually need to do is
+ *	make sure we don't set an invalid mode. We do need to honour
+ *	the cable detect here.
+ */
+
+static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed)
+{
+
+	u8 speed		= ide_rate_filter(jmicron_ratemask(drive), xferspeed);
+
+	return ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *	config_chipset_for_dma	-	configure for DMA
+ *	@drive: drive to configure
+ *
+ *	As the JMicron snoops for timings all we actually need to do is
+ *	make sure we don't set an invalid mode.
+ */
+
+static int config_chipset_for_dma (ide_drive_t *drive)
+{
+	u8 speed	= ide_dma_speed(drive, jmicron_ratemask(drive));
+
+	config_jmicron_chipset_for_pio(drive, !speed);
+	jmicron_tune_chipset(drive, speed);
+	return ide_dma_enable(drive);
+}
+
+/**
+ *	jmicron_configure_drive_for_dma	-	set up for DMA transfers
+ *	@drive: drive we are going to set up
+ *
+ *	As the JMicron snoops for timings all we actually need to do is
+ *	make sure we don't set an invalid mode.
+ */
+
+static int jmicron_config_drive_for_dma (ide_drive_t *drive)
+{
+	ide_hwif_t *hwif	= drive->hwif;
+
+	if (ide_use_dma(drive)) {
+		if (config_chipset_for_dma(drive))
+			return hwif->ide_dma_on(drive);
+	}
+	config_jmicron_chipset_for_pio(drive, 1);
+	return hwif->ide_dma_off_quietly(drive);
+}
+
+/**
+ *	init_hwif_jmicron	-	set up hwif structs
+ *	@hwif: interface to set up
+ *
+ *	Minimal set up is required for the Jmicron hardware.
+ */
+
+static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
+{
+	hwif->speedproc = &jmicron_tune_chipset;
+	hwif->tuneproc	= &jmicron_tuneproc;
+
+	hwif->drives[0].autotune = 1;
+	hwif->drives[1].autotune = 1;
+
+	if (!hwif->dma_base)
+		goto fallback;
+
+	hwif->atapi_dma = 1;
+	hwif->ultra_mask = 0x7f;
+	hwif->mwdma_mask = 0x07;
+
+	hwif->ide_dma_check = &jmicron_config_drive_for_dma;
+	if (!(hwif->udma_four))
+		hwif->udma_four = ata66_jmicron(hwif);
+
+	hwif->autodma = 1;
+	hwif->drives[0].autodma = hwif->autodma;
+	hwif->drives[1].autodma = hwif->autodma;
+	return;
+fallback:
+	hwif->autodma = 0;
+	return;
+}
+
+#define DECLARE_JMB_DEV(name_str)			\
+	{						\
+		.name		= name_str,		\
+		.init_hwif	= init_hwif_jmicron,	\
+		.channels	= 2,			\
+		.autodma	= AUTODMA,		\
+		.bootable	= ON_BOARD,		\
+		.enablebits	= { {0x40, 1, 1}, {0x40, 0x10, 0x10} }, \
+	}
+
+static ide_pci_device_t jmicron_chipsets[] __devinitdata = {
+	/* 0 */ DECLARE_JMB_DEV("JMB361"),
+	/* 1 */ DECLARE_JMB_DEV("JMB363"),
+	/* 2 */ DECLARE_JMB_DEV("JMB365"),
+	/* 3 */ DECLARE_JMB_DEV("JMB366"),
+	/* 4 */ DECLARE_JMB_DEV("JMB368"),
+};
+
+/**
+ *	jmicron_init_one	-	pci layer discovery entry
+ *	@dev: PCI device
+ *	@id: ident table entry
+ *
+ *	Called by the PCI code when it finds a Jmicron controller.
+ *	We then use the IDE PCI generic helper to do most of the work.
+ */
+
+static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	ide_setup_pci_device(dev, &jmicron_chipsets[id->driver_data]);
+	return 0;
+}
+
+static struct pci_device_id jmicron_pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0},
+	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1},
+	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2},
+	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3},
+	{ PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4},
+	{ 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl);
+
+static struct pci_driver driver = {
+	.name		= "JMicron IDE",
+	.id_table	= jmicron_pci_tbl,
+	.probe		= jmicron_init_one,
+};
+
+static int __init jmicron_ide_init(void)
+{
+	return ide_pci_register_driver(&driver);
+}
+
+module_init(jmicron_ide_init);
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("PCI driver module for the JMicron in legacy modes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index b46022a..184cdac 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -154,7 +154,8 @@
 	u8			AP, BP, CP, DP;
 	u8			TA = 0, TB = 0, TC = 0;
 
-	if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
+	if (drive->media != ide_disk &&
+		drive->media != ide_cdrom && speed < XFER_SW_DMA_0)
 		return -1;
 
 	pci_read_config_dword(dev, drive_pci, &drive_conf);
@@ -330,14 +331,12 @@
 
 chipset_is_set:
 
-	if (drive->media == ide_disk) {
-		pci_read_config_byte(dev, (drive_pci), &AP);
-		if (id->capability & 4)	/* IORDY_EN */
-			pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
-		pci_read_config_byte(dev, (drive_pci), &AP);
-		if (drive->media == ide_disk)	/* PREFETCH_EN */
-			pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
-	}
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	if (id->capability & 4) /* IORDY_EN */
+		pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	if (drive->media == ide_disk)	/* PREFETCH_EN */
+		pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
 
 	speed = ide_dma_speed(drive, pdc202xx_ratemask(drive));
 
@@ -385,7 +384,7 @@
 {
 	if (drive->current_speed > XFER_UDMA_2)
 		pdc_old_enable_66MHz_clock(drive->hwif);
-	if (drive->addressing == 1) {
+	if (drive->media != ide_disk || drive->addressing == 1) {
 		struct request *rq	= HWGROUP(drive)->rq;
 		ide_hwif_t *hwif	= HWIF(drive);
 		unsigned long high_16   = hwif->dma_master;
@@ -405,7 +404,7 @@
 
 static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
 {
-	if (drive->addressing == 1) {
+	if (drive->media != ide_disk || drive->addressing == 1) {
 		ide_hwif_t *hwif	= HWIF(drive);
 		unsigned long high_16	= hwif->dma_master;
 		unsigned long atapi_reg	= high_16 + (hwif->channel ? 0x24 : 0x20);
@@ -519,6 +518,7 @@
 	hwif->ultra_mask = 0x3f;
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
+	hwif->atapi_dma = 1;
 
 	hwif->err_stops_fifo = 1;
 
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index eb5bab1..cdc3aab 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -222,13 +222,15 @@
 	u16 master_data;
 	u8 slave_data;
 	static DEFINE_SPINLOCK(tune_lock);
+	int control = 0;
 
 				 /* ISP  RTC */
-	u8 timings[][2]	= { { 0, 0 },
-			    { 0, 0 },
-			    { 1, 0 },
-			    { 2, 1 },
-			    { 2, 3 }, };
+	static const u8 timings[][2]= {
+					{ 0, 0 },
+					{ 0, 0 },
+					{ 1, 0 },
+					{ 2, 1 },
+					{ 2, 3 }, };
 
 	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
 
@@ -239,19 +241,30 @@
 	 */
 	spin_lock_irqsave(&tune_lock, flags);
 	pci_read_config_word(dev, master_port, &master_data);
+
+	if (pio >= 2)
+		control |= 1;	/* Programmable timing on */
+	if (drive->media == ide_disk)
+		control |= 4;	/* Prefetch, post write */
+	if (pio >= 3)
+		control |= 2;	/* IORDY */
 	if (is_slave) {
 		master_data = master_data | 0x4000;
-		if (pio > 1)
+		if (pio > 1) {
 			/* enable PPE, IE and TIME */
-			master_data = master_data | 0x0070;
+			master_data = master_data | (control << 4);
+		} else {
+			master_data &= ~0x0070;
+		}
 		pci_read_config_byte(dev, slave_port, &slave_data);
 		slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0);
 		slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0));
 	} else {
 		master_data = master_data & 0xccf8;
-		if (pio > 1)
+		if (pio > 1) {
 			/* enable PPE, IE and TIME */
-			master_data = master_data | 0x0007;
+			master_data = master_data | control;
+		}
 		master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
 	}
 	pci_write_config_word(dev, master_port, master_data);
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index fc2b549..ff80937 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -323,6 +323,7 @@
  	}
 }
 
+#ifdef CONFIG_PM
 static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev)
 {
 	int	h;
@@ -451,6 +452,7 @@
 	}
 	return 0;
 }
+#endif
 
 /*
  * This gets invoked by the IDE driver once for each channel,
@@ -499,8 +501,10 @@
 	.name		= "SC1200_IDE",
 	.id_table	= sc1200_pci_tbl,
 	.probe		= sc1200_init_one,
+#ifdef CONFIG_PM
 	.suspend	= sc1200_suspend,
 	.resume		= sc1200_resume,
+#endif
 };
 
 static int sc1200_ide_init(void)
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index d8a0d87..f3fe287 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -220,7 +220,7 @@
 	ide_hwif_t *hwif = HWIF(drive);
 	u64 dma_base = hwif->dma_base;
 	int dma_stat = 0;
-	unsigned long *ending_dma = (unsigned long *) hwif->dma_base2;
+	unsigned long *ending_dma = ide_get_hwifdata(hwif);
 
 	hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
 
@@ -369,6 +369,7 @@
 {
 	void __iomem *virt_dma_base;
 	int num_ports = sizeof (ioc4_dma_regs_t);
+	void *pad;
 
 	printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name,
 	       dma_base, dma_base + num_ports - 1);
@@ -400,17 +401,14 @@
 
 	hwif->sg_max_nents = IOC4_PRD_ENTRIES;
 
-	hwif->dma_base2 = (unsigned long)
-		pci_alloc_consistent(hwif->pci_dev,
-				     IOC4_IDE_CACHELINE_SIZE,
-				     (dma_addr_t *) &(hwif->dma_status));
+	pad = pci_alloc_consistent(hwif->pci_dev, IOC4_IDE_CACHELINE_SIZE,
+				   (dma_addr_t *) &(hwif->dma_status));
 
-	if (!hwif->dma_base2)
-		goto dma_base2alloc_failure;
+	if (pad) {
+		ide_set_hwifdata(hwif, pad);
+		return;
+	}
 
-	return;
-
-dma_base2alloc_failure:
 	pci_free_consistent(hwif->pci_dev,
 			    IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
 			    hwif->dmatable_cpu, hwif->dmatable_dma);
@@ -476,7 +474,7 @@
 	hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4);
 
 	/* Address of the Ending DMA */
-	memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE);
+	memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
 	ending_dma_addr = cpu_to_le32(hwif->dma_status);
 	hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4);
 
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 20b3929..697f566 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -898,7 +898,6 @@
        	base = (unsigned long) addr;
 
 	hwif->dma_base			= base + (ch ? 0x08 : 0x00);
-	hwif->dma_base2			= base + (ch ? 0x18 : 0x10);
 	hwif->mmio			= 2;
 }
 
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 9b7589e..2af634d 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -248,7 +248,7 @@
 	u8 t;
 
 	for (via_config = via_isa_bridges; via_config->id; via_config++)
-		if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
+		if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
 			!!(via_config->flags & VIA_BAD_ID),
 			via_config->id, NULL))) {
 
@@ -256,6 +256,7 @@
 			if (t >= via_config->rev_min &&
 			    t <= via_config->rev_max)
 				break;
+			pci_dev_put(*isa);
 		}
 
 	return via_config;
@@ -283,6 +284,7 @@
 	via_config = via_config_find(&isa);
 	if (!via_config->id) {
 		printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
+		pci_dev_put(isa);
 		return -ENODEV;
 	}
 
@@ -361,6 +363,7 @@
 		via_dma[via_config->flags & VIA_UDMA],
 		pci_name(dev));
 
+	pci_dev_put(isa);
 	return 0;
 }
 
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 31ad79f..91c5344 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/ide-pmac.c
+ * linux/drivers/ide/ppc/pmac.c
  *
  * Support for IDE interfaces on PowerMacs.
  * These IDE interfaces are memory-mapped and have a DBDMA channel
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index eb09452..0719b64 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -101,7 +101,7 @@
 				return hwif;	/* pick an unused entry */
 		}
 	}
-	for (h = 0; h < 2; ++h) {
+	for (h = 0; h < 2 && h < MAX_HWIFS; ++h) {
 		hwif = ide_hwifs + h;
 		if (hwif->chipset == ide_unknown)
 			return hwif;	/* pick an unused entry */
@@ -795,24 +795,6 @@
 EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
 
 /**
- *	ide_unregister_pci_driver	-	unregister an IDE driver
- *	@driver: driver to remove
- *
- *	Unregister a currently installed IDE driver. Returns are the same
- *	as for pci_unregister_driver
- */
- 
-void ide_pci_unregister_driver(struct pci_driver *driver)
-{
-	if(!pre_init)
-		pci_unregister_driver(driver);
-	else
-		list_del(&driver->node);
-}
-
-EXPORT_SYMBOL_GPL(ide_pci_unregister_driver);
-
-/**
  *	ide_scan_pcidev		-	find an IDE driver for a device
  *	@dev: PCI device to check
  *
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index 2769e50..672b92e 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -140,7 +140,7 @@
 	help
 	  This builds sbp2 for use with non-OHCI host adapters which do not
 	  support physical DMA or for when ohci1394 is run with phys_dma=0.
-	  Physical DMA is data movement without assistence of the drivers'
+	  Physical DMA is data movement without assistance of the drivers'
 	  interrupt handlers.  This option includes the interrupt handlers
 	  that are required in absence of this hardware feature.
 
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 1178bd4..9ae4f3a 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -874,23 +874,25 @@
 	__u16 port;
 	u8 ip_ver;
 
-	id = rdma_create_id(listen_id->event_handler, listen_id->context,
-			    listen_id->ps);
-	if (IS_ERR(id))
-		return NULL;
-
-	rt = &id->route;
-	rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1;
-	rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, GFP_KERNEL);
-	if (!rt->path_rec)
-		goto err;
-
 	if (cma_get_net_info(ib_event->private_data, listen_id->ps,
 			     &ip_ver, &port, &src, &dst))
 		goto err;
 
+	id = rdma_create_id(listen_id->event_handler, listen_id->context,
+			    listen_id->ps);
+	if (IS_ERR(id))
+		goto err;
+
 	cma_save_net_info(&id->route.addr, &listen_id->route.addr,
 			  ip_ver, port, src, dst);
+
+	rt = &id->route;
+	rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1;
+	rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths,
+			       GFP_KERNEL);
+	if (!rt->path_rec)
+		goto destroy_id;
+
 	rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path;
 	if (rt->num_paths == 2)
 		rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
@@ -903,8 +905,10 @@
 	id_priv = container_of(id, struct rdma_id_private, id);
 	id_priv->state = CMA_CONNECT;
 	return id_priv;
-err:
+
+destroy_id:
 	rdma_destroy_id(id);
+err:
 	return NULL;
 }
 
@@ -932,6 +936,7 @@
 	mutex_unlock(&lock);
 	if (ret) {
 		ret = -ENODEV;
+		cma_exch(conn_id, CMA_DESTROYING);
 		cma_release_remove(conn_id);
 		rdma_destroy_id(&conn_id->id);
 		goto out;
@@ -1307,6 +1312,7 @@
 		work->old_state = CMA_ROUTE_QUERY;
 		work->new_state = CMA_ADDR_RESOLVED;
 		work->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
+		work->event.status = status;
 	}
 
 	queue_work(cma_wq, &work->work);
@@ -1862,6 +1868,11 @@
 
 	ret = ib_send_cm_req(id_priv->cm_id.ib, &req);
 out:
+	if (ret && !IS_ERR(id_priv->cm_id.ib)) {
+		ib_destroy_cm_id(id_priv->cm_id.ib);
+		id_priv->cm_id.ib = NULL;
+	}
+
 	kfree(private_data);
 	return ret;
 }
@@ -1889,10 +1900,8 @@
 	cm_id->remote_addr = *sin;
 
 	ret = cma_modify_qp_rtr(&id_priv->id);
-	if (ret) {
-		iw_destroy_cm_id(cm_id);
-		return ret;
-	}
+	if (ret)
+		goto out;
 
 	iw_param.ord = conn_param->initiator_depth;
 	iw_param.ird = conn_param->responder_resources;
@@ -1904,6 +1913,10 @@
 		iw_param.qpn = conn_param->qp_num;
 	ret = iw_cm_connect(cm_id, &iw_param);
 out:
+	if (ret && !IS_ERR(cm_id)) {
+		iw_destroy_cm_id(cm_id);
+		id_priv->cm_id.iw = NULL;
+	}
 	return ret;
 }
 
@@ -2142,12 +2155,9 @@
 
 static void cma_process_remove(struct cma_device *cma_dev)
 {
-	struct list_head remove_list;
 	struct rdma_id_private *id_priv;
 	int ret;
 
-	INIT_LIST_HEAD(&remove_list);
-
 	mutex_lock(&lock);
 	while (!list_empty(&cma_dev->id_list)) {
 		id_priv = list_entry(cma_dev->id_list.next,
@@ -2158,8 +2168,7 @@
 			continue;
 		}
 
-		list_del(&id_priv->list);
-		list_add_tail(&id_priv->list, &remove_list);
+		list_del_init(&id_priv->list);
 		atomic_inc(&id_priv->refcount);
 		mutex_unlock(&lock);
 
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 2380994..024d511 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -49,7 +49,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0016");
+MODULE_VERSION("SVNEHCA_0017");
 
 int ehca_open_aqp1     = 0;
 int ehca_debug_level   = 0;
@@ -239,7 +239,7 @@
 	return ret;
 }
 
-int ehca_register_device(struct ehca_shca *shca)
+int ehca_init_device(struct ehca_shca *shca)
 {
 	int ret;
 
@@ -317,11 +317,6 @@
 	/* shca->ib_device.process_mad	    = ehca_process_mad;	    */
 	shca->ib_device.mmap		    = ehca_mmap;
 
-	ret = ib_register_device(&shca->ib_device);
-	if (ret)
-		ehca_err(&shca->ib_device,
-			 "ib_register_device() failed ret=%x", ret);
-
 	return ret;
 }
 
@@ -561,9 +556,9 @@
 		goto probe1;
 	}
 
-	ret = ehca_register_device(shca);
+	ret = ehca_init_device(shca);
 	if (ret) {
-		ehca_gen_err("Cannot register Infiniband device");
+		ehca_gen_err("Cannot init ehca  device struct");
 		goto probe1;
 	}
 
@@ -571,7 +566,7 @@
 	ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
 	if (ret) {
 		ehca_err(&shca->ib_device, "Cannot create EQ.");
-		goto probe2;
+		goto probe1;
 	}
 
 	ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
@@ -600,6 +595,13 @@
 		goto probe5;
 	}
 
+	ret = ib_register_device(&shca->ib_device);
+	if (ret) {
+		ehca_err(&shca->ib_device,
+			 "ib_register_device() failed ret=%x", ret);
+		goto probe6;
+	}
+
 	/* create AQP1 for port 1 */
 	if (ehca_open_aqp1 == 1) {
 		shca->sport[0].port_state = IB_PORT_DOWN;
@@ -607,7 +609,7 @@
 		if (ret) {
 			ehca_err(&shca->ib_device,
 				 "Cannot create AQP1 for port 1.");
-			goto probe6;
+			goto probe7;
 		}
 	}
 
@@ -618,7 +620,7 @@
 		if (ret) {
 			ehca_err(&shca->ib_device,
 				 "Cannot create AQP1 for port 2.");
-			goto probe7;
+			goto probe8;
 		}
 	}
 
@@ -630,12 +632,15 @@
 
 	return 0;
 
-probe7:
+probe8:
 	ret = ehca_destroy_aqp1(&shca->sport[0]);
 	if (ret)
 		ehca_err(&shca->ib_device,
 			 "Cannot destroy AQP1 for port 1. ret=%x", ret);
 
+probe7:
+	ib_unregister_device(&shca->ib_device);
+
 probe6:
 	ret = ehca_dereg_internal_maxmr(shca);
 	if (ret)
@@ -660,9 +665,6 @@
 		ehca_err(&shca->ib_device,
 			 "Cannot destroy EQ. ret=%x", ret);
 
-probe2:
-	ib_unregister_device(&shca->ib_device);
-
 probe1:
 	ib_dealloc_device(&shca->ib_device);
 
@@ -750,7 +752,7 @@
 	int ret;
 
 	printk(KERN_INFO "eHCA Infiniband Device Driver "
-	                 "(Rel.: SVNEHCA_0016)\n");
+	                 "(Rel.: SVNEHCA_0017)\n");
 	idr_init(&ehca_qp_idr);
 	idr_init(&ehca_cq_idr);
 	spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 9f56bb8..809da3e 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -117,7 +117,7 @@
 		unsigned int l = (unsigned int)(len); \
 		unsigned char *deb = (unsigned char*)(adr);	\
 		for (x = 0; x < l; x += 16) { \
-			printk("EHCA_DMP:%s" format \
+			printk("EHCA_DMP:%s " format \
 			       " adr=%p ofs=%04x %016lx %016lx\n", \
 			       __FUNCTION__, ##args, deb, x, \
 			       *((u64 *)&deb[0]), *((u64 *)&deb[8])); \
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index a504cf6..ce60387 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -241,10 +241,7 @@
 		 * original work request since we may need to resend
 		 * it.
 		 */
-		qp->s_sge.sge = wqe->sg_list[0];
-		qp->s_sge.sg_list = wqe->sg_list + 1;
-		qp->s_sge.num_sge = wqe->wr.num_sge;
-		qp->s_len = len = wqe->length;
+		len = wqe->length;
 		ss = &qp->s_sge;
 		bth2 = 0;
 		switch (wqe->wr.opcode) {
@@ -368,14 +365,23 @@
 		default:
 			goto done;
 		}
+		qp->s_sge.sge = wqe->sg_list[0];
+		qp->s_sge.sg_list = wqe->sg_list + 1;
+		qp->s_sge.num_sge = wqe->wr.num_sge;
+		qp->s_len = wqe->length;
 		if (newreq) {
 			qp->s_tail++;
 			if (qp->s_tail >= qp->s_size)
 				qp->s_tail = 0;
 		}
-		bth2 |= qp->s_psn++ & IPATH_PSN_MASK;
-		if ((int)(qp->s_psn - qp->s_next_psn) > 0)
-			qp->s_next_psn = qp->s_psn;
+		bth2 |= qp->s_psn & IPATH_PSN_MASK;
+		if (wqe->wr.opcode == IB_WR_RDMA_READ)
+			qp->s_psn = wqe->lpsn + 1;
+		else {
+			qp->s_psn++;
+			if ((int)(qp->s_psn - qp->s_next_psn) > 0)
+				qp->s_next_psn = qp->s_psn;
+		}
 		/*
 		 * Put the QP on the pending list so lost ACKs will cause
 		 * a retry.  More than one request can be pending so the
@@ -690,13 +696,6 @@
 	struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
 	struct ipath_ibdev *dev;
 
-	/*
-	 * If there are no requests pending, we are done.
-	 */
-	if (ipath_cmp24(psn, qp->s_next_psn) >= 0 ||
-	    qp->s_last == qp->s_tail)
-		goto done;
-
 	if (qp->s_retry == 0) {
 		wc->wr_id = wqe->wr.wr_id;
 		wc->status = IB_WC_RETRY_EXC_ERR;
@@ -731,8 +730,6 @@
 		dev->n_rc_resends += (int)qp->s_psn - (int)psn;
 
 	reset_psn(qp, psn);
-
-done:
 	tasklet_hi_schedule(&qp->s_task);
 
 bail:
@@ -765,6 +762,7 @@
 	struct ib_wc wc;
 	struct ipath_swqe *wqe;
 	int ret = 0;
+	u32 ack_psn;
 
 	/*
 	 * Remove the QP from the timeout queue (or RNR timeout queue).
@@ -777,26 +775,26 @@
 		list_del_init(&qp->timerwait);
 	spin_unlock(&dev->pending_lock);
 
+	/* Nothing is pending to ACK/NAK. */
+	if (unlikely(qp->s_last == qp->s_tail))
+		goto bail;
+
 	/*
 	 * Note that NAKs implicitly ACK outstanding SEND and RDMA write
 	 * requests and implicitly NAK RDMA read and atomic requests issued
 	 * before the NAK'ed request.  The MSN won't include the NAK'ed
 	 * request but will include an ACK'ed request(s).
 	 */
+	ack_psn = psn;
+	if (aeth >> 29)
+		ack_psn--;
 	wqe = get_swqe_ptr(qp, qp->s_last);
 
-	/* Nothing is pending to ACK/NAK. */
-	if (qp->s_last == qp->s_tail)
-		goto bail;
-
 	/*
 	 * The MSN might be for a later WQE than the PSN indicates so
 	 * only complete WQEs that the PSN finishes.
 	 */
-	while (ipath_cmp24(psn, wqe->lpsn) >= 0) {
-		/* If we are ACKing a WQE, the MSN should be >= the SSN. */
-		if (ipath_cmp24(aeth, wqe->ssn) < 0)
-			break;
+	while (ipath_cmp24(ack_psn, wqe->lpsn) >= 0) {
 		/*
 		 * If this request is a RDMA read or atomic, and the ACK is
 		 * for a later operation, this ACK NAKs the RDMA read or
@@ -807,7 +805,8 @@
 		 * is sent but before the response is received.
 		 */
 		if ((wqe->wr.opcode == IB_WR_RDMA_READ &&
-		     opcode != OP(RDMA_READ_RESPONSE_LAST)) ||
+		     (opcode != OP(RDMA_READ_RESPONSE_LAST) ||
+		       ipath_cmp24(ack_psn, wqe->lpsn) != 0)) ||
 		    ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
 		      wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) &&
 		     (opcode != OP(ATOMIC_ACKNOWLEDGE) ||
@@ -825,6 +824,10 @@
 			 */
 			goto bail;
 		}
+		if (wqe->wr.opcode == IB_WR_RDMA_READ ||
+		    wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
+		    wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
+			tasklet_hi_schedule(&qp->s_task);
 		/* Post a send completion queue entry if requested. */
 		if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) ||
 		    (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
@@ -1055,7 +1058,8 @@
 		/* no AETH, no ACK */
 		if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
 			dev->n_rdma_seq++;
-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+			if (qp->s_last != qp->s_tail)
+				ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
 			goto ack_done;
 		}
 	rdma_read:
@@ -1091,7 +1095,8 @@
 		/* ACKs READ req. */
 		if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
 			dev->n_rdma_seq++;
-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+			if (qp->s_last != qp->s_tail)
+				ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
 			goto ack_done;
 		}
 		/* FALLTHROUGH */
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 42eaed8..a545610 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1601,7 +1601,7 @@
 	dev->mmap = ipath_mmap;
 
 	snprintf(dev->node_desc, sizeof(dev->node_desc),
-		 IPATH_IDSTR " %s", system_utsname.nodename);
+		 IPATH_IDSTR " %s", init_utsname()->nodename);
 
 	ret = ib_register_device(dev);
 	if (ret)
diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig
index d74653d..c75322d 100644
--- a/drivers/infiniband/ulp/ipoib/Kconfig
+++ b/drivers/infiniband/ulp/ipoib/Kconfig
@@ -26,7 +26,7 @@
 	bool "IP-over-InfiniBand data path debugging"
 	depends on INFINIBAND_IPOIB_DEBUG
 	---help---
-	  This option compiles debugging code into the the data path
+	  This option compiles debugging code into the data path
 	  of the IPoIB driver.  The output can be turned on via the
 	  data_debug_level module parameter; however, even with output
 	  turned off, this debugging code will have some performance
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 58223b5..9623231 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -24,6 +24,20 @@
 
 if INPUT
 
+config INPUT_FF_MEMLESS
+	tristate "Support for memoryless force-feedback devices"
+	default n
+	---help---
+	  Say Y here if you have memoryless force-feedback input device
+	  such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual
+	  Power 2, or similar. You will also need to enable hardware-specific
+	  driver.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ff-memless.
+
 comment "Userland interfaces"
 
 config INPUT_MOUSEDEV
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 1a6ff49..a005b1d 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -4,7 +4,11 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_INPUT)		+= input.o
+obj-$(CONFIG_INPUT)		+= input-core.o
+input-core-objs := input.o ff-core.o
+
+obj-$(CONFIG_INPUT_FF_MEMLESS)	+= ff-memless.o
+
 obj-$(CONFIG_INPUT_MOUSEDEV)	+= mousedev.o
 obj-$(CONFIG_INPUT_JOYDEV)	+= joydev.o
 obj-$(CONFIG_INPUT_EVDEV)	+= evdev.o
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c
index 07358fb..5a9653c 100644
--- a/drivers/input/evbug.c
+++ b/drivers/input/evbug.c
@@ -42,10 +42,12 @@
 
 static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
 {
-	printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value);
+	printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
+		handle->dev->phys, type, code, value);
 }
 
-static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev,
+					  const struct input_device_id *id)
 {
 	struct input_handle *handle;
 
@@ -72,7 +74,7 @@
 	kfree(handle);
 }
 
-static struct input_device_id evbug_ids[] = {
+static const struct input_device_id evbug_ids[] = {
 	{ .driver_info = 1 },	/* Matches all devices */
 	{ },			/* Terminating zero entry */
 };
@@ -89,8 +91,7 @@
 
 static int __init evbug_init(void)
 {
-	input_register_handler(&evbug_handler);
-	return 0;
+	return input_register_handler(&evbug_handler);
 }
 
 static void __exit evbug_exit(void)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 4bf4818..6439f37 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -391,8 +391,10 @@
 	struct evdev *evdev = list->evdev;
 	struct input_dev *dev = evdev->handle.dev;
 	struct input_absinfo abs;
+	struct ff_effect effect;
 	int __user *ip = (int __user *)p;
 	int i, t, u, v;
+	int error;
 
 	if (!evdev->exist)
 		return -ENODEV;
@@ -460,27 +462,22 @@
 			return 0;
 
 		case EVIOCSFF:
-			if (dev->upload_effect) {
-				struct ff_effect effect;
-				int err;
+			if (copy_from_user(&effect, p, sizeof(effect)))
+				return -EFAULT;
 
-				if (copy_from_user(&effect, p, sizeof(effect)))
-					return -EFAULT;
-				err = dev->upload_effect(dev, &effect);
-				if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
-					return -EFAULT;
-				return err;
-			} else
-				return -ENOSYS;
+			error = input_ff_upload(dev, &effect, file);
+
+			if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
+				return -EFAULT;
+
+			return error;
 
 		case EVIOCRMFF:
-			if (!dev->erase_effect)
-				return -ENOSYS;
-
-			return dev->erase_effect(dev, (int)(unsigned long) p);
+			return input_ff_erase(dev, (int)(unsigned long) p, file);
 
 		case EVIOCGEFFECTS:
-			if (put_user(dev->ff_effects_max, ip))
+			i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0;
+			if (put_user(i, ip))
 				return -EFAULT;
 			return 0;
 
@@ -604,7 +601,7 @@
 }
 #endif
 
-static struct file_operations evdev_fops = {
+static const struct file_operations evdev_fops = {
 	.owner =	THIS_MODULE,
 	.read =		evdev_read,
 	.write =	evdev_write,
@@ -619,7 +616,8 @@
 	.flush =	evdev_flush
 };
 
-static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev,
+					  const struct input_device_id *id)
 {
 	struct evdev *evdev;
 	struct class_device *cdev;
@@ -669,6 +667,7 @@
 	evdev->exist = 0;
 
 	if (evdev->open) {
+		input_flush_device(handle, NULL);
 		input_close_device(handle);
 		wake_up_interruptible(&evdev->wait);
 		list_for_each_entry(list, &evdev->list, node)
@@ -677,7 +676,7 @@
 		evdev_free(evdev);
 }
 
-static struct input_device_id evdev_ids[] = {
+static const struct input_device_id evdev_ids[] = {
 	{ .driver_info = 1 },	/* Matches all devices */
 	{ },			/* Terminating zero entry */
 };
@@ -696,8 +695,7 @@
 
 static int __init evdev_init(void)
 {
-	input_register_handler(&evdev_handler);
-	return 0;
+	return input_register_handler(&evdev_handler);
 }
 
 static void __exit evdev_exit(void)
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
new file mode 100644
index 0000000..35656ca
--- /dev/null
+++ b/drivers/input/ff-core.c
@@ -0,0 +1,367 @@
+/*
+ *  Force feedback support for Linux input subsystem
+ *
+ *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ *  Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
+ */
+
+/*
+ * 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
+ */
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("ff-core: " format "\n", ## arg)
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+/*
+ * Check that the effect_id is a valid effect and whether the user
+ * is the owner
+ */
+static int check_effect_access(struct ff_device *ff, int effect_id,
+				struct file *file)
+{
+	if (effect_id < 0 || effect_id >= ff->max_effects ||
+	    !ff->effect_owners[effect_id])
+		return -EINVAL;
+
+	if (file && ff->effect_owners[effect_id] != file)
+		return -EACCES;
+
+	return 0;
+}
+
+/*
+ * Checks whether 2 effects can be combined together
+ */
+static inline int check_effects_compatible(struct ff_effect *e1,
+					   struct ff_effect *e2)
+{
+	return e1->type == e2->type &&
+	       (e1->type != FF_PERIODIC ||
+		e1->u.periodic.waveform == e2->u.periodic.waveform);
+}
+
+/*
+ * Convert an effect into compatible one
+ */
+static int compat_effect(struct ff_device *ff, struct ff_effect *effect)
+{
+	int magnitude;
+
+	switch (effect->type) {
+	case FF_RUMBLE:
+		if (!test_bit(FF_PERIODIC, ff->ffbit))
+			return -EINVAL;
+
+		/*
+		 * calculate manginude of sine wave as average of rumble's
+		 * 2/3 of strong magnitude and 1/3 of weak magnitude
+		 */
+		magnitude = effect->u.rumble.strong_magnitude / 3 +
+			    effect->u.rumble.weak_magnitude / 6;
+
+		effect->type = FF_PERIODIC;
+		effect->u.periodic.waveform = FF_SINE;
+		effect->u.periodic.period = 50;
+		effect->u.periodic.magnitude = max(magnitude, 0x7fff);
+		effect->u.periodic.offset = 0;
+		effect->u.periodic.phase = 0;
+		effect->u.periodic.envelope.attack_length = 0;
+		effect->u.periodic.envelope.attack_level = 0;
+		effect->u.periodic.envelope.fade_length = 0;
+		effect->u.periodic.envelope.fade_level = 0;
+
+		return 0;
+
+	default:
+		/* Let driver handle conversion */
+		return 0;
+	}
+}
+
+/**
+ * input_ff_upload() - upload effect into force-feedback device
+ * @dev: input device
+ * @effect: effect to be uploaded
+ * @file: owner of the effect
+ */
+int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
+		    struct file *file)
+{
+	struct ff_device *ff = dev->ff;
+	struct ff_effect *old;
+	int ret = 0;
+	int id;
+
+	if (!test_bit(EV_FF, dev->evbit))
+		return -ENOSYS;
+
+	if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX ||
+	    !test_bit(effect->type, dev->ffbit)) {
+		debug("invalid or not supported effect type in upload");
+		return -EINVAL;
+	}
+
+	if (effect->type == FF_PERIODIC &&
+	    (effect->u.periodic.waveform < FF_WAVEFORM_MIN ||
+	     effect->u.periodic.waveform > FF_WAVEFORM_MAX ||
+	     !test_bit(effect->u.periodic.waveform, dev->ffbit))) {
+		debug("invalid or not supported wave form in upload");
+		return -EINVAL;
+	}
+
+	if (!test_bit(effect->type, ff->ffbit)) {
+		ret = compat_effect(ff, effect);
+		if (ret)
+			return ret;
+	}
+
+	mutex_lock(&ff->mutex);
+
+	if (effect->id == -1) {
+		for (id = 0; id < ff->max_effects; id++)
+		     if (!ff->effect_owners[id])
+			break;
+
+		if (id >= ff->max_effects) {
+			ret = -ENOSPC;
+			goto out;
+		}
+
+		effect->id = id;
+		old = NULL;
+
+	} else {
+		id = effect->id;
+
+		ret = check_effect_access(ff, id, file);
+		if (ret)
+			goto out;
+
+		old = &ff->effects[id];
+
+		if (!check_effects_compatible(effect, old)) {
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	ret = ff->upload(dev, effect, old);
+	if (ret)
+		goto out;
+
+	ff->effects[id] = *effect;
+	ff->effect_owners[id] = file;
+
+ out:
+	mutex_unlock(&ff->mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(input_ff_upload);
+
+/*
+ * Erases the effect if the requester is also the effect owner. The mutex
+ * should already be locked before calling this function.
+ */
+static int erase_effect(struct input_dev *dev, int effect_id,
+			struct file *file)
+{
+	struct ff_device *ff = dev->ff;
+	int error;
+
+	error = check_effect_access(ff, effect_id, file);
+	if (error)
+		return error;
+
+	ff->playback(dev, effect_id, 0);
+
+	if (ff->erase) {
+		error = ff->erase(dev, effect_id);
+		if (error)
+			return error;
+	}
+
+	ff->effect_owners[effect_id] = NULL;
+
+	return 0;
+}
+
+/**
+ * input_ff_erase - erase an effect from device
+ * @dev: input device to erase effect from
+ * @effect_id: id of the ffect to be erased
+ * @file: purported owner of the request
+ *
+ * This function erases a force-feedback effect from specified device.
+ * The effect will only be erased if it was uploaded through the same
+ * file handle that is requesting erase.
+ */
+int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file)
+{
+	struct ff_device *ff = dev->ff;
+	int ret;
+
+	if (!test_bit(EV_FF, dev->evbit))
+		return -ENOSYS;
+
+	mutex_lock(&ff->mutex);
+	ret = erase_effect(dev, effect_id, file);
+	mutex_unlock(&ff->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(input_ff_erase);
+
+/*
+ * flush_effects - erase all effects owned by a file handle
+ */
+static int flush_effects(struct input_dev *dev, struct file *file)
+{
+	struct ff_device *ff = dev->ff;
+	int i;
+
+	debug("flushing now");
+
+	mutex_lock(&ff->mutex);
+
+	for (i = 0; i < ff->max_effects; i++)
+		erase_effect(dev, i, file);
+
+	mutex_unlock(&ff->mutex);
+
+	return 0;
+}
+
+/**
+ * input_ff_event() - generic handler for force-feedback events
+ * @dev: input device to send the effect to
+ * @type: event type (anything but EV_FF is ignored)
+ * @code: event code
+ * @value: event value
+ */
+int input_ff_event(struct input_dev *dev, unsigned int type,
+		   unsigned int code, int value)
+{
+	struct ff_device *ff = dev->ff;
+
+	if (type != EV_FF)
+		return 0;
+
+	mutex_lock(&ff->mutex);
+
+	switch (code) {
+	case FF_GAIN:
+		if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff)
+			break;
+
+		ff->set_gain(dev, value);
+		break;
+
+	case FF_AUTOCENTER:
+		if (!test_bit(FF_AUTOCENTER, dev->ffbit) || value > 0xffff)
+			break;
+
+		ff->set_autocenter(dev, value);
+		break;
+
+	default:
+		ff->playback(dev, code, value);
+		break;
+	}
+
+	mutex_unlock(&ff->mutex);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_event);
+
+/**
+ * input_ff_create() - create force-feedback device
+ * @dev: input device supporting force-feedback
+ * @max_effects: maximum number of effects supported by the device
+ *
+ * This function allocates all necessary memory for a force feedback
+ * portion of an input device and installs all default handlers.
+ * @dev->ffbit should be already set up before calling this function.
+ * Once ff device is created you need to setup its upload, erase,
+ * playback and other handlers before registering input device
+ */
+int input_ff_create(struct input_dev *dev, int max_effects)
+{
+	struct ff_device *ff;
+	int i;
+
+	if (!max_effects) {
+		printk(KERN_ERR
+		       "ff-core: cannot allocate device without any effects\n");
+		return -EINVAL;
+	}
+
+	ff = kzalloc(sizeof(struct ff_device) +
+		     max_effects * sizeof(struct file *), GFP_KERNEL);
+	if (!ff)
+		return -ENOMEM;
+
+	ff->effects = kcalloc(max_effects, sizeof(struct ff_effect),
+			      GFP_KERNEL);
+	if (!ff->effects) {
+		kfree(ff);
+		return -ENOMEM;
+	}
+
+	ff->max_effects = max_effects;
+	mutex_init(&ff->mutex);
+
+	dev->ff = ff;
+	dev->flush = flush_effects;
+	dev->event = input_ff_event;
+	set_bit(EV_FF, dev->evbit);
+
+	/* Copy "true" bits into ff device bitmap */
+	for (i = 0; i <= FF_MAX; i++)
+		if (test_bit(i, dev->ffbit))
+			set_bit(i, ff->ffbit);
+
+	/* we can emulate RUMBLE with periodic effects */
+	if (test_bit(FF_PERIODIC, ff->ffbit))
+		set_bit(FF_RUMBLE, dev->ffbit);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_create);
+
+/**
+ * input_ff_free() - frees force feedback portion of input device
+ * @dev: input device supporintg force feedback
+ *
+ * This function is only needed in error path as input core will
+ * automatically free force feedback structures when device is
+ * destroyed.
+ */
+void input_ff_destroy(struct input_dev *dev)
+{
+	clear_bit(EV_FF, dev->evbit);
+	if (dev->ff) {
+		if (dev->ff->destroy)
+			dev->ff->destroy(dev->ff);
+		kfree(dev->ff->private);
+		kfree(dev->ff);
+		dev->ff = NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(input_ff_destroy);
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
new file mode 100644
index 0000000..cd8b729
--- /dev/null
+++ b/drivers/input/ff-memless.c
@@ -0,0 +1,515 @@
+/*
+ *  Force feedback support for memoryless devices
+ *
+ *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ *  Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
+ */
+
+/*
+ * 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
+ */
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+
+#include "fixp-arith.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anssi Hannula <anssi.hannula@gmail.com>");
+MODULE_DESCRIPTION("Force feedback support for memoryless devices");
+
+/* Number of effects handled with memoryless devices */
+#define FF_MEMLESS_EFFECTS	16
+
+/* Envelope update interval in ms */
+#define FF_ENVELOPE_INTERVAL	50
+
+#define FF_EFFECT_STARTED	0
+#define FF_EFFECT_PLAYING	1
+#define FF_EFFECT_ABORTING	2
+
+struct ml_effect_state {
+	struct ff_effect *effect;
+	unsigned long flags;	/* effect state (STARTED, PLAYING, etc) */
+	int count;		/* loop count of the effect */
+	unsigned long play_at;	/* start time */
+	unsigned long stop_at;	/* stop time */
+	unsigned long adj_at;	/* last time the effect was sent */
+};
+
+struct ml_device {
+	void *private;
+	struct ml_effect_state states[FF_MEMLESS_EFFECTS];
+	int gain;
+	struct timer_list timer;
+	spinlock_t timer_lock;
+	struct input_dev *dev;
+
+	int (*play_effect)(struct input_dev *dev, void *data,
+			   struct ff_effect *effect);
+};
+
+static const struct ff_envelope *get_envelope(const struct ff_effect *effect)
+{
+	static const struct ff_envelope empty_envelope;
+
+	switch (effect->type) {
+		case FF_PERIODIC:
+			return &effect->u.periodic.envelope;
+		case FF_CONSTANT:
+			return &effect->u.constant.envelope;
+		default:
+			return &empty_envelope;
+	}
+}
+
+/*
+ * Check for the next time envelope requires an update on memoryless devices
+ */
+static unsigned long calculate_next_time(struct ml_effect_state *state)
+{
+	const struct ff_envelope *envelope = get_envelope(state->effect);
+	unsigned long attack_stop, fade_start, next_fade;
+
+	if (envelope->attack_length) {
+		attack_stop = state->play_at +
+			msecs_to_jiffies(envelope->attack_length);
+		if (time_before(state->adj_at, attack_stop))
+			return state->adj_at +
+					msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
+	}
+
+	if (state->effect->replay.length) {
+		if (envelope->fade_length) {
+			/* check when fading should start */
+			fade_start = state->stop_at -
+					msecs_to_jiffies(envelope->fade_length);
+
+			if (time_before(state->adj_at, fade_start))
+				return fade_start;
+
+			/* already fading, advance to next checkpoint */
+			next_fade = state->adj_at +
+					msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
+			if (time_before(next_fade, state->stop_at))
+				return next_fade;
+		}
+
+		return state->stop_at;
+	}
+
+	return state->play_at;
+}
+
+static void ml_schedule_timer(struct ml_device *ml)
+{
+	struct ml_effect_state *state;
+	unsigned long now = jiffies;
+	unsigned long earliest = 0;
+	unsigned long next_at;
+	int events = 0;
+	int i;
+
+	debug("calculating next timer");
+
+	for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
+
+		state = &ml->states[i];
+
+		if (!test_bit(FF_EFFECT_STARTED, &state->flags))
+			continue;
+
+		if (test_bit(FF_EFFECT_PLAYING, &state->flags))
+			next_at = calculate_next_time(state);
+		else
+			next_at = state->play_at;
+
+		if (time_before_eq(now, next_at) &&
+		    (++events == 1 || time_before(next_at, earliest)))
+			earliest = next_at;
+	}
+
+	if (!events) {
+		debug("no actions");
+		del_timer(&ml->timer);
+	} else {
+		debug("timer set");
+		mod_timer(&ml->timer, earliest);
+	}
+}
+
+/*
+ * Apply an envelope to a value
+ */
+static int apply_envelope(struct ml_effect_state *state, int value,
+			  struct ff_envelope *envelope)
+{
+	struct ff_effect *effect = state->effect;
+	unsigned long now = jiffies;
+	int time_from_level;
+	int time_of_envelope;
+	int envelope_level;
+	int difference;
+
+	if (envelope->attack_length &&
+	    time_before(now,
+			state->play_at + msecs_to_jiffies(envelope->attack_length))) {
+		debug("value = 0x%x, attack_level = 0x%x", value,
+		      envelope->attack_level);
+		time_from_level = jiffies_to_msecs(now - state->play_at);
+		time_of_envelope = envelope->attack_length;
+		envelope_level = min_t(__s16, envelope->attack_level, 0x7fff);
+
+	} else if (envelope->fade_length && effect->replay.length &&
+		   time_after(now,
+			      state->stop_at - msecs_to_jiffies(envelope->fade_length)) &&
+		   time_before(now, state->stop_at)) {
+		time_from_level = jiffies_to_msecs(state->stop_at - now);
+		time_of_envelope = envelope->fade_length;
+		envelope_level = min_t(__s16, envelope->fade_level, 0x7fff);
+	} else
+		return value;
+
+	difference = abs(value) - envelope_level;
+
+	debug("difference = %d", difference);
+	debug("time_from_level = 0x%x", time_from_level);
+	debug("time_of_envelope = 0x%x", time_of_envelope);
+
+	difference = difference * time_from_level / time_of_envelope;
+
+	debug("difference = %d", difference);
+
+	return value < 0 ?
+		-(difference + envelope_level) : (difference + envelope_level);
+}
+
+/*
+ * Return the type the effect has to be converted into (memless devices)
+ */
+static int get_compatible_type(struct ff_device *ff, int effect_type)
+{
+
+	if (test_bit(effect_type, ff->ffbit))
+		return effect_type;
+
+	if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit))
+		return FF_RUMBLE;
+
+	printk(KERN_ERR
+	       "ff-memless: invalid type in get_compatible_type()\n");
+
+	return 0;
+}
+
+/*
+ * Combine two effects and apply gain.
+ */
+static void ml_combine_effects(struct ff_effect *effect,
+			       struct ml_effect_state *state,
+			       int gain)
+{
+	struct ff_effect *new = state->effect;
+	unsigned int strong, weak, i;
+	int x, y;
+	fixp_t level;
+
+	switch (new->type) {
+	case FF_CONSTANT:
+		i = new->direction * 360 / 0xffff;
+		level = fixp_new16(apply_envelope(state,
+					new->u.constant.level,
+					&new->u.constant.envelope));
+		x = fixp_mult(fixp_sin(i), level) * gain / 0xffff;
+		y = fixp_mult(-fixp_cos(i), level) * gain / 0xffff;
+		/*
+		 * here we abuse ff_ramp to hold x and y of constant force
+		 * If in future any driver wants something else than x and y
+		 * in s8, this should be changed to something more generic
+		 */
+		effect->u.ramp.start_level =
+			max(min(effect->u.ramp.start_level + x, 0x7f), -0x80);
+		effect->u.ramp.end_level =
+			max(min(effect->u.ramp.end_level + y, 0x7f), -0x80);
+		break;
+
+	case FF_RUMBLE:
+		strong = new->u.rumble.strong_magnitude * gain / 0xffff;
+		weak = new->u.rumble.weak_magnitude * gain / 0xffff;
+		effect->u.rumble.strong_magnitude =
+			min(strong + effect->u.rumble.strong_magnitude,
+			    0xffffU);
+		effect->u.rumble.weak_magnitude =
+			min(weak + effect->u.rumble.weak_magnitude, 0xffffU);
+		break;
+
+	case FF_PERIODIC:
+		i = apply_envelope(state, abs(new->u.periodic.magnitude),
+				   &new->u.periodic.envelope);
+
+		/* here we also scale it 0x7fff => 0xffff */
+		i = i * gain / 0x7fff;
+
+		effect->u.rumble.strong_magnitude =
+			min(i + effect->u.rumble.strong_magnitude, 0xffffU);
+		effect->u.rumble.weak_magnitude =
+			min(i + effect->u.rumble.weak_magnitude, 0xffffU);
+		break;
+
+	default:
+		printk(KERN_ERR "ff-memless: invalid type in ml_combine_effects()\n");
+		break;
+	}
+
+}
+
+
+/*
+ * Because memoryless devices have only one effect per effect type active
+ * at one time we have to combine multiple effects into one
+ */
+static int ml_get_combo_effect(struct ml_device *ml,
+			       unsigned long *effect_handled,
+			       struct ff_effect *combo_effect)
+{
+	struct ff_effect *effect;
+	struct ml_effect_state *state;
+	int effect_type;
+	int i;
+
+	memset(combo_effect, 0, sizeof(struct ff_effect));
+
+	for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
+		if (__test_and_set_bit(i, effect_handled))
+			continue;
+
+		state = &ml->states[i];
+		effect = state->effect;
+
+		if (!test_bit(FF_EFFECT_STARTED, &state->flags))
+			continue;
+
+		if (time_before(jiffies, state->play_at))
+			continue;
+
+		/*
+		 * here we have started effects that are either
+		 * currently playing (and may need be aborted)
+		 * or need to start playing.
+		 */
+		effect_type = get_compatible_type(ml->dev->ff, effect->type);
+		if (combo_effect->type != effect_type) {
+			if (combo_effect->type != 0) {
+				__clear_bit(i, effect_handled);
+				continue;
+			}
+			combo_effect->type = effect_type;
+		}
+
+		if (__test_and_clear_bit(FF_EFFECT_ABORTING, &state->flags)) {
+			__clear_bit(FF_EFFECT_PLAYING, &state->flags);
+			__clear_bit(FF_EFFECT_STARTED, &state->flags);
+		} else if (effect->replay.length &&
+			   time_after_eq(jiffies, state->stop_at)) {
+
+			__clear_bit(FF_EFFECT_PLAYING, &state->flags);
+
+			if (--state->count <= 0) {
+				__clear_bit(FF_EFFECT_STARTED, &state->flags);
+			} else {
+				state->play_at = jiffies +
+					msecs_to_jiffies(effect->replay.delay);
+				state->stop_at = state->play_at +
+					msecs_to_jiffies(effect->replay.length);
+			}
+		} else {
+			__set_bit(FF_EFFECT_PLAYING, &state->flags);
+			state->adj_at = jiffies;
+			ml_combine_effects(combo_effect, state, ml->gain);
+		}
+	}
+
+	return combo_effect->type != 0;
+}
+
+static void ml_play_effects(struct ml_device *ml)
+{
+	struct ff_effect effect;
+	DECLARE_BITMAP(handled_bm, FF_MEMLESS_EFFECTS);
+
+	memset(handled_bm, 0, sizeof(handled_bm));
+
+	while (ml_get_combo_effect(ml, handled_bm, &effect))
+		ml->play_effect(ml->dev, ml->private, &effect);
+
+	ml_schedule_timer(ml);
+}
+
+static void ml_effect_timer(unsigned long timer_data)
+{
+	struct input_dev *dev = (struct input_dev *)timer_data;
+	struct ml_device *ml = dev->ff->private;
+
+	debug("timer: updating effects");
+
+	spin_lock(&ml->timer_lock);
+	ml_play_effects(ml);
+	spin_unlock(&ml->timer_lock);
+}
+
+static void ml_ff_set_gain(struct input_dev *dev, u16 gain)
+{
+	struct ml_device *ml = dev->ff->private;
+	int i;
+
+	spin_lock_bh(&ml->timer_lock);
+
+	ml->gain = gain;
+
+	for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
+		__clear_bit(FF_EFFECT_PLAYING, &ml->states[i].flags);
+
+	ml_play_effects(ml);
+
+	spin_unlock_bh(&ml->timer_lock);
+}
+
+static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
+{
+	struct ml_device *ml = dev->ff->private;
+	struct ml_effect_state *state = &ml->states[effect_id];
+
+	spin_lock_bh(&ml->timer_lock);
+
+	if (value > 0) {
+		debug("initiated play");
+
+		__set_bit(FF_EFFECT_STARTED, &state->flags);
+		state->count = value;
+		state->play_at = jiffies +
+				 msecs_to_jiffies(state->effect->replay.delay);
+		state->stop_at = state->play_at +
+				 msecs_to_jiffies(state->effect->replay.length);
+		state->adj_at = state->play_at;
+
+		ml_schedule_timer(ml);
+
+	} else {
+		debug("initiated stop");
+
+		if (test_bit(FF_EFFECT_PLAYING, &state->flags))
+			__set_bit(FF_EFFECT_ABORTING, &state->flags);
+		else
+			__clear_bit(FF_EFFECT_STARTED, &state->flags);
+
+		ml_play_effects(ml);
+	}
+
+	spin_unlock_bh(&ml->timer_lock);
+
+	return 0;
+}
+
+static int ml_ff_upload(struct input_dev *dev,
+			struct ff_effect *effect, struct ff_effect *old)
+{
+	struct ml_device *ml = dev->ff->private;
+	struct ml_effect_state *state = &ml->states[effect->id];
+
+	spin_lock_bh(&ml->timer_lock);
+
+	if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
+		__clear_bit(FF_EFFECT_PLAYING, &state->flags);
+		state->play_at = jiffies +
+				 msecs_to_jiffies(state->effect->replay.delay);
+		state->stop_at = state->play_at +
+				 msecs_to_jiffies(state->effect->replay.length);
+		state->adj_at = state->play_at;
+		ml_schedule_timer(ml);
+	}
+
+	spin_unlock_bh(&ml->timer_lock);
+
+	return 0;
+}
+
+static void ml_ff_destroy(struct ff_device *ff)
+{
+	struct ml_device *ml = ff->private;
+
+	kfree(ml->private);
+}
+
+/**
+ * input_ff_create_memless() - create memoryless FF device
+ * @dev: input device supporting force-feedback
+ * @data: driver-specific data to be passed into @play_effect
+ * @play_effect: driver-specific method for playing FF effect
+ */
+int input_ff_create_memless(struct input_dev *dev, void *data,
+		int (*play_effect)(struct input_dev *, void *, struct ff_effect *))
+{
+	struct ml_device *ml;
+	struct ff_device *ff;
+	int error;
+	int i;
+
+	ml = kzalloc(sizeof(struct ml_device), GFP_KERNEL);
+	if (!ml)
+		return -ENOMEM;
+
+	ml->dev = dev;
+	ml->private = data;
+	ml->play_effect = play_effect;
+	ml->gain = 0xffff;
+	spin_lock_init(&ml->timer_lock);
+	setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
+
+	set_bit(FF_GAIN, dev->ffbit);
+
+	error = input_ff_create(dev, FF_MEMLESS_EFFECTS);
+	if (error) {
+		kfree(ml);
+		return error;
+	}
+
+	ff = dev->ff;
+	ff->private = ml;
+	ff->upload = ml_ff_upload;
+	ff->playback = ml_ff_playback;
+	ff->set_gain = ml_ff_set_gain;
+	ff->destroy = ml_ff_destroy;
+
+	/* we can emulate periodic effects with RUMBLE */
+	if (test_bit(FF_RUMBLE, ff->ffbit)) {
+		set_bit(FF_PERIODIC, dev->ffbit);
+		set_bit(FF_SINE, dev->ffbit);
+		set_bit(FF_TRIANGLE, dev->ffbit);
+		set_bit(FF_SQUARE, dev->ffbit);
+	}
+
+	for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
+		ml->states[i].effect = &ff->effects[i];
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_create_memless);
diff --git a/drivers/usb/input/fixp-arith.h b/drivers/input/fixp-arith.h
similarity index 100%
rename from drivers/usb/input/fixp-arith.h
rename to drivers/input/fixp-arith.h
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 9cb4b9a..1c8c8a5 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -176,6 +176,10 @@
 			break;
 
 		case EV_FF:
+
+			if (value < 0)
+				return;
+
 			if (dev->event)
 				dev->event(dev, type, code, value);
 			break;
@@ -309,7 +313,8 @@
 		if (i != NBITS(max)) \
 			continue;
 
-static struct input_device_id *input_match_device(struct input_device_id *id, struct input_dev *dev)
+static const struct input_device_id *input_match_device(const struct input_device_id *id,
+							struct input_dev *dev)
 {
 	int i;
 
@@ -762,7 +767,9 @@
 {
 	struct input_dev *dev = to_input_dev(class_dev);
 
+	input_ff_destroy(dev);
 	kfree(dev);
+
 	module_put(THIS_MODULE);
 }
 
@@ -899,12 +906,13 @@
 
 	dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
 	if (dev) {
-		dev->dynalloc = 1;
 		dev->cdev.class = &input_class;
 		class_device_initialize(&dev->cdev);
 		mutex_init(&dev->mutex);
 		INIT_LIST_HEAD(&dev->h_list);
 		INIT_LIST_HEAD(&dev->node);
+
+		__module_get(THIS_MODULE);
 	}
 
 	return dev;
@@ -929,17 +937,10 @@
 	static atomic_t input_no = ATOMIC_INIT(0);
 	struct input_handle *handle;
 	struct input_handler *handler;
-	struct input_device_id *id;
+	const struct input_device_id *id;
 	const char *path;
 	int error;
 
-	if (!dev->dynalloc) {
-		printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
-			"Please convert to input_allocate_device() or contact dtor_core@ameritech.net\n",
-			dev->name ? dev->name : "<Unknown>");
-		return -EINVAL;
-	}
-
 	set_bit(EV_SYN, dev->evbit);
 
 	/*
@@ -955,10 +956,8 @@
 		dev->rep[REP_PERIOD] = 33;
 	}
 
-	INIT_LIST_HEAD(&dev->h_list);
 	list_add_tail(&dev->node, &input_dev_list);
 
-	dev->cdev.class = &input_class;
 	snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
 		 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
 
@@ -978,8 +977,6 @@
 	if (error)
 		goto fail3;
 
-	__module_get(THIS_MODULE);
-
 	path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
 	printk(KERN_INFO "input: %s as %s\n",
 		dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
@@ -1008,9 +1005,12 @@
 void input_unregister_device(struct input_dev *dev)
 {
 	struct list_head *node, *next;
+	int code;
 
-	if (!dev)
-		return;
+	for (code = 0; code <= KEY_MAX; code++)
+		if (test_bit(code, dev->key))
+			input_report_key(dev, code, 0);
+	input_sync(dev);
 
 	del_timer_sync(&dev->timer);
 
@@ -1037,19 +1037,20 @@
 }
 EXPORT_SYMBOL(input_unregister_device);
 
-void input_register_handler(struct input_handler *handler)
+int input_register_handler(struct input_handler *handler)
 {
 	struct input_dev *dev;
 	struct input_handle *handle;
-	struct input_device_id *id;
-
-	if (!handler)
-		return;
+	const struct input_device_id *id;
 
 	INIT_LIST_HEAD(&handler->h_list);
 
-	if (handler->fops != NULL)
+	if (handler->fops != NULL) {
+		if (input_table[handler->minor >> 5])
+			return -EBUSY;
+
 		input_table[handler->minor >> 5] = handler;
+	}
 
 	list_add_tail(&handler->node, &input_handler_list);
 
@@ -1063,6 +1064,7 @@
 				}
 
 	input_wakeup_procfs_readers();
+	return 0;
 }
 EXPORT_SYMBOL(input_register_handler);
 
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index d671575..9f3529a 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -451,7 +451,7 @@
 	}
 }
 
-static struct file_operations joydev_fops = {
+static const struct file_operations joydev_fops = {
 	.owner =	THIS_MODULE,
 	.read =		joydev_read,
 	.write =	joydev_write,
@@ -465,7 +465,8 @@
 	.fasync =	joydev_fasync,
 };
 
-static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev,
+					   const struct input_device_id *id)
 {
 	struct joydev *joydev;
 	struct class_device *cdev;
@@ -562,7 +563,7 @@
 		joydev_free(joydev);
 }
 
-static struct input_device_id joydev_blacklist[] = {
+static const struct input_device_id joydev_blacklist[] = {
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
 		.evbit = { BIT(EV_KEY) },
@@ -571,7 +572,7 @@
 	{ }	/* Terminating entry */
 };
 
-static struct input_device_id joydev_ids[] = {
+static const struct input_device_id joydev_ids[] = {
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
 		.evbit = { BIT(EV_ABS) },
@@ -605,8 +606,7 @@
 
 static int __init joydev_init(void)
 {
-	input_register_handler(&joydev_handler);
-	return 0;
+	return input_register_handler(&joydev_handler);
 }
 
 static void __exit joydev_exit(void)
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 67519ef..2712634 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -32,7 +32,7 @@
 	  module will be called analog.
 
 config JOYSTICK_A3D
-	tristate "Assasin 3D and MadCatz Panther devices"
+	tristate "Assassin 3D and MadCatz Panther devices"
 	select GAMEPORT
 	help
 	  Say Y here if you have an FPGaming or MadCatz controller using the
diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c
index 50c9076..8fb0c19 100644
--- a/drivers/input/joystick/iforce/iforce-ff.c
+++ b/drivers/input/joystick/iforce/iforce-ff.c
@@ -165,19 +165,19 @@
 	data[0] = LO(mod_chunk->start);
 	data[1] = HI(mod_chunk->start);
 
-	data[2] = (100*rk)>>15;	/* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
-	data[3] = (100*lk)>>15; /* This code is incorrect on cpus lacking arith shift */
+	data[2] = (100 * rk) >> 15;	/* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
+	data[3] = (100 * lk) >> 15; /* This code is incorrect on cpus lacking arith shift */
 
-	center = (500*center)>>15;
+	center = (500 * center) >> 15;
 	data[4] = LO(center);
 	data[5] = HI(center);
 
-	db = (1000*db)>>16;
+	db = (1000 * db) >> 16;
 	data[6] = LO(db);
 	data[7] = HI(db);
 
-	data[8] = (100*rsat)>>16;
-	data[9] = (100*lsat)>>16;
+	data[8] = (100 * rsat) >> 16;
+	data[9] = (100 * lsat) >> 16;
 
 	iforce_send_packet(iforce, FF_CMD_CONDITION, data);
 	iforce_dump_packet("condition", FF_CMD_CONDITION, data);
@@ -188,6 +188,7 @@
 static unsigned char find_button(struct iforce *iforce, signed short button)
 {
 	int i;
+
 	for (i = 1; iforce->type->btn[i] >= 0; i++)
 		if (iforce->type->btn[i] == button)
 			return i + 1;
@@ -198,19 +199,17 @@
  * Analyse the changes in an effect, and tell if we need to send an condition
  * parameter packet
  */
-static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
+static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
 {
-	int id = new->id;
-	struct ff_effect* old = &iforce->core_effects[id].effect;
-	int ret=0;
+	int ret = 0;
 	int i;
 
 	if (new->type != FF_SPRING && new->type != FF_FRICTION) {
 		printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n");
-		return FALSE;
+		return 0;
 	}
 
-	for(i=0; i<2; i++) {
+	for (i = 0; i < 2; i++) {
 		ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation
 			|| old->u.condition[i].left_saturation != new->u.condition[i].left_saturation
 			|| old->u.condition[i].right_coeff != new->u.condition[i].right_coeff
@@ -225,35 +224,29 @@
  * Analyse the changes in an effect, and tell if we need to send a magnitude
  * parameter packet
  */
-static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect)
+static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect)
 {
-	int id = effect->id;
-	struct ff_effect* old = &iforce->core_effects[id].effect;
-
 	if (effect->type != FF_CONSTANT) {
 		printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
-		return FALSE;
+		return 0;
 	}
 
-	return (old->u.constant.level != effect->u.constant.level);
+	return old->u.constant.level != effect->u.constant.level;
 }
 
 /*
  * Analyse the changes in an effect, and tell if we need to send an envelope
  * parameter packet
  */
-static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect)
+static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect)
 {
-	int id = effect->id;
-	struct ff_effect* old = &iforce->core_effects[id].effect;
-
 	switch (effect->type) {
 	case FF_CONSTANT:
 		if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length
 		|| old->u.constant.envelope.attack_level != effect->u.constant.envelope.attack_level
 		|| old->u.constant.envelope.fade_length != effect->u.constant.envelope.fade_length
 		|| old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level)
-			return TRUE;
+			return 1;
 		break;
 
 	case FF_PERIODIC:
@@ -261,30 +254,26 @@
 		|| old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level
 		|| old->u.periodic.envelope.fade_length != effect->u.periodic.envelope.fade_length
 		|| old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level)
-			return TRUE;
+			return 1;
 		break;
 
 	default:
 		printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
 	}
 
-	return FALSE;
+	return 0;
 }
 
 /*
  * Analyse the changes in an effect, and tell if we need to send a periodic
  * parameter effect
  */
-static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
+static int need_period_modifier(struct ff_effect *old, struct ff_effect *new)
 {
-	int id = new->id;
-	struct ff_effect* old = &iforce->core_effects[id].effect;
-
 	if (new->type != FF_PERIODIC) {
-		printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n");
-		return FALSE;
+		printk(KERN_WARNING "iforce.c: bad effect type in need_period_modifier\n");
+		return 0;
 	}
-
 	return (old->u.periodic.period != new->u.periodic.period
 		|| old->u.periodic.magnitude != new->u.periodic.magnitude
 		|| old->u.periodic.offset != new->u.periodic.offset
@@ -295,19 +284,16 @@
  * Analyse the changes in an effect, and tell if we need to send an effect
  * packet
  */
-static int need_core(struct iforce* iforce, struct ff_effect* new)
+static int need_core(struct ff_effect *old, struct ff_effect *new)
 {
-	int id = new->id;
-	struct ff_effect* old = &iforce->core_effects[id].effect;
-
 	if (old->direction != new->direction
 		|| old->trigger.button != new->trigger.button
 		|| old->trigger.interval != new->trigger.interval
 		|| old->replay.length != new->replay.length
 		|| old->replay.delay != new->replay.delay)
-		return TRUE;
+		return 1;
 
-	return FALSE;
+	return 0;
 }
 /*
  * Send the part common to all effects to the device
@@ -360,7 +346,7 @@
  * Upload a periodic effect to the device
  * See also iforce_upload_constant.
  */
-int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
 {
 	u8 wave_code;
 	int core_id = effect->id;
@@ -371,23 +357,25 @@
 	int param2_err = 1;
 	int core_err = 0;
 
-	if (!is_update || need_period_modifier(iforce, effect)) {
+	if (!old || need_period_modifier(old, effect)) {
 		param1_err = make_period_modifier(iforce, mod1_chunk,
-			is_update,
+			old != NULL,
 			effect->u.periodic.magnitude, effect->u.periodic.offset,
 			effect->u.periodic.period, effect->u.periodic.phase);
-		if (param1_err) return param1_err;
+		if (param1_err)
+			return param1_err;
 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
 	}
 
-	if (!is_update || need_envelope_modifier(iforce, effect)) {
+	if (!old || need_envelope_modifier(old, effect)) {
 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
-			is_update,
+			old !=NULL,
 			effect->u.periodic.envelope.attack_length,
 			effect->u.periodic.envelope.attack_level,
 			effect->u.periodic.envelope.fade_length,
 			effect->u.periodic.envelope.fade_level);
-		if (param2_err) return param2_err;
+		if (param2_err)
+			return param2_err;
 		set_bit(FF_MOD2_IS_USED, core_effect->flags);
 	}
 
@@ -400,7 +388,7 @@
 		default:		wave_code = 0x20; break;
 	}
 
-	if (!is_update || need_core(iforce, effect)) {
+	if (!old || need_core(old, effect)) {
 		core_err = make_core(iforce, effect->id,
 			mod1_chunk->start,
 			mod2_chunk->start,
@@ -429,7 +417,7 @@
  *  0 Ok, effect created or updated
  *  1 effect did not change since last upload, and no packet was therefore sent
  */
-int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
 {
 	int core_id = effect->id;
 	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -439,26 +427,28 @@
 	int param2_err = 1;
 	int core_err = 0;
 
-	if (!is_update || need_magnitude_modifier(iforce, effect)) {
+	if (!old || need_magnitude_modifier(old, effect)) {
 		param1_err = make_magnitude_modifier(iforce, mod1_chunk,
-			is_update,
+			old != NULL,
 			effect->u.constant.level);
-		if (param1_err) return param1_err;
+		if (param1_err)
+			return param1_err;
 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
 	}
 
-	if (!is_update || need_envelope_modifier(iforce, effect)) {
+	if (!old || need_envelope_modifier(old, effect)) {
 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
-			is_update,
+			old != NULL,
 			effect->u.constant.envelope.attack_length,
 			effect->u.constant.envelope.attack_level,
 			effect->u.constant.envelope.fade_length,
 			effect->u.constant.envelope.fade_level);
-		if (param2_err) return param2_err;
+		if (param2_err)
+			return param2_err;
 		set_bit(FF_MOD2_IS_USED, core_effect->flags);
 	}
 
-	if (!is_update || need_core(iforce, effect)) {
+	if (!old || need_core(old, effect)) {
 		core_err = make_core(iforce, effect->id,
 			mod1_chunk->start,
 			mod2_chunk->start,
@@ -483,7 +473,7 @@
 /*
  * Upload an condition effect. Those are for example friction, inertia, springs...
  */
-int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
 {
 	int core_id = effect->id;
 	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -494,37 +484,39 @@
 	int core_err = 0;
 
 	switch (effect->type) {
-		case FF_SPRING:		type = 0x40; break;
-		case FF_DAMPER:		type = 0x41; break;
+		case FF_SPRING:	type = 0x40; break;
+		case FF_DAMPER:	type = 0x41; break;
 		default: return -1;
 	}
 
-	if (!is_update || need_condition_modifier(iforce, effect)) {
+	if (!old || need_condition_modifier(old, effect)) {
 		param_err = make_condition_modifier(iforce, mod1_chunk,
-			is_update,
+			old != NULL,
 			effect->u.condition[0].right_saturation,
 			effect->u.condition[0].left_saturation,
 			effect->u.condition[0].right_coeff,
 			effect->u.condition[0].left_coeff,
 			effect->u.condition[0].deadband,
 			effect->u.condition[0].center);
-		if (param_err) return param_err;
+		if (param_err)
+			return param_err;
 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
 
 		param_err = make_condition_modifier(iforce, mod2_chunk,
-			is_update,
+			old != NULL,
 			effect->u.condition[1].right_saturation,
 			effect->u.condition[1].left_saturation,
 			effect->u.condition[1].right_coeff,
 			effect->u.condition[1].left_coeff,
 			effect->u.condition[1].deadband,
 			effect->u.condition[1].center);
-		if (param_err) return param_err;
+		if (param_err)
+			return param_err;
 		set_bit(FF_MOD2_IS_USED, core_effect->flags);
 
 	}
 
-	if (!is_update || need_core(iforce, effect)) {
+	if (!old || need_core(old, effect)) {
 		core_err = make_core(iforce, effect->id,
 			mod1_chunk->start, mod2_chunk->start,
 			type, 0xc0,
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index b4914e7..24c684b 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -83,103 +83,57 @@
 	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce }
 };
 
+static int iforce_playback(struct input_dev *dev, int effect_id, int value)
+{
+	struct iforce* iforce = dev->private;
+	struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
 
+	if (value > 0)
+		set_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
+	else
+		clear_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
 
-static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+	iforce_control_playback(iforce, effect_id, value);
+	return 0;
+}
+
+static void iforce_set_gain(struct input_dev *dev, u16 gain)
 {
 	struct iforce* iforce = dev->private;
 	unsigned char data[3];
 
-	if (type != EV_FF)
-		return -1;
+	data[0] = gain >> 9;
+	iforce_send_packet(iforce, FF_CMD_GAIN, data);
+}
 
-	switch (code) {
+static void iforce_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+	struct iforce* iforce = dev->private;
+	unsigned char data[3];
 
-		case FF_GAIN:
+	data[0] = 0x03;
+	data[1] = magnitude >> 9;
+	iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
 
-			data[0] = value >> 9;
-			iforce_send_packet(iforce, FF_CMD_GAIN, data);
-
-			return 0;
-
-		case FF_AUTOCENTER:
-
-			data[0] = 0x03;
-			data[1] = value >> 9;
-			iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
-
-			data[0] = 0x04;
-			data[1] = 0x01;
-			iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
-
-			return 0;
-
-		default: /* Play or stop an effect */
-
-			if (!CHECK_OWNERSHIP(code, iforce)) {
-				return -1;
-			}
-			if (value > 0) {
-				set_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
-			}
-			else {
-				clear_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
-			}
-
-			iforce_control_playback(iforce, code, value);
-			return 0;
-	}
-
-	return -1;
+	data[0] = 0x04;
+	data[1] = 0x01;
+	iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
 }
 
 /*
  * Function called when an ioctl is performed on the event dev entry.
  * It uploads an effect to the device
  */
-static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
 {
 	struct iforce* iforce = dev->private;
-	int id;
+	struct iforce_core_effect *core_effect = &iforce->core_effects[effect->id];
 	int ret;
-	int is_update;
 
-/* Check this effect type is supported by this device */
-	if (!test_bit(effect->type, iforce->dev->ffbit))
-		return -EINVAL;
-
-/*
- * If we want to create a new effect, get a free id
- */
-	if (effect->id == -1) {
-
-		for (id = 0; id < FF_EFFECTS_MAX; ++id)
-			if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
-				break;
-
-		if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
-			return -ENOMEM;
-
-		effect->id = id;
-		iforce->core_effects[id].owner = current->pid;
-		iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED);	/* Only IS_USED bit must be set */
-
-		is_update = FALSE;
-	}
-	else {
-		/* We want to update an effect */
-		if (!CHECK_OWNERSHIP(effect->id, iforce))
-			return -EACCES;
-
-		/* Parameter type cannot be updated */
-		if (effect->type != iforce->core_effects[effect->id].effect.type)
-			return -EINVAL;
-
+	if (__test_and_set_bit(FF_CORE_IS_USED, core_effect->flags)) {
 		/* Check the effect is not already being updated */
-		if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags))
+		if (test_bit(FF_CORE_UPDATE, core_effect->flags))
 			return -EAGAIN;
-
-		is_update = TRUE;
 	}
 
 /*
@@ -188,28 +142,28 @@
 	switch (effect->type) {
 
 		case FF_PERIODIC:
-			ret = iforce_upload_periodic(iforce, effect, is_update);
+			ret = iforce_upload_periodic(iforce, effect, old);
 			break;
 
 		case FF_CONSTANT:
-			ret = iforce_upload_constant(iforce, effect, is_update);
+			ret = iforce_upload_constant(iforce, effect, old);
 			break;
 
 		case FF_SPRING:
 		case FF_DAMPER:
-			ret = iforce_upload_condition(iforce, effect, is_update);
+			ret = iforce_upload_condition(iforce, effect, old);
 			break;
 
 		default:
 			return -EINVAL;
 	}
+
 	if (ret == 0) {
 		/* A packet was sent, forbid new updates until we are notified
 		 * that the packet was updated
 		 */
-		set_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags);
+		set_bit(FF_CORE_UPDATE, core_effect->flags);
 	}
-	iforce->core_effects[effect->id].effect = *effect;
 	return ret;
 }
 
@@ -219,20 +173,9 @@
  */
 static int iforce_erase_effect(struct input_dev *dev, int effect_id)
 {
-	struct iforce* iforce = dev->private;
+	struct iforce *iforce = dev->private;
+	struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
 	int err = 0;
-	struct iforce_core_effect* core_effect;
-
-	if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
-		return -EINVAL;
-
-	core_effect = &iforce->core_effects[effect_id];
-
-	/* Check who is trying to erase this effect */
-	if (core_effect->owner != current->pid) {
-		printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, core_effect->owner);
-		return -EACCES;
-	}
 
 	if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
 		err = release_resource(&core_effect->mod1_chunk);
@@ -240,7 +183,7 @@
 	if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
 		err = release_resource(&core_effect->mod2_chunk);
 
-	/*TODO: remember to change that if more FF_MOD* bits are added */
+	/* TODO: remember to change that if more FF_MOD* bits are added */
 	core_effect->flags[0] = 0;
 
 	return err;
@@ -260,33 +203,11 @@
 #endif
 	}
 
-	/* Enable force feedback */
-	iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
-
-	return 0;
-}
-
-static int iforce_flush(struct input_dev *dev, struct file *file)
-{
-	struct iforce *iforce = dev->private;
-	int i;
-
-	/* Erase all effects this process owns */
-	for (i=0; i<dev->ff_effects_max; ++i) {
-
-		if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
-			current->pid == iforce->core_effects[i].owner) {
-
-			/* Stop effect */
-			input_report_ff(dev, i, 0);
-
-			/* Free ressources assigned to effect */
-			if (iforce_erase_effect(dev, i)) {
-				printk(KERN_WARNING "iforce_flush: erase effect %d failed\n", i);
-			}
-		}
-
+	if (test_bit(EV_FF, dev->evbit)) {
+		/* Enable force feedback */
+		iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
 	}
+
 	return 0;
 }
 
@@ -295,17 +216,18 @@
 	struct iforce *iforce = dev->private;
 	int i;
 
-	/* Check: no effect should be present in memory */
-	for (i=0; i<dev->ff_effects_max; ++i) {
-		if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags))
-			break;
-	}
-	if (i<dev->ff_effects_max) {
-		printk(KERN_WARNING "iforce_release: Device still owns effects\n");
-	}
+	if (test_bit(EV_FF, dev->evbit)) {
+		/* Check: no effects should be present in memory */
+		for (i = 0; i < dev->ff->max_effects; i++) {
+			if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
+				printk(KERN_WARNING "iforce_release: Device still owns effects\n");
+				break;
+			}
+		}
 
-	/* Disable force feedback playback */
-	iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
+		/* Disable force feedback playback */
+		iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
+	}
 
 	switch (iforce->bus) {
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
@@ -342,8 +264,10 @@
 int iforce_init_device(struct iforce *iforce)
 {
 	struct input_dev *input_dev;
+	struct ff_device *ff;
 	unsigned char c[] = "CEOV";
-	int i;
+	int i, error;
+	int ff_effects = 0;
 
 	input_dev = input_allocate_device();
 	if (!input_dev)
@@ -378,11 +302,6 @@
 	input_dev->name = "Unknown I-Force device";
 	input_dev->open = iforce_open;
 	input_dev->close = iforce_release;
-	input_dev->flush = iforce_flush;
-	input_dev->event = iforce_input_event;
-	input_dev->upload_effect = iforce_upload_effect;
-	input_dev->erase_effect = iforce_erase_effect;
-	input_dev->ff_effects_max = 10;
 
 /*
  * On-device memory allocation.
@@ -430,15 +349,15 @@
 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
 
 	if (!iforce_get_id_packet(iforce, "N"))
-		iforce->dev->ff_effects_max = iforce->edata[1];
+		ff_effects = iforce->edata[1];
 	else
 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
 
 	/* Check if the device can store more effects than the driver can really handle */
-	if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) {
-		printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
-			iforce->dev->ff_effects_max, FF_EFFECTS_MAX);
-		iforce->dev->ff_effects_max = FF_EFFECTS_MAX;
+	if (ff_effects > IFORCE_EFFECTS_MAX) {
+		printk(KERN_WARNING "iforce: Limiting number of effects to %d (device reports %d)\n",
+		       IFORCE_EFFECTS_MAX, ff_effects);
+		ff_effects = IFORCE_EFFECTS_MAX;
 	}
 
 /*
@@ -472,12 +391,10 @@
  * Set input device bitfields and ranges.
  */
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS);
 
-	for (i = 0; iforce->type->btn[i] >= 0; i++) {
-		signed short t = iforce->type->btn[i];
-		set_bit(t, input_dev->keybit);
-	}
+	for (i = 0; iforce->type->btn[i] >= 0; i++)
+		set_bit(iforce->type->btn[i], input_dev->keybit);
 	set_bit(BTN_DEAD, input_dev->keybit);
 
 	for (i = 0; iforce->type->abs[i] >= 0; i++) {
@@ -516,9 +433,24 @@
 		}
 	}
 
-	for (i = 0; iforce->type->ff[i] >= 0; i++)
-		set_bit(iforce->type->ff[i], input_dev->ffbit);
+	if (ff_effects) {
 
+		for (i = 0; iforce->type->ff[i] >= 0; i++)
+			set_bit(iforce->type->ff[i], input_dev->ffbit);
+
+		error = input_ff_create(input_dev, ff_effects);
+		if (error) {
+			input_free_device(input_dev);
+			return error;
+		}
+
+		ff = input_dev->ff;
+		ff->upload = iforce_upload_effect;
+		ff->erase = iforce_erase_effect;
+		ff->set_gain = iforce_set_gain;
+		ff->set_autocenter = iforce_set_autocenter;
+		ff->playback = iforce_playback;
+	}
 /*
  * Register input device.
  */
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 76cb1f8..8632d47 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -140,7 +140,10 @@
 {
 	int i;
 
-	for (i = 0; i < iforce->dev->ff_effects_max; ++i) {
+	if (!iforce->dev->ff)
+		return 0;
+
+	for (i = 0; i < iforce->dev->ff->max_effects; ++i) {
 		if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
 		    (iforce->core_effects[i].mod1_chunk.start == addr ||
 		     iforce->core_effects[i].mod2_chunk.start == addr)) {
@@ -229,19 +232,17 @@
 			i = data[1] & 0x7f;
 			if (data[1] & 0x80) {
 				if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
-				/* Report play event */
-				input_report_ff_status(dev, i, FF_STATUS_PLAYING);
+					/* Report play event */
+					input_report_ff_status(dev, i, FF_STATUS_PLAYING);
 				}
-			}
-			else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
+			} else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
 				/* Report stop event */
 				input_report_ff_status(dev, i, FF_STATUS_STOPPED);
 			}
 			if (LO(cmd) > 3) {
 				int j;
-				for (j=3; j<LO(cmd); j+=2) {
+				for (j = 3; j < LO(cmd); j += 2)
 					mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
-				}
 			}
 			break;
 	}
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index e9924d6..947df27 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -51,10 +51,7 @@
 #define IFORCE_232	1
 #define IFORCE_USB	2
 
-#define FALSE 0
-#define TRUE 1
-
-#define FF_EFFECTS_MAX	32
+#define IFORCE_EFFECTS_MAX	32
 
 /* Each force feedback effect is made of one core effect, which can be
  * associated to at most to effect modifiers
@@ -67,24 +64,11 @@
 #define FF_CORE_UPDATE		5	/* Effect is being updated */
 #define FF_MODCORE_MAX		5
 
-#define CHECK_OWNERSHIP(i, iforce)	\
-	((i) < FF_EFFECTS_MAX && i >= 0 && \
-	test_bit(FF_CORE_IS_USED, (iforce)->core_effects[(i)].flags) && \
-	(current->pid == 0 || \
-	(iforce)->core_effects[(i)].owner == current->pid))
-
 struct iforce_core_effect {
 	/* Information about where modifiers are stored in the device's memory */
 	struct resource mod1_chunk;
 	struct resource mod2_chunk;
 	unsigned long flags[NBITS(FF_MODCORE_MAX)];
-	pid_t owner;
-	/* Used to keep track of parameters of an effect. They are needed
-	 * to know what parts of an effect changed in an update operation.
-	 * We try to send only parameter packets if possible, as sending
-	 * effect parameter requires the effect to be stoped and restarted
-	 */
-	struct ff_effect effect;
 };
 
 #define FF_CMD_EFFECT		0x010e
@@ -145,7 +129,7 @@
 					/* Force Feedback */
 	wait_queue_head_t wait;
 	struct resource device_memory;
-	struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
+	struct iforce_core_effect core_effects[IFORCE_EFFECTS_MAX];
 	struct mutex mem_mutex;
 };
 
@@ -182,9 +166,9 @@
 int iforce_get_id_packet(struct iforce *iforce, char *packet);
 
 /* iforce-ff.c */
-int iforce_upload_periodic(struct iforce*, struct ff_effect*, int is_update);
-int iforce_upload_constant(struct iforce*, struct ff_effect*, int is_update);
-int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update);
+int iforce_upload_periodic(struct iforce *, struct ff_effect *, struct ff_effect *);
+int iforce_upload_constant(struct iforce *, struct ff_effect *, struct ff_effect *);
+int iforce_upload_condition(struct iforce *, struct ff_effect *, struct ff_effect *);
 
 /* Public variables */
 extern struct serio_driver iforce_serio_drv;
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 83eac3a..679bde3 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -121,6 +121,17 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called newtonkbd.
 
+config KEYBOARD_STOWAWAY
+	tristate "Stowaway keyboard"
+	select SERIO
+	help
+	  Say Y here if you have a Stowaway keyboard on a serial port.
+	  Stowaway compatible keyboards like Dicota Input-PDA keyboard
+	  are also supported by this driver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called stowaway.
+
 config KEYBOARD_CORGI
 	tristate "Corgi keyboard"
 	depends on PXA_SHARPSL
@@ -166,7 +177,7 @@
 	  However, it has been thoroughly tested and is stable.
 
 	  If you want full HIL support including support for multiple
-	  keyboards, mices and tablets, you have to enable the
+	  keyboards, mice, and tablets, you have to enable the
 	  "HP System Device Controller i8042 Support" in the input/serio
 	  submenu.
 
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index b265391..4c79e7b 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -11,6 +11,7 @@
 obj-$(CONFIG_KEYBOARD_AMIGA)		+= amikbd.o
 obj-$(CONFIG_KEYBOARD_LOCOMO)		+= locomokbd.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
+obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
 obj-$(CONFIG_KEYBOARD_CORGI)		+= corgikbd.o
 obj-$(CONFIG_KEYBOARD_SPITZ)		+= spitzkbd.o
 obj-$(CONFIG_KEYBOARD_HIL)		+= hil_kbd.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index a86afd0..40244d4 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -652,9 +652,7 @@
 		return 0;
 	}
 
-	if (param[0] != 0xab && param[0] != 0xac &&	/* Regular and NCD Sun keyboards */
-	    param[0] != 0x2b && param[0] != 0x5d &&	/* Trust keyboard, raw and translated */
-	    param[0] != 0x60 && param[0] != 0x47)	/* NMB SGI keyboard, raw and translated */
+	if (!ps2_is_keyboard_id(param[0]))
 		return -1;
 
 	atkbd->id = (param[0] << 8) | param[1];
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c
new file mode 100644
index 0000000..04c54c5
--- /dev/null
+++ b/drivers/input/keyboard/stowaway.c
@@ -0,0 +1,187 @@
+/*
+ * Stowaway keyboard driver for Linux
+ */
+
+/*
+ *  Copyright (c) 2006 Marek Vasut
+ *
+ *  Based on Newton keyboard driver for Linux
+ *  by Justin Cormack
+ */
+
+/*
+ * 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
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <marek.vasut@gmail.com>, or by paper mail:
+ * Marek Vasut, Liskovecka 559, Frydek-Mistek, 738 01 Czech Republic
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+
+#define DRIVER_DESC	"Stowaway keyboard driver"
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+#define SKBD_KEY_MASK	0x7f
+#define SKBD_RELEASE	0x80
+
+static unsigned char skbd_keycode[128] = {
+	KEY_1, KEY_2, KEY_3, KEY_Z, KEY_4, KEY_5, KEY_6, KEY_7,
+	0, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_GRAVE,
+	KEY_X, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_SPACE,
+	KEY_CAPSLOCK, KEY_TAB, KEY_LEFTCTRL, 0, 0, 0, 0, 0,
+	0, 0, 0, KEY_LEFTALT, 0, 0, 0, 0,
+	0, 0, 0, 0, KEY_C, KEY_V, KEY_B, KEY_N,
+	KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_HOME, KEY_8, KEY_9, KEY_0, KEY_ESC,
+	KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_END, KEY_U, KEY_I, KEY_O, KEY_P,
+	KEY_APOSTROPHE, KEY_ENTER, KEY_PAGEUP,0, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
+	KEY_SLASH, KEY_UP, KEY_PAGEDOWN, 0,KEY_M, KEY_COMMA, KEY_DOT, KEY_INSERT,
+	KEY_DELETE, KEY_LEFT, KEY_DOWN, KEY_RIGHT,  0, 0, 0,
+	KEY_LEFTSHIFT, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7,
+	KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, 0, 0, 0
+};
+
+struct skbd {
+	unsigned char keycode[128];
+	struct input_dev *dev;
+	struct serio *serio;
+	char phys[32];
+};
+
+static irqreturn_t skbd_interrupt(struct serio *serio, unsigned char data,
+				  unsigned int flags, struct pt_regs *regs)
+{
+	struct skbd *skbd = serio_get_drvdata(serio);
+	struct input_dev *dev = skbd->dev;
+
+	if (skbd->keycode[data & SKBD_KEY_MASK]) {
+		input_regs(dev, regs);
+		input_report_key(dev, skbd->keycode[data & SKBD_KEY_MASK],
+				 !(data & SKBD_RELEASE));
+		input_sync(dev);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int skbd_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct skbd *skbd;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
+	int i;
+
+	skbd = kzalloc(sizeof(struct skbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!skbd || !input_dev)
+		goto fail1;
+
+	skbd->serio = serio;
+	skbd->dev = input_dev;
+	snprintf(skbd->phys, sizeof(skbd->phys), "%s/input0", serio->phys);
+	memcpy(skbd->keycode, skbd_keycode, sizeof(skbd->keycode));
+
+	input_dev->name = "Stowaway Keyboard";
+	input_dev->phys = skbd->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_STOWAWAY;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = skbd;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->keycode = skbd->keycode;
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = ARRAY_SIZE(skbd_keycode);
+	for (i = 0; i < ARRAY_SIZE(skbd_keycode); i++)
+		set_bit(skbd_keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
+
+	serio_set_drvdata(serio, skbd);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(skbd->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3: serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(skbd);
+	return err;
+}
+
+static void skbd_disconnect(struct serio *serio)
+{
+	struct skbd *skbd = serio_get_drvdata(serio);
+
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_unregister_device(skbd->dev);
+	kfree(skbd);
+}
+
+static struct serio_device_id skbd_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_STOWAWAY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, skbd_serio_ids);
+
+static struct serio_driver skbd_drv = {
+	.driver		= {
+		.name	= "stowaway",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= skbd_serio_ids,
+	.interrupt	= skbd_interrupt,
+	.connect	= skbd_connect,
+	.disconnect	= skbd_disconnect,
+};
+
+static int __init skbd_init(void)
+{
+	serio_register_driver(&skbd_drv);
+	return 0;
+}
+
+static void __exit skbd_exit(void)
+{
+	serio_unregister_driver(&skbd_drv);
+}
+
+module_init(skbd_init);
+module_exit(skbd_exit);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index d723e9a..9516439 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -20,6 +20,9 @@
  * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
  *
  * Changes/Revisions:
+ *	0.3	09/04/2006 (Anssi Hannula <anssi.hannula@gmail.com>)
+ *		- updated ff support for the changes in kernel interface
+ *		- added MODULE_VERSION
  *	0.2	16/10/2004 (Micah Dowty <micah@navi.cx>)
  *		- added force feedback support
  *              - added UI_SET_PHYS
@@ -107,18 +110,31 @@
 	return request->retval;
 }
 
-static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+static void uinput_dev_set_gain(struct input_dev *dev, u16 gain)
+{
+	uinput_dev_event(dev, EV_FF, FF_GAIN, gain);
+}
+
+static void uinput_dev_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+	uinput_dev_event(dev, EV_FF, FF_AUTOCENTER, magnitude);
+}
+
+static int uinput_dev_playback(struct input_dev *dev, int effect_id, int value)
+{
+	return uinput_dev_event(dev, EV_FF, effect_id, value);
+}
+
+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
 {
 	struct uinput_request request;
 	int retval;
 
-	if (!test_bit(EV_FF, dev->evbit))
-		return -ENOSYS;
-
 	request.id = -1;
 	init_completion(&request.done);
 	request.code = UI_FF_UPLOAD;
-	request.u.effect = effect;
+	request.u.upload.effect = effect;
+	request.u.upload.old = old;
 
 	retval = uinput_request_reserve_slot(dev->private, &request);
 	if (!retval)
@@ -168,6 +184,7 @@
 
 static int uinput_create_device(struct uinput_device *udev)
 {
+	struct input_dev *dev = udev->dev;
 	int error;
 
 	if (udev->state != UIST_SETUP_COMPLETE) {
@@ -175,15 +192,29 @@
 		return -EINVAL;
 	}
 
-	error = input_register_device(udev->dev);
-	if (error) {
-		uinput_destroy_device(udev);
-		return error;
+	if (udev->ff_effects_max) {
+		error = input_ff_create(dev, udev->ff_effects_max);
+		if (error)
+			goto fail1;
+
+		dev->ff->upload = uinput_dev_upload_effect;
+		dev->ff->erase = uinput_dev_erase_effect;
+		dev->ff->playback = uinput_dev_playback;
+		dev->ff->set_gain = uinput_dev_set_gain;
+		dev->ff->set_autocenter = uinput_dev_set_autocenter;
 	}
 
+	error = input_register_device(udev->dev);
+	if (error)
+		goto fail2;
+
 	udev->state = UIST_CREATED;
 
 	return 0;
+
+ fail2:	input_ff_destroy(dev);
+ fail1: uinput_destroy_device(udev);
+	return error;
 }
 
 static int uinput_open(struct inode *inode, struct file *file)
@@ -243,8 +274,6 @@
 		return -ENOMEM;
 
 	udev->dev->event = uinput_dev_event;
-	udev->dev->upload_effect = uinput_dev_upload_effect;
-	udev->dev->erase_effect = uinput_dev_erase_effect;
 	udev->dev->private = udev;
 
 	return 0;
@@ -278,6 +307,8 @@
 		goto exit;
 	}
 
+	udev->ff_effects_max = user_dev->ff_effects_max;
+
 	size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
 	if (!size) {
 		retval = -EINVAL;
@@ -296,7 +327,6 @@
 	dev->id.vendor	= user_dev->id.vendor;
 	dev->id.product	= user_dev->id.product;
 	dev->id.version	= user_dev->id.version;
-	dev->ff_effects_max = user_dev->ff_effects_max;
 
 	size = sizeof(int) * (ABS_MAX + 1);
 	memcpy(dev->absmax, user_dev->absmax, size);
@@ -525,12 +555,17 @@
 				break;
 			}
 			req = uinput_request_find(udev, ff_up.request_id);
-			if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
+			if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) {
 				retval = -EINVAL;
 				break;
 			}
 			ff_up.retval = 0;
-			memcpy(&ff_up.effect, req->u.effect, sizeof(struct ff_effect));
+			memcpy(&ff_up.effect, req->u.upload.effect, sizeof(struct ff_effect));
+			if (req->u.upload.old)
+				memcpy(&ff_up.old, req->u.upload.old, sizeof(struct ff_effect));
+			else
+				memset(&ff_up.old, 0, sizeof(struct ff_effect));
+
 			if (copy_to_user(p, &ff_up, sizeof(ff_up))) {
 				retval = -EFAULT;
 				break;
@@ -561,12 +596,11 @@
 				break;
 			}
 			req = uinput_request_find(udev, ff_up.request_id);
-			if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
+			if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) {
 				retval = -EINVAL;
 				break;
 			}
 			req->retval = ff_up.retval;
-			memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect));
 			uinput_request_done(udev, req);
 			break;
 
@@ -622,6 +656,7 @@
 MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
 MODULE_DESCRIPTION("User level driver support for input subsystem");
 MODULE_LICENSE("GPL");
+MODULE_VERSION("0.3");
 
 module_init(uinput_init);
 module_exit(uinput_exit);
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index de0f46d..4639537 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -248,13 +248,10 @@
 
 	keymap = dmi->driver_data;
 	for (key = keymap; key->type != KE_END; key++) {
-		if (key->type == KE_WIFI) {
+		if (key->type == KE_WIFI)
 			have_wifi = 1;
-			break;
-		} else if (key->type == KE_BLUETOOTH) {
+		else if (key->type == KE_BLUETOOTH)
 			have_bluetooth = 1;
-			break;
-		}
 	}
 	return 1;
 }
@@ -389,7 +386,16 @@
 		},
 		.driver_data = keymap_acer_travelmate_240
 	},
-        {
+	{
+		.callback = dmi_matched,
+		.ident = "Acer TravelMate 2424NWXCi",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
+		},
+		.driver_data = keymap_acer_travelmate_240
+	},
+	{
 		.callback = dmi_matched,
 		.ident = "AOpen 1559AS",
 		.matches = {
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 070d753..450b68a 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -36,7 +36,7 @@
 #define ALPS_PASS	0x20
 #define ALPS_FW_BK_2	0x40
 
-static struct alps_model_info alps_model_data[] = {
+static const struct alps_model_info alps_model_data[] = {
 	{ { 0x33, 0x02, 0x0a },	0x88, 0xf8, ALPS_OLDPROTO },		/* UMAX-530T */
 	{ { 0x53, 0x02, 0x0a },	0xf8, 0xf8, 0 },
 	{ { 0x53, 0x02, 0x14 },	0xf8, 0xf8, 0 },
@@ -209,10 +209,10 @@
 	return PSMOUSE_GOOD_DATA;
 }
 
-static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
+static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
+	static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
 	unsigned char param[4];
 	int i;
 
@@ -504,7 +504,7 @@
 int alps_detect(struct psmouse *psmouse, int set_properties)
 {
 	int version;
-	struct alps_model_info *model;
+	const struct alps_model_info *model;
 
 	if (!(model = alps_get_model(psmouse, &version)))
 		return -1;
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index e428f8d..69db732 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -25,7 +25,7 @@
 	struct input_dev *dev2;		/* Relative device */
 	char name[32];			/* Name */
 	char phys[32];			/* Phys */
-	struct alps_model_info *i; 	/* Info */
+	const struct alps_model_info *i;/* Info */
 	int prev_fin;			/* Finger bit from previous packet */
 };
 
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index c14395b..5e9d250 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -115,13 +115,15 @@
 
 static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-	unsigned char params[] = { 0, 1, 2, 2, 3 };
+	static const unsigned char params[] = { 0, 1, 2, 2, 3 };
+	unsigned char p;
 
 	if (resolution == 0 || resolution > 400)
 		resolution = 400;
 
-	ps2_command(&psmouse->ps2dev, &params[resolution / 100], PSMOUSE_CMD_SETRES);
-	psmouse->resolution = 50 << params[resolution / 100];
+	p = params[resolution / 100];
+	ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
+	psmouse->resolution = 50 << p;
 }
 
 static void lifebook_disconnect(struct psmouse *psmouse)
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 54b696c..7972eec 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -30,9 +30,9 @@
 #define PS2PP_NAV_BTN		0x20
 
 struct ps2pp_info {
-	const int model;
-	unsigned const int kind;
-	unsigned const int features;
+	u8 model;
+	u8 kind;
+	u16 features;
 };
 
 /*
@@ -199,9 +199,9 @@
 	device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr);
 }
 
-static struct ps2pp_info *get_model_info(unsigned char model)
+static const struct ps2pp_info *get_model_info(unsigned char model)
 {
-	static struct ps2pp_info ps2pp_list[] = {
+	static const struct ps2pp_info ps2pp_list[] = {
 		{ 12,	0,			PS2PP_SIDE_BTN},
 		{ 13,	0,			0 },
 		{ 15,	PS2PP_KIND_MX,					/* MX1000 */
@@ -215,6 +215,7 @@
 		{ 51,	0,			0 },
 		{ 52,	PS2PP_KIND_WHEEL,	PS2PP_SIDE_BTN | PS2PP_WHEEL },
 		{ 53,	PS2PP_KIND_WHEEL,	PS2PP_WHEEL },
+		{ 56,	PS2PP_KIND_WHEEL,	PS2PP_SIDE_BTN | PS2PP_WHEEL }, /* Cordless MouseMan Wheel */
 		{ 61,	PS2PP_KIND_MX,					/* MX700 */
 				PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
 				PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
@@ -244,12 +245,11 @@
 				PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
 		{ 114,	PS2PP_KIND_MX,					/* MX310 */
 				PS2PP_WHEEL | PS2PP_SIDE_BTN |
-				PS2PP_TASK_BTN | PS2PP_EXTRA_BTN },
-		{ }
+				PS2PP_TASK_BTN | PS2PP_EXTRA_BTN }
 	};
 	int i;
 
-	for (i = 0; ps2pp_list[i].model; i++)
+	for (i = 0; i < ARRAY_SIZE(ps2pp_list); i++)
 		if (model == ps2pp_list[i].model)
 			return &ps2pp_list[i];
 
@@ -261,7 +261,8 @@
  * Set up input device's properties based on the detected mouse model.
  */
 
-static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
+static void ps2pp_set_model_properties(struct psmouse *psmouse,
+				       const struct ps2pp_info *model_info,
 				       int using_ps2pp)
 {
 	struct input_dev *input_dev = psmouse->dev;
@@ -327,7 +328,7 @@
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
 	unsigned char model, buttons;
-	struct ps2pp_info *model_info;
+	const struct ps2pp_info *model_info;
 	int use_ps2pp = 0;
 
 	param[0] = 0;
@@ -349,7 +350,7 @@
 /*
  * Do Logitech PS2++ / PS2T++ magic init.
  */
-		if (model == 97) { /* Touch Pad 3 */
+		if (model_info->kind == PS2PP_KIND_TP3) { /* Touch Pad 3 */
 
 			/* Unprotect RAM */
 			param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 343afa3..9fb7eb6 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -112,8 +112,8 @@
 
 struct psmouse_protocol {
 	enum psmouse_type type;
-	char *name;
-	char *alias;
+	const char *name;
+	const char *alias;
 	int maxproto;
 	int (*detect)(struct psmouse *, int);
 	int (*init)(struct psmouse *);
@@ -507,15 +507,17 @@
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[2];
-	unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20, 0 };
+	static const unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
 	int i;
 
 	param[0] = 10;
 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 	param[0] = 0;
 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-	for (i = 0; seq[i]; i++)
-		ps2_command(ps2dev, seq + i, PSMOUSE_CMD_SETRATE);
+	for (i = 0; i < ARRAY_SIZE(seq); i++) {
+		param[0] = seq[i];
+		ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+	}
 	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 
 	if (param[0] != 2)
@@ -652,7 +654,7 @@
 	return PSMOUSE_PS2;
 }
 
-static struct psmouse_protocol psmouse_protocols[] = {
+static const struct psmouse_protocol psmouse_protocols[] = {
 	{
 		.type		= PSMOUSE_PS2,
 		.name		= "PS/2",
@@ -726,7 +728,7 @@
 	},
 };
 
-static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
+static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
 {
 	int i;
 
@@ -738,9 +740,9 @@
 	return &psmouse_protocols[0];
 }
 
-static struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
+static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
 {
-	struct psmouse_protocol *p;
+	const struct psmouse_protocol *p;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) {
@@ -795,13 +797,15 @@
 
 void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-	unsigned char params[] = { 0, 1, 2, 2, 3 };
+	static const unsigned char params[] = { 0, 1, 2, 2, 3 };
+	unsigned char p;
 
 	if (resolution == 0 || resolution > 200)
 		resolution = 200;
 
-	ps2_command(&psmouse->ps2dev, &params[resolution / 50], PSMOUSE_CMD_SETRES);
-	psmouse->resolution = 25 << params[resolution / 50];
+	p = params[resolution / 50];
+	ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
+	psmouse->resolution = 25 << p;
 }
 
 /*
@@ -810,12 +814,14 @@
 
 static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
 {
-	unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+	static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+	unsigned char r;
 	int i = 0;
 
 	while (rates[i] > rate) i++;
-	ps2_command(&psmouse->ps2dev, &rates[i], PSMOUSE_CMD_SETRATE);
-	psmouse->rate = rates[i];
+	r = rates[i];
+	ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
+	psmouse->rate = r;
 }
 
 /*
@@ -1031,7 +1037,7 @@
 	mutex_unlock(&psmouse_mutex);
 }
 
-static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
+static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto)
 {
 	struct input_dev *input_dev = psmouse->dev;
 
@@ -1362,7 +1368,7 @@
 	struct serio *serio = psmouse->ps2dev.serio;
 	struct psmouse *parent = NULL;
 	struct input_dev *new_dev;
-	struct psmouse_protocol *proto;
+	const struct psmouse_protocol *proto;
 	int retry = 0;
 
 	if (!(proto = psmouse_protocol_by_name(buf, count)))
@@ -1459,7 +1465,7 @@
 
 static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
 {
-	struct psmouse_protocol *proto;
+	const struct psmouse_protocol *proto;
 
 	if (!val)
 		return -EINVAL;
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index 0023501..680b323 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -42,7 +42,7 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
+static const char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
 					"Logitech M+ Mouse", "Microsoft MZ Mouse", "Logitech MZ+ Mouse",
 					"Logitech MZ++ Mouse"};
 
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index ad5d0a8..392108c 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -430,11 +430,11 @@
 
 static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type)
 {
-	static unsigned char newabs_mask[]	= { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
-	static unsigned char newabs_rel_mask[]	= { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
-	static unsigned char newabs_rslt[]	= { 0x80, 0x00, 0x00, 0xC0, 0x00 };
-	static unsigned char oldabs_mask[]	= { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
-	static unsigned char oldabs_rslt[]	= { 0xC0, 0x00, 0x00, 0x80, 0x00 };
+	static const unsigned char newabs_mask[]	= { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
+	static const unsigned char newabs_rel_mask[]	= { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
+	static const unsigned char newabs_rslt[]	= { 0x80, 0x00, 0x00, 0xC0, 0x00 };
+	static const unsigned char oldabs_mask[]	= { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
+	static const unsigned char oldabs_rslt[]	= { 0xC0, 0x00, 0x00, 0x80, 0x00 };
 
 	if (idx < 0 || idx > 4)
 		return 0;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 1f851ac..a22a74a 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -614,7 +614,7 @@
 		(list->mousedev->exist ? 0 : (POLLHUP | POLLERR));
 }
 
-static struct file_operations mousedev_fops = {
+static const struct file_operations mousedev_fops = {
 	.owner =	THIS_MODULE,
 	.read =		mousedev_read,
 	.write =	mousedev_write,
@@ -624,7 +624,8 @@
 	.fasync =	mousedev_fasync,
 };
 
-static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev,
+					     const struct input_device_id *id)
 {
 	struct mousedev *mousedev;
 	struct class_device *cdev;
@@ -688,7 +689,7 @@
 	}
 }
 
-static struct input_device_id mousedev_ids[] = {
+static const struct input_device_id mousedev_ids[] = {
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
 		.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
@@ -737,7 +738,12 @@
 
 static int __init mousedev_init(void)
 {
-	input_register_handler(&mousedev_handler);
+	struct class_device *cdev;
+	int error;
+
+	error = input_register_handler(&mousedev_handler);
+	if (error)
+		return error;
 
 	memset(&mousedev_mix, 0, sizeof(struct mousedev));
 	INIT_LIST_HEAD(&mousedev_mix.list);
@@ -746,12 +752,20 @@
 	mousedev_mix.exist = 1;
 	mousedev_mix.minor = MOUSEDEV_MIX;
 
-	class_device_create(&input_class, NULL,
+	cdev = class_device_create(&input_class, NULL,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
+	if (IS_ERR(cdev)) {
+		input_unregister_handler(&mousedev_handler);
+		return PTR_ERR(cdev);
+	}
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-	if (!(psaux_registered = !misc_register(&psaux_mouse)))
-		printk(KERN_WARNING "mice: could not misc_register the device\n");
+	error = misc_register(&psaux_mouse);
+	if (error)
+		printk(KERN_WARNING "mice: could not register psaux device, "
+			"error: %d\n", error);
+	else
+		psaux_registered = 1;
 #endif
 
 	printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");
diff --git a/drivers/input/power.c b/drivers/input/power.c
index 51a519e..ee82464 100644
--- a/drivers/input/power.c
+++ b/drivers/input/power.c
@@ -98,7 +98,7 @@
 
 static struct input_handle *power_connect(struct input_handler *handler,
 					  struct input_dev *dev,
-					  struct input_device_id *id)
+					  const struct input_device_id *id)
 {
 	struct input_handle *handle;
 
@@ -120,7 +120,7 @@
 	kfree(handle);
 }
 
-static struct input_device_id power_ids[] = {
+static const struct input_device_id power_ids[] = {
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
 		.evbit = { BIT(EV_KEY) },
@@ -150,8 +150,7 @@
 
 static int __init power_init(void)
 {
-	input_register_handler(&power_handler);
-	return 0;
+	return input_register_handler(&power_handler);
 }
 
 static void __exit power_exit(void)
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index 98acf17..8cdbfec 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -115,9 +115,9 @@
 	depends on GSC && SERIO
 	default y
 	---help---
-	  This option enables supports for the the "System Device
+	  This option enables support for the "System Device
 	  Controller", an i8042 carrying microcode to manage a
-	  few miscellanous devices on some Hewlett Packard systems.
+	  few miscellaneous devices on some Hewlett Packard systems.
 	  The SDC itself contains a 10ms resolution timer/clock capable
 	  of delivering interrupts on a periodic and one-shot basis.
 	  The SDC may also be connected to a battery-backed real-time
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index f606e96..8738edd 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -160,6 +160,13 @@
 		},
 	},
 	{
+		.ident = "Toshiba Equium A110",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
+		},
+	},
+	{
 		.ident = "Alienware Sentia",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
@@ -180,6 +187,13 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
 		},
 	},
+	{
+		.ident = "Amoi M636/A737",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
+		},
+	},
 	{ }
 };
 
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 06a3f25..1bb0c76 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -90,46 +90,24 @@
 struct i8042_port {
 	struct serio *serio;
 	int irq;
-	unsigned char disable;
-	unsigned char irqen;
 	unsigned char exists;
 	signed char mux;
-	char name[8];
 };
 
 #define I8042_KBD_PORT_NO	0
 #define I8042_AUX_PORT_NO	1
 #define I8042_MUX_PORT_NO	2
 #define I8042_NUM_PORTS		(I8042_NUM_MUX_PORTS + 2)
-static struct i8042_port i8042_ports[I8042_NUM_PORTS] = {
-	{
-		.disable	= I8042_CTR_KBDDIS,
-		.irqen		= I8042_CTR_KBDINT,
-		.mux		= -1,
-		.name		= "KBD",
-	},
-	{
-		.disable	= I8042_CTR_AUXDIS,
-		.irqen		= I8042_CTR_AUXINT,
-		.mux		= -1,
-		.name		= "AUX",
-	}
-};
+
+static struct i8042_port i8042_ports[I8042_NUM_PORTS];
 
 static unsigned char i8042_initial_ctr;
 static unsigned char i8042_ctr;
-static unsigned char i8042_mux_open;
 static unsigned char i8042_mux_present;
-static struct timer_list i8042_timer;
+static unsigned char i8042_kbd_irq_registered;
+static unsigned char i8042_aux_irq_registered;
 static struct platform_device *i8042_platform_device;
 
-
-/*
- * Shared IRQ's require a device pointer, but this driver doesn't support
- * multiple devices
- */
-#define i8042_request_irq_cookie (&i8042_timer)
-
 static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 /*
@@ -141,6 +119,7 @@
 static int i8042_wait_read(void)
 {
 	int i = 0;
+
 	while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
 		udelay(50);
 		i++;
@@ -151,6 +130,7 @@
 static int i8042_wait_write(void)
 {
 	int i = 0;
+
 	while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
 		udelay(50);
 		i++;
@@ -192,48 +172,57 @@
  * encoded in bits 8-11 of the command number.
  */
 
-static int i8042_command(unsigned char *param, int command)
+static int __i8042_command(unsigned char *param, int command)
 {
-	unsigned long flags;
-	int i, retval, auxerr = 0;
+	int i, error;
 
 	if (i8042_noloop && command == I8042_CMD_AUX_LOOP)
 		return -1;
 
-	spin_lock_irqsave(&i8042_lock, flags);
-
-	if ((retval = i8042_wait_write()))
-		goto out;
+	error = i8042_wait_write();
+	if (error)
+		return error;
 
 	dbg("%02x -> i8042 (command)", command & 0xff);
 	i8042_write_command(command & 0xff);
 
 	for (i = 0; i < ((command >> 12) & 0xf); i++) {
-		if ((retval = i8042_wait_write()))
-			goto out;
+		error = i8042_wait_write();
+		if (error)
+			return error;
 		dbg("%02x -> i8042 (parameter)", param[i]);
 		i8042_write_data(param[i]);
 	}
 
 	for (i = 0; i < ((command >> 8) & 0xf); i++) {
-		if ((retval = i8042_wait_read()))
-			goto out;
+		error = i8042_wait_read();
+		if (error) {
+			dbg("     -- i8042 (timeout)");
+			return error;
+		}
 
 		if (command == I8042_CMD_AUX_LOOP &&
 		    !(i8042_read_status() & I8042_STR_AUXDATA)) {
-			retval = auxerr = -1;
-			goto out;
+			dbg("     -- i8042 (auxerr)");
+			return -1;
 		}
 
 		param[i] = i8042_read_data();
 		dbg("%02x <- i8042 (return)", param[i]);
 	}
 
-	if (retval)
-		dbg("     -- i8042 (%s)", auxerr ? "auxerr" : "timeout");
+	return 0;
+}
 
- out:
+static int i8042_command(unsigned char *param, int command)
+{
+	unsigned long flags;
+	int retval;
+
+	spin_lock_irqsave(&i8042_lock, flags);
+	retval = __i8042_command(param, command);
 	spin_unlock_irqrestore(&i8042_lock, flags);
+
 	return retval;
 }
 
@@ -248,7 +237,7 @@
 
 	spin_lock_irqsave(&i8042_lock, flags);
 
-	if(!(retval = i8042_wait_write())) {
+	if (!(retval = i8042_wait_write())) {
 		dbg("%02x -> i8042 (kbd-data)", c);
 		i8042_write_data(c);
 	}
@@ -287,100 +276,6 @@
 }
 
 /*
- * i8042_activate_port() enables port on a chip.
- */
-
-static int i8042_activate_port(struct i8042_port *port)
-{
-	if (!port->serio)
-		return -1;
-
-	i8042_flush();
-
-	/*
-	 * Enable port again here because it is disabled if we are
-	 * resuming (normally it is enabled already).
-	 */
-	i8042_ctr &= ~port->disable;
-
-	i8042_ctr |= port->irqen;
-
-	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		i8042_ctr &= ~port->irqen;
-		return -1;
-	}
-
-	return 0;
-}
-
-
-/*
- * i8042_open() is called when a port is open by the higher layer.
- * It allocates the interrupt and calls i8042_enable_port.
- */
-
-static int i8042_open(struct serio *serio)
-{
-	struct i8042_port *port = serio->port_data;
-
-	if (port->mux != -1)
-		if (i8042_mux_open++)
-			return 0;
-
-	if (request_irq(port->irq, i8042_interrupt,
-			IRQF_SHARED, "i8042", i8042_request_irq_cookie)) {
-		printk(KERN_ERR "i8042.c: Can't get irq %d for %s, unregistering the port.\n", port->irq, port->name);
-		goto irq_fail;
-	}
-
-	if (i8042_activate_port(port)) {
-		printk(KERN_ERR "i8042.c: Can't activate %s, unregistering the port\n", port->name);
-		goto activate_fail;
-	}
-
-	i8042_interrupt(0, NULL, NULL);
-
-	return 0;
-
- activate_fail:
-	free_irq(port->irq, i8042_request_irq_cookie);
-
- irq_fail:
-	serio_unregister_port_delayed(serio);
-
-	return -1;
-}
-
-/*
- * i8042_close() frees the interrupt, so that it can possibly be used
- * by another driver. We never know - if the user doesn't have a mouse,
- * the BIOS could have used the AUX interrupt for PCI.
- */
-
-static void i8042_close(struct serio *serio)
-{
-	struct i8042_port *port = serio->port_data;
-
-	if (port->mux != -1)
-		if (--i8042_mux_open)
-			return;
-
-	i8042_ctr &= ~port->irqen;
-
-	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		printk(KERN_WARNING "i8042.c: Can't write CTR while closing %s.\n", port->name);
-/*
- * We still want to continue and free IRQ so if more data keeps coming in
- * kernel will just ignore the irq.
- */
-	}
-
-	free_irq(port->irq, i8042_request_irq_cookie);
-
-	i8042_flush();
-}
-
-/*
  * i8042_start() is called by serio core when port is about to finish
  * registering. It will mark port as existing so i8042_interrupt can
  * start sending data through it.
@@ -423,8 +318,6 @@
 	unsigned int port_no;
 	int ret;
 
-	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
-
 	spin_lock_irqsave(&i8042_lock, flags);
 	str = i8042_read_status();
 	if (unlikely(~str & I8042_STR_OBF)) {
@@ -480,8 +373,8 @@
 
 	port = &i8042_ports[port_no];
 
-	dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
-	    data, port->name, irq,
+	dbg("%02x <- i8042 (interrupt, %d, %d%s%s)",
+	    data, port_no, irq,
 	    dfl & SERIO_PARITY ? ", bad parity" : "",
 	    dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
@@ -494,6 +387,58 @@
 }
 
 /*
+ * i8042_enable_kbd_port enables keybaord port on chip
+ */
+
+static int i8042_enable_kbd_port(void)
+{
+	i8042_ctr &= ~I8042_CTR_KBDDIS;
+	i8042_ctr |= I8042_CTR_KBDINT;
+
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+		printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/*
+ * i8042_enable_aux_port enables AUX (mouse) port on chip
+ */
+
+static int i8042_enable_aux_port(void)
+{
+	i8042_ctr &= ~I8042_CTR_AUXDIS;
+	i8042_ctr |= I8042_CTR_AUXINT;
+
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+		printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/*
+ * i8042_enable_mux_ports enables 4 individual AUX ports after
+ * the controller has been switched into Multiplexed mode
+ */
+
+static int i8042_enable_mux_ports(void)
+{
+	unsigned char param;
+	int i;
+
+	for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+		i8042_command(&param, I8042_CMD_MUX_PFX + i);
+		i8042_command(&param, I8042_CMD_AUX_ENABLE);
+	}
+
+	return i8042_enable_aux_port();
+}
+
+/*
  * i8042_set_mux_mode checks whether the controller has an active
  * multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode.
  */
@@ -510,8 +455,7 @@
 
 /*
  * Internal loopback test - send three bytes, they should come back from the
- * mouse interface, the last should be version. Note that we negate mouseport
- * command responses for the i8042_check_aux() routine.
+ * mouse interface, the last should be version.
  */
 
 	param = 0xf0;
@@ -530,41 +474,6 @@
 	return 0;
 }
 
-
-/*
- * i8042_enable_mux_ports enables 4 individual AUX ports after
- * the controller has been switched into Multiplexed mode
- */
-
-static int i8042_enable_mux_ports(void)
-{
-	unsigned char param;
-	int i;
-/*
- * Disable all muxed ports by disabling AUX.
- */
-
-	i8042_ctr |= I8042_CTR_AUXDIS;
-	i8042_ctr &= ~I8042_CTR_AUXINT;
-
-	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");
-		return -1;
-	}
-
-/*
- * Enable all muxed ports.
- */
-
-	for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
-		i8042_command(&param, I8042_CMD_MUX_PFX + i);
-		i8042_command(&param, I8042_CMD_AUX_ENABLE);
-	}
-
-	return 0;
-}
-
-
 /*
  * i8042_check_mux() checks whether the controller supports the PS/2 Active
  * Multiplexing specification by Synaptics, Phoenix, Insyde and
@@ -578,21 +487,56 @@
 	if (i8042_set_mux_mode(1, &mux_version))
 		return -1;
 
-	/* Workaround for interference with USB Legacy emulation */
-	/* that causes a v10.12 MUX to be found. */
+/*
+ * Workaround for interference with USB Legacy emulation
+ * that causes a v10.12 MUX to be found.
+ */
 	if (mux_version == 0xAC)
 		return -1;
 
 	printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
 		(mux_version >> 4) & 0xf, mux_version & 0xf);
 
-	if (i8042_enable_mux_ports())
-		return -1;
+/*
+ * Disable all muxed ports by disabling AUX.
+ */
+	i8042_ctr |= I8042_CTR_AUXDIS;
+	i8042_ctr &= ~I8042_CTR_AUXINT;
+
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+		printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");
+		return -EIO;
+	}
 
 	i8042_mux_present = 1;
+
 	return 0;
 }
 
+/*
+ * The following is used to test AUX IRQ delivery.
+ */
+static struct completion i8042_aux_irq_delivered __devinitdata;
+static int i8042_irq_being_tested __devinitdata;
+
+static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+	unsigned char str, data;
+
+	spin_lock_irqsave(&i8042_lock, flags);
+	str = i8042_read_status();
+	if (str & I8042_STR_OBF) {
+		data = i8042_read_data();
+		if (i8042_irq_being_tested &&
+		    data == 0xa5 && (str & I8042_STR_AUXDATA))
+			complete(&i8042_aux_irq_delivered);
+	}
+	spin_unlock_irqrestore(&i8042_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
 
 /*
  * i8042_check_aux() applies as much paranoia as it can at detecting
@@ -601,18 +545,10 @@
 
 static int __devinit i8042_check_aux(void)
 {
+	int retval = -1;
+	int irq_registered = 0;
+	unsigned long flags;
 	unsigned char param;
-	static int i8042_check_aux_cookie;
-
-/*
- * Check if AUX irq is available. If it isn't, then there is no point
- * in trying to detect AUX presence.
- */
-
-	if (request_irq(i8042_ports[I8042_AUX_PORT_NO].irq, i8042_interrupt,
-			IRQF_SHARED, "i8042", &i8042_check_aux_cookie))
-                return -1;
-	free_irq(i8042_ports[I8042_AUX_PORT_NO].irq, &i8042_check_aux_cookie);
 
 /*
  * Get rid of bytes in the queue.
@@ -637,9 +573,9 @@
  * AUX ports, we test for this only when the LOOP command failed.
  */
 
-		if (i8042_command(&param, I8042_CMD_AUX_TEST)
-			|| (param && param != 0xfa && param != 0xff))
-				return -1;
+		if (i8042_command(&param, I8042_CMD_AUX_TEST) ||
+		    (param && param != 0xfa && param != 0xff))
+			return -1;
 	}
 
 /*
@@ -659,6 +595,54 @@
 		return -1;
 
 /*
+ * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and
+ * used it for a PCI card or somethig else.
+ */
+
+	if (i8042_noloop) {
+/*
+ * Without LOOP command we can't test AUX IRQ delivery. Assume the port
+ * is working and hope we are right.
+ */
+		retval = 0;
+		goto out;
+	}
+
+	if (request_irq(I8042_AUX_IRQ, i8042_aux_test_irq, IRQF_SHARED,
+			"i8042", i8042_platform_device))
+		goto out;
+
+	irq_registered = 1;
+
+	if (i8042_enable_aux_port())
+		goto out;
+
+	spin_lock_irqsave(&i8042_lock, flags);
+
+	init_completion(&i8042_aux_irq_delivered);
+	i8042_irq_being_tested = 1;
+
+	param = 0xa5;
+	retval = __i8042_command(&param, I8042_CMD_AUX_LOOP & 0xf0ff);
+
+	spin_unlock_irqrestore(&i8042_lock, flags);
+
+	if (retval)
+		goto out;
+
+	if (wait_for_completion_timeout(&i8042_aux_irq_delivered,
+					msecs_to_jiffies(250)) == 0) {
+/*
+ * AUX IRQ was never delivered so we need to flush the controller to
+ * get rid of the byte we put there; otherwise keyboard may not work.
+ */
+		i8042_flush();
+		retval = -1;
+	}
+
+ out:
+
+/*
  * Disable the interface.
  */
 
@@ -666,47 +650,25 @@
 	i8042_ctr &= ~I8042_CTR_AUXINT;
 
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
-		return -1;
+		retval = -1;
 
-	return 0;
+	if (irq_registered)
+		free_irq(I8042_AUX_IRQ, i8042_platform_device);
+
+	return retval;
 }
 
-
-/*
- * i8042_port_register() marks the device as existing,
- * registers it, and reports to the user.
- */
-
-static int __devinit i8042_port_register(struct i8042_port *port)
+static int i8042_controller_check(void)
 {
-	i8042_ctr &= ~port->disable;
-
-	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
-		kfree(port->serio);
-		port->serio = NULL;
-		i8042_ctr |= port->disable;
-		return -EIO;
+	if (i8042_flush() == I8042_BUFFER_SIZE) {
+		printk(KERN_ERR "i8042.c: No controller found.\n");
+		return -ENODEV;
 	}
 
-	printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
-	       port->name,
-	       (unsigned long) I8042_DATA_REG,
-	       (unsigned long) I8042_COMMAND_REG,
-	       port->irq);
-
-	serio_register_port(port->serio);
-
 	return 0;
 }
 
-
-static void i8042_timer_func(unsigned long data)
-{
-	i8042_interrupt(0, NULL, NULL);
-}
-
-static int i8042_ctl_test(void)
+static int i8042_controller_selftest(void)
 {
 	unsigned char param;
 
@@ -715,13 +677,13 @@
 
 	if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
 		printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
-		return -1;
+		return -ENODEV;
 	}
 
 	if (param != I8042_RET_CTL_TEST) {
 		printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
 			 param, I8042_RET_CTL_TEST);
-		return -1;
+		return -EIO;
 	}
 
 	return 0;
@@ -738,25 +700,12 @@
 	unsigned long flags;
 
 /*
- * Test the i8042. We need to know if it thinks it's working correctly
- * before doing anything else.
- */
-
-	if (i8042_flush() == I8042_BUFFER_SIZE) {
-		printk(KERN_ERR "i8042.c: No controller found.\n");
-		return -1;
-	}
-
-	if (i8042_ctl_test())
-		return -1;
-
-/*
  * Save the CTR for restoral on unload / reboot.
  */
 
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
 		printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
-		return -1;
+		return -EIO;
 	}
 
 	i8042_initial_ctr = i8042_ctr;
@@ -805,7 +754,7 @@
 
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
 		printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
-		return -1;
+		return -EIO;
 	}
 
 	return 0;
@@ -813,15 +762,12 @@
 
 
 /*
- * Reset the controller.
- */
-static void i8042_controller_reset(void)
-{
-/*
- * Reset the controller if requested.
+ * Reset the controller and reset CRT to the original value set by BIOS.
  */
 
-	i8042_ctl_test();
+static void i8042_controller_reset(void)
+{
+	i8042_flush();
 
 /*
  * Disable MUX mode if present.
@@ -831,12 +777,16 @@
 		i8042_set_mux_mode(0, NULL);
 
 /*
+ * Reset the controller if requested.
+ */
+
+	i8042_controller_selftest();
+
+/*
  * Restore the original control register setting.
  */
 
-	i8042_ctr = i8042_initial_ctr;
-
-	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+	if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))
 		printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");
 }
 
@@ -850,14 +800,12 @@
 {
 	int i;
 
-	i8042_flush();
-
 /*
  * Reset anything that is connected to the ports.
  */
 
 	for (i = 0; i < I8042_NUM_PORTS; i++)
-		if (i8042_ports[i].exists)
+		if (i8042_ports[i].serio)
 			serio_cleanup(i8042_ports[i].serio);
 
 	i8042_controller_reset();
@@ -913,8 +861,7 @@
 
 static int i8042_suspend(struct platform_device *dev, pm_message_t state)
 {
-	del_timer_sync(&i8042_timer);
-	i8042_controller_reset();
+	i8042_controller_cleanup();
 
 	return 0;
 }
@@ -926,33 +873,39 @@
 
 static int i8042_resume(struct platform_device *dev)
 {
-	int i;
+	int error;
 
-	if (i8042_ctl_test())
-		return -1;
+	error = i8042_controller_check();
+	if (error)
+		return error;
 
+	error = i8042_controller_selftest();
+	if (error)
+		return error;
+
+/*
+ * Restore pre-resume CTR value and disable all ports
+ */
+
+	i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;
+	i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		printk(KERN_ERR "i8042: Can't write CTR\n");
-		return -1;
+		printk(KERN_ERR "i8042: Can't write CTR to resume\n");
+		return -EIO;
 	}
 
-	if (i8042_mux_present)
+	if (i8042_mux_present) {
 		if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports())
-			printk(KERN_WARNING "i8042: failed to resume active multiplexor, mouse won't work.\n");
+			printk(KERN_WARNING
+				"i8042: failed to resume active multiplexor, "
+				"mouse won't work.\n");
+	} else if (i8042_ports[I8042_AUX_PORT_NO].serio)
+		i8042_enable_aux_port();
 
-/*
- * Activate all ports.
- */
+	if (i8042_ports[I8042_KBD_PORT_NO].serio)
+		i8042_enable_kbd_port();
 
-	for (i = 0; i < I8042_NUM_PORTS; i++)
-		i8042_activate_port(&i8042_ports[i]);
-
-/*
- * Restart timer (for polling "stuck" data)
- */
-	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
-
-	panic_blink = i8042_panic_blink;
+	i8042_interrupt(0, NULL, NULL);
 
 	return 0;
 }
@@ -978,24 +931,24 @@
 
 	serio->id.type		= i8042_direct ? SERIO_8042 : SERIO_8042_XL;
 	serio->write		= i8042_dumbkbd ? NULL : i8042_kbd_write;
-	serio->open		= i8042_open;
-	serio->close		= i8042_close;
 	serio->start		= i8042_start;
 	serio->stop		= i8042_stop;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
-	strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
+	strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
 	strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
 
 	port->serio = serio;
+	port->irq = I8042_KBD_IRQ;
 
-	return i8042_port_register(port);
+	return 0;
 }
 
-static int __devinit i8042_create_aux_port(void)
+static int __devinit i8042_create_aux_port(int idx)
 {
 	struct serio *serio;
-	struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
+	int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
+	struct i8042_port *port = &i8042_ports[port_no];
 
 	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
 	if (!serio)
@@ -1003,111 +956,191 @@
 
 	serio->id.type		= SERIO_8042;
 	serio->write		= i8042_aux_write;
-	serio->open		= i8042_open;
-	serio->close		= i8042_close;
 	serio->start		= i8042_start;
 	serio->stop		= i8042_stop;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
-	strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
-	strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+	if (idx < 0) {
+		strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
+		strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+	} else {
+		snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
+		snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1);
+	}
 
 	port->serio = serio;
+	port->mux = idx;
+	port->irq = I8042_AUX_IRQ;
 
-	return i8042_port_register(port);
+	return 0;
 }
 
-static int __devinit i8042_create_mux_port(int index)
+static void __devinit i8042_free_kbd_port(void)
 {
-	struct serio *serio;
-	struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
+	kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
+	i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
+}
 
-	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
-	if (!serio)
-		return -ENOMEM;
+static void __devinit i8042_free_aux_ports(void)
+{
+	int i;
 
-	serio->id.type		= SERIO_8042;
-	serio->write		= i8042_aux_write;
-	serio->open		= i8042_open;
-	serio->close		= i8042_close;
-	serio->start		= i8042_start;
-	serio->stop		= i8042_stop;
-	serio->port_data	= port;
-	serio->dev.parent	= &i8042_platform_device->dev;
-	snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
-	snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
+	for (i = I8042_AUX_PORT_NO; i < I8042_NUM_PORTS; i++) {
+		kfree(i8042_ports[i].serio);
+		i8042_ports[i].serio = NULL;
+	}
+}
 
-	*port = i8042_ports[I8042_AUX_PORT_NO];
-	port->exists = 0;
-	snprintf(port->name, sizeof(port->name), "AUX%d", index);
-	port->mux = index;
-	port->serio = serio;
+static void __devinit i8042_register_ports(void)
+{
+	int i;
 
-	return i8042_port_register(port);
+	for (i = 0; i < I8042_NUM_PORTS; i++) {
+		if (i8042_ports[i].serio) {
+			printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n",
+				i8042_ports[i].serio->name,
+				(unsigned long) I8042_DATA_REG,
+				(unsigned long) I8042_COMMAND_REG,
+				i8042_ports[i].irq);
+			serio_register_port(i8042_ports[i].serio);
+		}
+	}
+}
+
+static void __devinit i8042_unregister_ports(void)
+{
+	int i;
+
+	for (i = 0; i < I8042_NUM_PORTS; i++) {
+		if (i8042_ports[i].serio) {
+			serio_unregister_port(i8042_ports[i].serio);
+			i8042_ports[i].serio = NULL;
+		}
+	}
+}
+
+static void i8042_free_irqs(void)
+{
+	if (i8042_aux_irq_registered)
+		free_irq(I8042_AUX_IRQ, i8042_platform_device);
+	if (i8042_kbd_irq_registered)
+		free_irq(I8042_KBD_IRQ, i8042_platform_device);
+
+	i8042_aux_irq_registered = i8042_kbd_irq_registered = 0;
+}
+
+static int __devinit i8042_setup_aux(void)
+{
+	int (*aux_enable)(void);
+	int error;
+	int i;
+
+	if (i8042_check_aux())
+		return -ENODEV;
+
+	if (i8042_nomux || i8042_check_mux()) {
+		error = i8042_create_aux_port(-1);
+		if (error)
+			goto err_free_ports;
+		aux_enable = i8042_enable_aux_port;
+	} else {
+		for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+			error = i8042_create_aux_port(i);
+			if (error)
+				goto err_free_ports;
+		}
+		aux_enable = i8042_enable_mux_ports;
+	}
+
+	error = request_irq(I8042_AUX_IRQ, i8042_interrupt, IRQF_SHARED,
+			    "i8042", i8042_platform_device);
+	if (error)
+		goto err_free_ports;
+
+	if (aux_enable())
+		goto err_free_irq;
+
+	i8042_aux_irq_registered = 1;
+	return 0;
+
+ err_free_irq:
+	free_irq(I8042_AUX_IRQ, i8042_platform_device);
+ err_free_ports:
+	i8042_free_aux_ports();
+	return error;
+}
+
+static int __devinit i8042_setup_kbd(void)
+{
+	int error;
+
+	error = i8042_create_kbd_port();
+	if (error)
+		return error;
+
+	error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
+			    "i8042", i8042_platform_device);
+	if (error)
+		goto err_free_port;
+
+	error = i8042_enable_kbd_port();
+	if (error)
+		goto err_free_irq;
+
+	i8042_kbd_irq_registered = 1;
+	return 0;
+
+ err_free_irq:
+	free_irq(I8042_KBD_IRQ, i8042_platform_device);
+ err_free_port:
+	i8042_free_kbd_port();
+	return error;
 }
 
 static int __devinit i8042_probe(struct platform_device *dev)
 {
-	int i, have_ports = 0;
-	int err;
+	int error;
 
-	init_timer(&i8042_timer);
-	i8042_timer.function = i8042_timer_func;
+	error = i8042_controller_selftest();
+	if (error)
+		return error;
 
-	if (i8042_controller_init())
-		return -ENODEV;
+	error = i8042_controller_init();
+	if (error)
+		return error;
 
-	if (!i8042_noaux && !i8042_check_aux()) {
-		if (!i8042_nomux && !i8042_check_mux()) {
-			for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
-				err = i8042_create_mux_port(i);
-				if (err)
-					goto err_unregister_ports;
-			}
-		} else {
-			err = i8042_create_aux_port();
-			if (err)
-				goto err_unregister_ports;
-		}
-		have_ports = 1;
+	if (!i8042_noaux) {
+		error = i8042_setup_aux();
+		if (error && error != -ENODEV && error != -EBUSY)
+			goto out_fail;
 	}
 
 	if (!i8042_nokbd) {
-		err = i8042_create_kbd_port();
-		if (err)
-			goto err_unregister_ports;
-		have_ports = 1;
+		error = i8042_setup_kbd();
+		if (error)
+			goto out_fail;
 	}
 
-	if (!have_ports) {
-		err = -ENODEV;
-		goto err_controller_cleanup;
-	}
+/*
+ * Ok, everything is ready, let's register all serio ports
+ */
+	i8042_register_ports();
 
-	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 	return 0;
 
- err_unregister_ports:
-	for (i = 0; i < I8042_NUM_PORTS; i++)
-		if (i8042_ports[i].serio)
-			serio_unregister_port(i8042_ports[i].serio);
- err_controller_cleanup:
-	i8042_controller_cleanup();
+ out_fail:
+	i8042_free_aux_ports();	/* in case KBD failed but AUX not */
+	i8042_free_irqs();
+	i8042_controller_reset();
 
-	return err;
+	return error;
 }
 
 static int __devexit i8042_remove(struct platform_device *dev)
 {
-	int i;
-
-	i8042_controller_cleanup();
-
-	for (i = 0; i < I8042_NUM_PORTS; i++)
-		if (i8042_ports[i].exists)
-			serio_unregister_port(i8042_ports[i].serio);
-
-	del_timer_sync(&i8042_timer);
+	i8042_unregister_ports();
+	i8042_free_irqs();
+	i8042_controller_reset();
 
 	return 0;
 }
@@ -1134,8 +1167,9 @@
 	if (err)
 		return err;
 
-	i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
-	i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
+	err = i8042_controller_check();
+	if (err)
+		goto err_platform_exit;
 
 	err = platform_driver_register(&i8042_driver);
 	if (err)
@@ -1151,6 +1185,8 @@
 	if (err)
 		goto err_free_device;
 
+	panic_blink = i8042_panic_blink;
+
 	return 0;
 
  err_free_device:
@@ -1167,7 +1203,6 @@
 {
 	platform_device_unregister(i8042_platform_device);
 	platform_driver_unregister(&i8042_driver);
-
 	i8042_platform_exit();
 
 	panic_blink = NULL;
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index af526ab..b3eb7a7 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -37,15 +37,6 @@
 #define I8042_CTL_TIMEOUT	10000
 
 /*
- * When the device isn't opened and it's interrupts aren't used, we poll it at
- * regular intervals to see if any characters arrived. If yes, we can start
- * probing for any mouse / keyboard connected. This is the period of the
- * polling.
- */
-
-#define I8042_POLL_PERIOD	HZ/20
-
-/*
  * Status register bits.
  */
 
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index ed202f2..dcb16b5 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -27,15 +27,6 @@
 MODULE_DESCRIPTION("PS/2 driver library");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(ps2_init);
-EXPORT_SYMBOL(ps2_sendbyte);
-EXPORT_SYMBOL(ps2_drain);
-EXPORT_SYMBOL(ps2_command);
-EXPORT_SYMBOL(ps2_schedule_command);
-EXPORT_SYMBOL(ps2_handle_ack);
-EXPORT_SYMBOL(ps2_handle_response);
-EXPORT_SYMBOL(ps2_cmd_aborted);
-
 /* Work structure to schedule execution of a command */
 struct ps2work {
 	struct work_struct work;
@@ -71,6 +62,7 @@
 
 	return -ps2dev->nak;
 }
+EXPORT_SYMBOL(ps2_sendbyte);
 
 /*
  * ps2_drain() waits for device to transmit requested number of bytes
@@ -96,15 +88,16 @@
 			   msecs_to_jiffies(timeout));
 	mutex_unlock(&ps2dev->cmd_mutex);
 }
+EXPORT_SYMBOL(ps2_drain);
 
 /*
  * ps2_is_keyboard_id() checks received ID byte against the list of
  * known keyboard IDs.
  */
 
-static inline int ps2_is_keyboard_id(char id_byte)
+int ps2_is_keyboard_id(char id_byte)
 {
-	static char keyboard_ids[] = {
+	const static char keyboard_ids[] = {
 		0xab,	/* Regular keyboards		*/
 		0xac,	/* NCD Sun keyboard		*/
 		0x2b,	/* Trust keyboard, translated	*/
@@ -115,6 +108,7 @@
 
 	return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
 }
+EXPORT_SYMBOL(ps2_is_keyboard_id);
 
 /*
  * ps2_adjust_timeout() is called after receiving 1st byte of command
@@ -139,6 +133,19 @@
 
 		case PS2_CMD_GETID:
 			/*
+			 * Microsoft Natural Elite keyboard responds to
+			 * the GET ID command as it were a mouse, with
+			 * a single byte. Fail the command so atkbd will
+			 * use alternative probe to detect it.
+			 */
+			if (ps2dev->cmdbuf[1] == 0xaa) {
+				serio_pause_rx(ps2dev->serio);
+				ps2dev->flags = 0;
+				serio_continue_rx(ps2dev->serio);
+				timeout = 0;
+			}
+
+			/*
 			 * If device behind the port is not a keyboard there
 			 * won't be 2nd byte of ID response.
 			 */
@@ -237,6 +244,7 @@
 	mutex_unlock(&ps2dev->cmd_mutex);
 	return rc;
 }
+EXPORT_SYMBOL(ps2_command);
 
 /*
  * ps2_execute_scheduled_command() sends a command, previously scheduled by
@@ -279,6 +287,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(ps2_schedule_command);
 
 /*
  * ps2_init() initializes ps2dev structure
@@ -290,6 +299,7 @@
 	init_waitqueue_head(&ps2dev->wait);
 	ps2dev->serio = serio;
 }
+EXPORT_SYMBOL(ps2_init);
 
 /*
  * ps2_handle_ack() is supposed to be used in interrupt handler
@@ -335,6 +345,7 @@
 
 	return 1;
 }
+EXPORT_SYMBOL(ps2_handle_ack);
 
 /*
  * ps2_handle_response() is supposed to be used in interrupt handler
@@ -360,6 +371,7 @@
 
 	return 1;
 }
+EXPORT_SYMBOL(ps2_handle_response);
 
 void ps2_cmd_aborted(struct ps2dev *ps2dev)
 {
@@ -371,4 +383,4 @@
 
 	ps2dev->flags = 0;
 }
-
+EXPORT_SYMBOL(ps2_cmd_aborted);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index b1b14f8..9418bbe 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -108,4 +108,40 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called hp680_ts_input.
 
+config TOUCHSCREEN_PENMOUNT
+	tristate "Penmount serial touchscreen"
+	select SERIO
+	help
+	  Say Y here if you have a Penmount serial touchscreen connected to
+	  your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called penmount.
+
+config TOUCHSCREEN_TOUCHRIGHT
+	tristate "Touchright serial touchscreen"
+	select SERIO
+	help
+	  Say Y here if you have a Touchright serial touchscreen connected to
+	  your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called touchright.
+
+config TOUCHSCREEN_TOUCHWIN
+	tristate "Touchwin serial touchscreen"
+	select SERIO
+	help
+	  Say Y here if you have a Touchwin serial touchscreen connected to
+	  your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called touchwin.
+
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 5e5557c..1abb8f1 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -12,3 +12,6 @@
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)	+= mk712.o
 obj-$(CONFIG_TOUCHSCREEN_HP600)	+= hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)	+= penmount.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index c86a2eb..ab56533 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -23,6 +23,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/init.h>
+#include <linux/ctype.h>
 
 #define DRIVER_DESC	"Elo serial touchscreen driver"
 
@@ -34,7 +35,19 @@
  * Definitions & global arrays.
  */
 
-#define	ELO_MAX_LENGTH	10
+#define ELO_MAX_LENGTH		10
+
+#define ELO10_PACKET_LEN	8
+#define ELO10_TOUCH		0x03
+#define ELO10_PRESSURE		0x80
+
+#define ELO10_LEAD_BYTE		'U'
+
+#define ELO10_ID_CMD		'i'
+
+#define ELO10_TOUCH_PACKET	'T'
+#define ELO10_ACK_PACKET	'A'
+#define ELI10_ID_PACKET		'I'
 
 /*
  * Per-touchscreen data.
@@ -43,51 +56,67 @@
 struct elo {
 	struct input_dev *dev;
 	struct serio *serio;
+	struct mutex cmd_mutex;
+	struct completion cmd_done;
 	int id;
 	int idx;
+	unsigned char expected_packet;
 	unsigned char csum;
 	unsigned char data[ELO_MAX_LENGTH];
+	unsigned char response[ELO10_PACKET_LEN];
 	char phys[32];
 };
 
-static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_regs *regs)
 {
 	struct input_dev *dev = elo->dev;
 
-	elo->csum += elo->data[elo->idx] = data;
-
+	elo->data[elo->idx] = data;
 	switch (elo->idx++) {
-
 		case 0:
-			if (data != 'U') {
+			elo->csum = 0xaa;
+			if (data != ELO10_LEAD_BYTE) {
+				pr_debug("elo: unsynchronized data: 0x%02x\n", data);
 				elo->idx = 0;
-				elo->csum = 0;
-			}
-			break;
-
-		case 1:
-			if (data != 'T') {
-				elo->idx = 0;
-				elo->csum = 0;
 			}
 			break;
 
 		case 9:
-			if (elo->csum) {
+			elo->idx = 0;
+			if (data != elo->csum) {
+				pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n",
+					 data, elo->csum);
+				break;
+			}
+			if (elo->data[1] != elo->expected_packet) {
+				if (elo->data[1] != ELO10_TOUCH_PACKET)
+					pr_debug("elo: unexpected packet: 0x%02x\n",
+						 elo->data[1]);
+				break;
+			}
+			if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
 				input_regs(dev, regs);
 				input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
 				input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
-				input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
-				input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
+				if (elo->data[2] & ELO10_PRESSURE)
+					input_report_abs(dev, ABS_PRESSURE,
+							(elo->data[8] << 8) | elo->data[7]);
+				input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH);
 				input_sync(dev);
+			} else if (elo->data[1] == ELO10_ACK_PACKET) {
+				if (elo->data[2] == '0')
+					elo->expected_packet = ELO10_TOUCH_PACKET;
+				complete(&elo->cmd_done);
+			} else {
+				memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN);
+				elo->expected_packet = ELO10_ACK_PACKET;
 			}
-			elo->idx = 0;
-			elo->csum = 0;
 			break;
 	}
+	elo->csum += data;
 }
 
-static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_regs *regs)
 {
 	struct input_dev *dev = elo->dev;
 
@@ -135,7 +164,7 @@
 	}
 }
 
-static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_regs *regs)
 {
 	struct input_dev *dev = elo->dev;
 
@@ -161,7 +190,7 @@
 static irqreturn_t elo_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct elo* elo = serio_get_drvdata(serio);
+	struct elo *elo = serio_get_drvdata(serio);
 
 	switch(elo->id) {
 		case 0:
@@ -181,17 +210,81 @@
 	return IRQ_HANDLED;
 }
 
+static int elo_command_10(struct elo *elo, unsigned char *packet)
+{
+	int rc = -1;
+	int i;
+	unsigned char csum = 0xaa + ELO10_LEAD_BYTE;
+
+	mutex_lock(&elo->cmd_mutex);
+
+	serio_pause_rx(elo->serio);
+	elo->expected_packet = toupper(packet[0]);
+	init_completion(&elo->cmd_done);
+	serio_continue_rx(elo->serio);
+
+	if (serio_write(elo->serio, ELO10_LEAD_BYTE))
+		goto out;
+
+	for (i = 0; i < ELO10_PACKET_LEN; i++) {
+		csum += packet[i];
+		if (serio_write(elo->serio, packet[i]))
+			goto out;
+	}
+
+	if (serio_write(elo->serio, csum))
+		goto out;
+
+	wait_for_completion_timeout(&elo->cmd_done, HZ);
+
+	if (elo->expected_packet == ELO10_TOUCH_PACKET) {
+		/* We are back in reporting mode, the command was ACKed */
+		memcpy(packet, elo->response, ELO10_PACKET_LEN);
+		rc = 0;
+	}
+
+ out:
+	mutex_unlock(&elo->cmd_mutex);
+	return rc;
+}
+
+static int elo_setup_10(struct elo *elo)
+{
+	static const char *elo_types[] = { "Accu", "Dura", "Intelli", "Carroll" };
+	struct input_dev *dev = elo->dev;
+	unsigned char packet[ELO10_PACKET_LEN] = { ELO10_ID_CMD };
+
+	if (elo_command_10(elo, packet))
+		return -1;
+
+	dev->id.version = (packet[5] << 8) | packet[4];
+
+	input_set_abs_params(dev, ABS_X, 96, 4000, 0, 0);
+	input_set_abs_params(dev, ABS_Y, 96, 4000, 0, 0);
+	if (packet[3] & ELO10_PRESSURE)
+		input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+
+	printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, "
+		"features: %x02x, controller: 0x%02x\n",
+		elo_types[(packet[1] -'0') & 0x03],
+		packet[5], packet[4], packet[3], packet[7]);
+
+	return 0;
+}
+
 /*
  * elo_disconnect() is the opposite of elo_connect()
  */
 
 static void elo_disconnect(struct serio *serio)
 {
-	struct elo* elo = serio_get_drvdata(serio);
+	struct elo *elo = serio_get_drvdata(serio);
 
+	input_get_device(elo->dev);
 	input_unregister_device(elo->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_put_device(elo->dev);
 	kfree(elo);
 }
 
@@ -211,12 +304,15 @@
 	input_dev = input_allocate_device();
 	if (!elo || !input_dev) {
 		err = -ENOMEM;
-		goto fail;
+		goto fail1;
 	}
 
 	elo->serio = serio;
 	elo->id = serio->id.id;
 	elo->dev = input_dev;
+	elo->expected_packet = ELO10_TOUCH_PACKET;
+	mutex_init(&elo->cmd_mutex);
+	init_completion(&elo->cmd_done);
 	snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
 
 	input_dev->private = elo;
@@ -231,12 +327,17 @@
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
 
+	serio_set_drvdata(serio, elo);
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
 	switch (elo->id) {
 
 		case 0: /* 10-byte protocol */
-			input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
-			input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
-			input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
+			if (elo_setup_10(elo))
+				goto fail3;
+
 			break;
 
 		case 1: /* 6-byte protocol */
@@ -253,17 +354,15 @@
 			break;
 	}
 
-	serio_set_drvdata(serio, elo);
-
-	err = serio_open(serio, drv);
+	err = input_register_device(elo->dev);
 	if (err)
-		goto fail;
+		goto fail3;
 
-	input_register_device(elo->dev);
 	return 0;
 
- fail:	serio_set_drvdata(serio, NULL);
-	input_free_device(input_dev);
+ fail3: serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
 	kfree(elo);
 	return err;
 }
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
new file mode 100644
index 0000000..f737010
--- /dev/null
+++ b/drivers/input/touchscreen/penmount.c
@@ -0,0 +1,185 @@
+/*
+ * Penmount serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on ELO driver (drivers/input/touchscreen/elo.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC	"Penmount serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define	PM_MAX_LENGTH	5
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct pm {
+	struct input_dev *dev;
+	struct serio *serio;
+	int idx;
+	unsigned char data[PM_MAX_LENGTH];
+	char phys[32];
+};
+
+static irqreturn_t pm_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+	struct pm *pm = serio_get_drvdata(serio);
+	struct input_dev *dev = pm->dev;
+
+	pm->data[pm->idx] = data;
+
+	if (pm->data[0] & 0x80) {
+		if (PM_MAX_LENGTH == ++pm->idx) {
+			input_regs(dev, regs);
+			input_report_abs(dev, ABS_X, pm->data[2] * 128 + pm->data[1]);
+			input_report_abs(dev, ABS_Y, pm->data[4] * 128 + pm->data[3]);
+			input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+			input_sync(dev);
+			pm->idx = 0;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * pm_disconnect() is the opposite of pm_connect()
+ */
+
+static void pm_disconnect(struct serio *serio)
+{
+	struct pm *pm = serio_get_drvdata(serio);
+
+	input_get_device(pm->dev);
+	input_unregister_device(pm->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(pm->dev);
+	kfree(pm);
+}
+
+/*
+ * pm_connect() is the routine that is called when someone adds a
+ * new serio device that supports Gunze protocol and registers it as
+ * an input device.
+ */
+
+static int pm_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct pm *pm;
+	struct input_dev *input_dev;
+	int err;
+
+	pm = kzalloc(sizeof(struct pm), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!pm || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
+
+	pm->serio = serio;
+	pm->dev = input_dev;
+	snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys);
+
+	input_dev->private = pm;
+	input_dev->name = "Penmount Serial TouchScreen";
+	input_dev->phys = pm->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_PENMOUNT;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+
+        input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+        input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+        input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
+        input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
+
+	serio_set_drvdata(serio, pm);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(pm->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(pm);
+	return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id pm_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_PENMOUNT,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, pm_serio_ids);
+
+static struct serio_driver pm_drv = {
+	.driver		= {
+		.name	= "penmountlpc",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= pm_serio_ids,
+	.interrupt	= pm_interrupt,
+	.connect	= pm_connect,
+	.disconnect	= pm_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init pm_init(void)
+{
+	serio_register_driver(&pm_drv);
+	return 0;
+}
+
+static void __exit pm_exit(void)
+{
+	serio_unregister_driver(&pm_drv);
+}
+
+module_init(pm_init);
+module_exit(pm_exit);
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
new file mode 100644
index 0000000..1c89fa5
--- /dev/null
+++ b/drivers/input/touchscreen/touchright.c
@@ -0,0 +1,196 @@
+/*
+ * Touchright serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC	"Touchright serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define TR_FORMAT_TOUCH_BIT	0x01
+#define TR_FORMAT_STATUS_BYTE	0x40
+#define TR_FORMAT_STATUS_MASK	~TR_FORMAT_TOUCH_BIT
+
+#define TR_LENGTH 5
+
+#define TR_MIN_XC 0
+#define TR_MAX_XC 0x1ff
+#define TR_MIN_YC 0
+#define TR_MAX_YC 0x1ff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct tr {
+	struct input_dev *dev;
+	struct serio *serio;
+	int idx;
+	unsigned char data[TR_LENGTH];
+	char phys[32];
+};
+
+static irqreturn_t tr_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+	struct tr *tr = serio_get_drvdata(serio);
+	struct input_dev *dev = tr->dev;
+
+	tr->data[tr->idx] = data;
+
+	if ((tr->data[0] & TR_FORMAT_STATUS_MASK) == TR_FORMAT_STATUS_BYTE) {
+		if (++tr->idx == TR_LENGTH) {
+			input_regs(dev, regs);
+			input_report_abs(dev, ABS_X,
+				(tr->data[1] << 5) | (tr->data[2] >> 1));
+			input_report_abs(dev, ABS_Y,
+				(tr->data[3] << 5) | (tr->data[4] >> 1));
+			input_report_key(dev, BTN_TOUCH,
+				tr->data[0] & TR_FORMAT_TOUCH_BIT);
+			input_sync(dev);
+			tr->idx = 0;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * tr_disconnect() is the opposite of tr_connect()
+ */
+
+static void tr_disconnect(struct serio *serio)
+{
+	struct tr *tr = serio_get_drvdata(serio);
+
+	input_get_device(tr->dev);
+	input_unregister_device(tr->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(tr->dev);
+	kfree(tr);
+}
+
+/*
+ * tr_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchright protocol and registers it as
+ * an input device.
+ */
+
+static int tr_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct tr *tr;
+	struct input_dev *input_dev;
+	int err;
+
+	tr = kzalloc(sizeof(struct tr), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!tr || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
+
+	tr->serio = serio;
+	tr->dev = input_dev;
+	snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys);
+
+	input_dev->private = tr;
+	input_dev->name = "Touchright Serial TouchScreen";
+	input_dev->phys = tr->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_TOUCHRIGHT;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0100;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0);
+	input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0);
+
+	serio_set_drvdata(serio, tr);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(tr->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(tr);
+	return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id tr_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_TOUCHRIGHT,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, tr_serio_ids);
+
+static struct serio_driver tr_drv = {
+	.driver		= {
+		.name	= "touchright",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= tr_serio_ids,
+	.interrupt	= tr_interrupt,
+	.connect	= tr_connect,
+	.disconnect	= tr_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init tr_init(void)
+{
+	serio_register_driver(&tr_drv);
+	return 0;
+}
+
+static void __exit tr_exit(void)
+{
+	serio_unregister_driver(&tr_drv);
+}
+
+module_init(tr_init);
+module_exit(tr_exit);
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
new file mode 100644
index 0000000..a7b4c75
--- /dev/null
+++ b/drivers/input/touchscreen/touchwin.c
@@ -0,0 +1,203 @@
+/*
+ * Touchwindow serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+/*
+ * 2005/02/19 Rick Koch:
+ *   The Touchwindow I used is made by Edmark Corp. and
+ *   constantly outputs a stream of 0's unless it is touched.
+ *   It then outputs 3 bytes: X, Y, and a copy of Y.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC	"Touchwindow serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define TW_LENGTH 3
+
+#define TW_MIN_XC 0
+#define TW_MAX_XC 0xff
+#define TW_MIN_YC 0
+#define TW_MAX_YC 0xff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct tw {
+	struct input_dev *dev;
+	struct serio *serio;
+	int idx;
+	int touched;
+	unsigned char data[TW_LENGTH];
+	char phys[32];
+};
+
+static irqreturn_t tw_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+	struct tw *tw = serio_get_drvdata(serio);
+	struct input_dev *dev = tw->dev;
+
+	if (data) {		/* touch */
+		tw->touched = 1;
+		tw->data[tw->idx++] = data;
+		/* verify length and that the two Y's are the same */
+		if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) {
+			input_regs(dev, regs);
+			input_report_abs(dev, ABS_X, tw->data[0]);
+			input_report_abs(dev, ABS_Y, tw->data[1]);
+			input_report_key(dev, BTN_TOUCH, 1);
+			input_sync(dev);
+			tw->idx = 0;
+		}
+	} else if (tw->touched) {	/* untouch */
+		input_report_key(dev, BTN_TOUCH, 0);
+		input_sync(dev);
+		tw->idx = 0;
+		tw->touched = 0;
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * tw_disconnect() is the opposite of tw_connect()
+ */
+
+static void tw_disconnect(struct serio *serio)
+{
+	struct tw *tw = serio_get_drvdata(serio);
+
+	input_get_device(tw->dev);
+	input_unregister_device(tw->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(tw->dev);
+	kfree(tw);
+}
+
+/*
+ * tw_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchwin protocol and registers it as
+ * an input device.
+ */
+
+static int tw_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct tw *tw;
+	struct input_dev *input_dev;
+	int err;
+
+	tw = kzalloc(sizeof(struct tw), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!tw || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
+
+	tw->serio = serio;
+	tw->dev = input_dev;
+	snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys);
+
+	input_dev->private = tw;
+	input_dev->name = "Touchwindow Serial TouchScreen";
+	input_dev->phys = tw->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_TOUCHWIN;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0100;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
+	input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);
+
+	serio_set_drvdata(serio, tw);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(tw->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(tw);
+	return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id tw_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_TOUCHWIN,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, tw_serio_ids);
+
+static struct serio_driver tw_drv = {
+	.driver		= {
+		.name	= "touchwin",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= tw_serio_ids,
+	.interrupt	= tw_interrupt,
+	.connect	= tw_connect,
+	.disconnect	= tw_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init tw_init(void)
+{
+	serio_register_driver(&tw_drv);
+	return 0;
+}
+
+static void __exit tw_exit(void)
+{
+	serio_unregister_driver(&tw_drv);
+}
+
+module_init(tw_init);
+module_exit(tw_exit);
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 00e3929..a730c46 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -135,8 +135,6 @@
 #define TS_GET_CAL	_IOR(IOC_H3600_TS_MAGIC, 10, struct ts_calibration)
 #define TS_SET_CAL	_IOW(IOC_H3600_TS_MAGIC, 11, struct ts_calibration)
 
-static struct input_handler tsdev_handler;
-
 static struct tsdev *tsdev_table[TSDEV_MINORS/2];
 
 static int tsdev_fasync(int fd, struct file *file, int on)
@@ -263,7 +261,7 @@
 	return retval;
 }
 
-static struct file_operations tsdev_fops = {
+static const struct file_operations tsdev_fops = {
 	.owner =	THIS_MODULE,
 	.open =		tsdev_open,
 	.release =	tsdev_release,
@@ -370,7 +368,7 @@
 
 static struct input_handle *tsdev_connect(struct input_handler *handler,
 					  struct input_dev *dev,
-					  struct input_device_id *id)
+					  const struct input_device_id *id)
 {
 	struct tsdev *tsdev;
 	struct class_device *cdev;
@@ -443,7 +441,7 @@
 		tsdev_free(tsdev);
 }
 
-static struct input_device_id tsdev_ids[] = {
+static const struct input_device_id tsdev_ids[] = {
 	{
 	      .flags	= INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
 	      .evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
@@ -481,9 +479,7 @@
 
 static int __init tsdev_init(void)
 {
-	input_register_handler(&tsdev_handler);
-	printk(KERN_INFO "ts: Compaq touchscreen protocol output\n");
-	return 0;
+	return input_register_handler(&tsdev_handler);
 }
 
 static void __exit tsdev_exit(void)
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 669f763..11844bb 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1298,7 +1298,7 @@
 
 static struct tty_driver *capinc_tty_driver;
 
-static struct tty_operations capinc_ops = {
+static const struct tty_operations capinc_ops = {
 	.open = capinc_tty_open,
 	.close = capinc_tty_close,
 	.write = capinc_tty_write,
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index bd2e426..596f3ae 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -134,7 +134,7 @@
 static int  if_write(struct tty_struct *tty,
 		     const unsigned char *buf, int count);
 
-static struct tty_operations if_ops = {
+static const struct tty_operations if_ops = {
 	.open =			if_open,
 	.close =		if_close,
 	.ioctl =		if_ioctl,
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index 9ae3a7f..9ad840e 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -83,5 +83,6 @@
 		return;
 
 	gig_dbg(DEBUG_INIT, "setting up sysfs");
-	class_device_create_file(cs->class, &class_device_attr_cidmode);
+	if (class_device_create_file(cs->class, &class_device_attr_cidmode))
+		dev_err(cs->dev, "could not create sysfs attribute\n");
 }
diff --git a/drivers/isdn/hardware/eicon/Kconfig b/drivers/isdn/hardware/eicon/Kconfig
index 51e66bc..01d4afd 100644
--- a/drivers/isdn/hardware/eicon/Kconfig
+++ b/drivers/isdn/hardware/eicon/Kconfig
@@ -47,7 +47,7 @@
 	tristate "DIVA Maint driver support"
 	depends on ISDN_DIVAS && m
 	help
-	  Enable Divas Maintainance driver.
+	  Enable Divas Maintenance driver.
 
 endmenu
 
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 6dfc941..eb57a98 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -321,7 +321,7 @@
 	help
 	  This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
-	  For more informations see under
+	  For more information see under
 	  <file:Documentation/isdn/README.hfc-pci>.
 
 config HISAX_W6692
diff --git a/drivers/isdn/hisax/amd7930_fn.h b/drivers/isdn/hisax/amd7930_fn.h
index e039c3a..1f4d80c 100644
--- a/drivers/isdn/hisax/amd7930_fn.h
+++ b/drivers/isdn/hisax/amd7930_fn.h
@@ -1,4 +1,4 @@
-/* 2001/10/02
+/* drivers/isdn/hisax/amd7930_fn.h
  *
  * gerdes_amd7930.h     Header-file included by
  *                      gerdes_amd7930.c
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index e103503..e4823ab2 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1721,11 +1721,11 @@
 		hisax_b_sched_event(bcs, B_RCVBUFREADY);
 		break;
 	case PH_DATA | CONFIRM:
-		bcs->tx_cnt -= (int) arg;
+		bcs->tx_cnt -= (long)arg;
 		if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag)) {
 			u_long	flags;
 			spin_lock_irqsave(&bcs->aclock, flags);
-			bcs->ackcnt += (int) arg;
+			bcs->ackcnt += (long)arg;
 			spin_unlock_irqrestore(&bcs->aclock, flags);
 			schedule_event(bcs, B_ACKPENDING);
 		}
@@ -1789,7 +1789,7 @@
 
 	switch (pr) {
 	case PH_ACTIVATE | REQUEST:
-		B_L2L1(b_if, pr, (void *) st->l1.mode);
+		B_L2L1(b_if, pr, (void *)(unsigned long)st->l1.mode);
 		break;
 	case PH_DATA | REQUEST:
 	case PH_PULL | INDICATION:
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 3a5ca8a..0ca5e66 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -424,7 +424,7 @@
 	struct hfc4s8s_btype *bch = ifc->priv;
 	struct hfc4s8s_l1 *l1 = bch->l1p;
 	struct sk_buff *skb = (struct sk_buff *) arg;
-	int mode = (int) arg;
+	long mode = (long) arg;
 	u_long flags;
 
 	switch (pr) {
@@ -914,7 +914,7 @@
 	struct sk_buff *skb;
 	u_char f1, f2;
 	u_char *cp;
-	int cnt;
+	long cnt;
 
 	if (l1p->l1_state != 7)
 		return;
@@ -980,7 +980,8 @@
 	struct sk_buff *skb;
 	struct hfc4s8s_l1 *l1 = bch->l1p;
 	u_char *cp;
-	int cnt, max, hdlc_num, ack_len = 0;
+	int cnt, max, hdlc_num;
+	long ack_len = 0;
 
 	if (!l1->enabled || (bch->mode == L1_MODE_NULL))
 		return;
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index f27c160..b7e8e23 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -970,7 +970,7 @@
 			break;
 		case (HW_TESTLOOP | REQUEST):
 			spin_lock_irqsave(&cs->lock, flags);
-			switch ((int) arg) {
+			switch ((long) arg) {
 				case (1):
 					Write_hfc(cs, HFCSX_B1_SSL, 0x80);	/* tx slot */
 					Write_hfc(cs, HFCSX_B1_RSL, 0x80);	/* rx slot */
@@ -986,7 +986,7 @@
 				default:
 					spin_unlock_irqrestore(&cs->lock, flags);
 					if (cs->debug & L1_DEB_WARN)
-						debugl1(cs, "hfcsx_l1hw loop invalid %4x", (int) arg);
+						debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg);
 					return;
 			}
 			cs->hw.hfcsx.trm |= 0x80;	/* enable IOM-loop */
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index b5e571a..6b88ecb 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -696,7 +696,7 @@
 				fifo->delete_flg = TRUE;
 				fifo->hif->l1l2(fifo->hif,
 						PH_DATA | CONFIRM,
-						(void *) fifo->skbuff->
+						(void *) (unsigned long) fifo->skbuff->
 						truesize);
 				if (fifo->skbuff && fifo->delete_flg) {
 					dev_kfree_skb_any(fifo->skbuff);
@@ -1144,7 +1144,7 @@
 				set_hfcmode(hfc,
 					    (fifo->fifonum ==
 					     HFCUSB_B1_TX) ? 0 : 1,
-					    (int) arg);
+					    (long) arg);
 				fifo->hif->l1l2(fifo->hif,
 						PH_ACTIVATE | INDICATION,
 						NULL);
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 75920aa..2f9d511 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1316,7 +1316,18 @@
 void iecpy(u_char * dest, u_char * iestart, int ieoffset);
 #endif	/* __KERNEL__ */
 
-#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
+/*
+ * Busywait delay for `jiffs' jiffies
+ */
+#define HZDELAY(jiffs) do {					\
+		int tout = jiffs;				\
+								\
+		while (tout--) {				\
+			int loops = USEC_PER_SEC / HZ;		\
+			while (loops--)				\
+				udelay(1);			\
+		}						\
+	} while (0)
 
 int ll_run(struct IsdnCardState *cs, int addfeatures);
 int CallcNew(void);
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 1d7cf3b..881a416 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -546,7 +546,7 @@
 	}
 	bcs->tx_cnt = 0;
 	bcs->tx_skb = NULL;
-	B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
+	B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long)skb->truesize);
 	dev_kfree_skb_irq(skb);
 }
 
@@ -635,7 +635,7 @@
 		hdlc_fill_fifo(bcs);
 		break;
 	case PH_ACTIVATE | REQUEST:
-		mode = (int) arg;
+		mode = (long) arg;
 		DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
 		modehdlc(bcs, mode);
 		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
@@ -998,18 +998,15 @@
 
 	retval = pci_register_driver(&fcpci_driver);
 	if (retval)
-		goto out;
+		return retval;
 #ifdef __ISAPNP__
 	retval = pnp_register_driver(&fcpnp_driver);
-	if (retval < 0)
-		goto out_unregister_pci;
+	if (retval < 0) {
+		pci_unregister_driver(&fcpci_driver);
+		return retval;
+	}
 #endif
 	return 0;
-
- out_unregister_pci:
-	pci_unregister_driver(&fcpci_driver);
- out:
-	return retval;
 }
 
 static void __exit hisax_fcpcipnp_exit(void)
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c
index 489022b..0945336 100644
--- a/drivers/isdn/hisax/niccy.c
+++ b/drivers/isdn/hisax/niccy.c
@@ -13,7 +13,6 @@
  *
  */
 
-
 #include <linux/init.h>
 #include "hisax.h"
 #include "isac.h"
@@ -45,33 +44,31 @@
 #define PCI_IRQ_DISABLE		0xff0000
 #define PCI_IRQ_ASSERT		0x800000
 
-static inline u_char
-readreg(unsigned int ale, unsigned int adr, u_char off)
+static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off)
 {
 	register u_char ret;
 
 	byteout(ale, off);
 	ret = bytein(adr);
-	return (ret);
+	return ret;
 }
 
-static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+static inline void readfifo(unsigned int ale, unsigned int adr, u_char off,
+		u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
 }
 
-
-static inline void
-writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
+static inline void writereg(unsigned int ale, unsigned int adr, u_char off,
+		u_char data)
 {
 	byteout(ale, off);
 	byteout(adr, data);
 }
 
-static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+static inline void writefifo(unsigned int ale, unsigned int adr, u_char off,
+		u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -79,39 +76,34 @@
 
 /* Interface functions */
 
-static u_char
-ReadISAC(struct IsdnCardState *cs, u_char offset)
+static u_char ReadISAC(struct IsdnCardState *cs, u_char offset)
 {
-	return (readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset));
+	return readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset);
 }
 
-static void
-WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
+static void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
 	writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset, value);
 }
 
-static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+static void ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 {
 	readfifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
 }
 
-static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+static void WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 {
 	writefifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
 }
 
-static u_char
-ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
+static u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
-	return (readreg(cs->hw.niccy.hscx_ale,
-			cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0)));
+	return readreg(cs->hw.niccy.hscx_ale,
+			cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0));
 }
 
-static void
-WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
+static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset,
+		u_char value)
 {
 	writereg(cs->hw.niccy.hscx_ale,
 		 cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0), value);
@@ -130,8 +122,8 @@
 
 #include "hscx_irq.c"
 
-static irqreturn_t
-niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+static irqreturn_t niccy_interrupt(int intno, void *dev_id,
+		struct pt_regs *regs)
 {
 	struct IsdnCardState *cs = dev_id;
 	u_char val;
@@ -141,21 +133,23 @@
 	if (cs->subtyp == NICCY_PCI) {
 		int ival;
 		ival = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
-		if (!(ival & PCI_IRQ_ASSERT)) { /* IRQ not for us (shared) */
+		if (!(ival & PCI_IRQ_ASSERT)) {	/* IRQ not for us (shared) */
 			spin_unlock_irqrestore(&cs->lock, flags);
 			return IRQ_NONE;
 		}
 		outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
 	}
-	val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+	val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx,
+			HSCX_ISTA + 0x40);
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
-	val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40);
+	val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx,
+			HSCX_ISTA + 0x40);
 	if (val) {
 		if (cs->debug & L1_DEB_HSCX)
 			debugl1(cs, "HSCX IntStat after IntRoutine");
@@ -168,21 +162,21 @@
 		goto Start_ISAC;
 	}
 	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF);
-	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0xFF);
+	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40,
+		 0xFF);
 	writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF);
 	writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0);
 	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0);
-	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0);
+	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40,0);
 	spin_unlock_irqrestore(&cs->lock, flags);
 	return IRQ_HANDLED;
 }
 
-static void
-release_io_niccy(struct IsdnCardState *cs)
+static void release_io_niccy(struct IsdnCardState *cs)
 {
 	if (cs->subtyp == NICCY_PCI) {
 		int val;
-		
+
 		val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
 		val &= PCI_IRQ_DISABLE;
 		outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
@@ -194,8 +188,7 @@
 	}
 }
 
-static void
-niccy_reset(struct IsdnCardState *cs)
+static void niccy_reset(struct IsdnCardState *cs)
 {
 	if (cs->subtyp == NICCY_PCI) {
 		int val;
@@ -207,29 +200,28 @@
 	inithscxisac(cs, 3);
 }
 
-static int
-niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg)
+static int niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			niccy_reset(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_niccy(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			niccy_reset(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		niccy_reset(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return 0;
+	case CARD_RELEASE:
+		release_io_niccy(cs);
+		return 0;
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		niccy_reset(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return 0;
+	case CARD_TEST:
+		return 0;
 	}
-	return(0);
+	return 0;
 }
 
 static struct pci_dev *niccy_dev __devinitdata = NULL;
@@ -237,8 +229,7 @@
 static struct pnp_card *pnp_c __devinitdata = NULL;
 #endif
 
-int __devinit
-setup_niccy(struct IsdnCard *card)
+int __devinit setup_niccy(struct IsdnCard *card)
 {
 	struct IsdnCardState *cs = card->cs;
 	char tmp[64];
@@ -246,40 +237,44 @@
 	strcpy(tmp, niccy_revision);
 	printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_NICCY)
-		return (0);
+		return 0;
 #ifdef __ISAPNP__
 	if (!card->para[1] && isapnp_present()) {
 		struct pnp_dev *pnp_d = NULL;
 		int err;
 
-		if ((pnp_c = pnp_find_card(
-			ISAPNP_VENDOR('S', 'D', 'A'),
-			ISAPNP_FUNCTION(0x0150), pnp_c))) {
-			if (!(pnp_d = pnp_find_dev(pnp_c,
-				ISAPNP_VENDOR('S', 'D', 'A'),
-				ISAPNP_FUNCTION(0x0150), pnp_d))) {
-				printk(KERN_ERR "NiccyPnP: PnP error card found, no device\n");
-				return (0);
+		pnp_c = pnp_find_card(ISAPNP_VENDOR('S', 'D', 'A'),
+				ISAPNP_FUNCTION(0x0150), pnp_c);
+		if (pnp_c) {
+			pnp_d = pnp_find_dev(pnp_c,
+					ISAPNP_VENDOR('S', 'D', 'A'),
+					ISAPNP_FUNCTION(0x0150), pnp_d);
+			if (!pnp_d) {
+				printk(KERN_ERR "NiccyPnP: PnP error card "
+					"found, no device\n");
+				return 0;
 			}
 			pnp_disable_dev(pnp_d);
 			err = pnp_activate_dev(pnp_d);
-			if (err<0) {
-				printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-					__FUNCTION__, err);
-				return(0);
+			if (err < 0) {
+				printk(KERN_WARNING "%s: pnp_activate_dev "
+					"ret(%d)\n", __FUNCTION__, err);
+				return 0;
 			}
 			card->para[1] = pnp_port_start(pnp_d, 0);
 			card->para[2] = pnp_port_start(pnp_d, 1);
 			card->para[0] = pnp_irq(pnp_d, 0);
-			if (!card->para[0] || !card->para[1] || !card->para[2]) {
-				printk(KERN_ERR "NiccyPnP:some resources are missing %ld/%lx/%lx\n",
-					card->para[0], card->para[1], card->para[2]);
+			if (!card->para[0] || !card->para[1] ||
+					!card->para[2]) {
+				printk(KERN_ERR "NiccyPnP:some resources are "
+					"missing %ld/%lx/%lx\n",
+					card->para[0], card->para[1],
+					card->para[2]);
 				pnp_disable_dev(pnp_d);
-				return(0);
+				return 0;
 			}
-		} else {
+		} else
 			printk(KERN_INFO "NiccyPnP: no ISAPnP card found\n");
-		}
 	}
 #endif
 	if (card->para[1]) {
@@ -291,50 +286,51 @@
 		cs->subtyp = NICCY_PNP;
 		cs->irq = card->para[0];
 		if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) {
-			printk(KERN_WARNING
-				"HiSax: %s data port %x-%x already in use\n",
-				CardType[card->typ],
-				cs->hw.niccy.isac,
-				cs->hw.niccy.isac + 1);
-			return (0);
+			printk(KERN_WARNING "HiSax: %s data port %x-%x "
+				"already in use\n", CardType[card->typ],
+				cs->hw.niccy.isac, cs->hw.niccy.isac + 1);
+			return 0;
 		}
 		if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) {
-			printk(KERN_WARNING
-				"HiSax: %s address port %x-%x already in use\n",
-				CardType[card->typ],
+			printk(KERN_WARNING "HiSax: %s address port %x-%x "
+				"already in use\n", CardType[card->typ],
 				cs->hw.niccy.isac_ale,
 				cs->hw.niccy.isac_ale + 1);
 			release_region(cs->hw.niccy.isac, 2);
-			return (0);
+			return 0;
 		}
 	} else {
 #ifdef CONFIG_PCI
 		u_int pci_ioaddr;
 		cs->subtyp = 0;
 		if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM,
-			PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) {
+						 PCI_DEVICE_ID_SATSAGEM_NICCY,
+						 niccy_dev))) {
 			if (pci_enable_device(niccy_dev))
-				return(0);
+				return 0;
 			/* get IRQ */
 			if (!niccy_dev->irq) {
-				printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n");
-				return(0);
+				printk(KERN_WARNING
+				       "Niccy: No IRQ for PCI card found\n");
+				return 0;
 			}
 			cs->irq = niccy_dev->irq;
 			cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0);
 			if (!cs->hw.niccy.cfg_reg) {
-				printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n");
-				return(0);
+				printk(KERN_WARNING
+				       "Niccy: No IO-Adr for PCI cfg found\n");
+				return 0;
 			}
 			pci_ioaddr = pci_resource_start(niccy_dev, 1);
 			if (!pci_ioaddr) {
-				printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n");
-				return(0);
+				printk(KERN_WARNING
+				       "Niccy: No IO-Adr for PCI card found\n");
+				return 0;
 			}
 			cs->subtyp = NICCY_PCI;
 		} else {
 			printk(KERN_WARNING "Niccy: No PCI card found\n");
-			return(0);
+			return 0;
 		}
 		cs->irq_flags |= IRQF_SHARED;
 		cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA;
@@ -343,29 +339,28 @@
 		cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR;
 		if (!request_region(cs->hw.niccy.isac, 4, "niccy")) {
 			printk(KERN_WARNING
-				"HiSax: %s data port %x-%x already in use\n",
-				CardType[card->typ],
-				cs->hw.niccy.isac,
-				cs->hw.niccy.isac + 4);
-			return (0);
+			       "HiSax: %s data port %x-%x already in use\n",
+			       CardType[card->typ],
+			       cs->hw.niccy.isac, cs->hw.niccy.isac + 4);
+			return 0;
 		}
 		if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) {
 			printk(KERN_WARNING
 			       "HiSax: %s pci port %x-%x already in use\n",
-				CardType[card->typ],
-				cs->hw.niccy.cfg_reg,
-				cs->hw.niccy.cfg_reg + 0x40);
+			       CardType[card->typ],
+			       cs->hw.niccy.cfg_reg,
+			       cs->hw.niccy.cfg_reg + 0x40);
 			release_region(cs->hw.niccy.isac, 4);
-			return (0);
+			return 0;
 		}
 #else
 		printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
 		printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
-		return (0);
-#endif /* CONFIG_PCI */
+		return 0;
+#endif				/* CONFIG_PCI */
 	}
 	printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n",
-		CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI",
+		CardType[cs->typ], (cs->subtyp == 1) ? "PnP" : "PCI",
 		cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
@@ -379,10 +374,10 @@
 	cs->irq_func = &niccy_interrupt;
 	ISACVersion(cs, "Niccy:");
 	if (HscxVersion(cs, "Niccy:")) {
-		printk(KERN_WARNING
-		    "Niccy: wrong HSCX versions check IO address\n");
+		printk(KERN_WARNING "Niccy: wrong HSCX versions check IO "
+			"address\n");
 		release_io_niccy(cs);
-		return (0);
+		return 0;
 	}
-	return (1);
+	return 1;
 }
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 22fd5db..aca2a39 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -86,7 +86,7 @@
 			if (!skb->len) {
 				// Frame sent
 				b_out->tx_skb = NULL;
-				B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
+				B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long) skb->truesize);
 				dev_kfree_skb_any(skb);
 
 /* 				if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
@@ -350,7 +350,7 @@
 {
 	struct st5481_bcs *bcs = ifc->priv;
 	struct sk_buff *skb = arg;
-	int mode;
+	long mode;
 
 	DBG(4, "");
 
@@ -360,8 +360,8 @@
 		bcs->b_out.tx_skb = skb;
 		break;
 	case PH_ACTIVATE | REQUEST:
-		mode = (int) arg;
-		DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
+		mode = (long) arg;
+		DBG(4,"B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode);
 		st5481B_mode(bcs, mode);
 		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
 		break;
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 493dc94..98adec4 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -374,7 +374,7 @@
 {
 	struct st5481_adapter *adapter = urb->context;
 	struct st5481_d_out *d_out = &adapter->d_out;
-	int buf_nr;
+	long buf_nr;
 	
 	DBG(2, "");
 
@@ -546,7 +546,7 @@
 static void dout_complete(struct FsmInst *fsm, int event, void *arg)
 {
 	struct st5481_adapter *adapter = fsm->userdata;
-	int buf_nr = (int) arg;
+	long buf_nr = (long) arg;
 
 	usb_d_out(adapter, buf_nr);
 }
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 9ab66e8..2b91bb0 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1860,7 +1860,7 @@
 		send_sig(SIGIO, dev->profd, 1);
 }
 
-static struct tty_operations modem_ops = {
+static const struct tty_operations modem_ops = {
         .open = isdn_tty_open,
 	.close = isdn_tty_close,
 	.write = isdn_tty_write,
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index b4b2433..04b8a58 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -103,9 +103,6 @@
 		return -ENODEV;
 	}
 
-	pr_debug("%s: Received %s command from Link Layer\n",
-		sc_adapter[card]->devicename, commands[cmd->command]);
-
 	/*
 	 * Dispatch the command
 	 */
@@ -118,7 +115,7 @@
 		memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long));
 		if (copy_from_user(&ioc, (scs_ioctl __user *)cmdptr,
 				   sizeof(scs_ioctl))) {
-			pr_debug("%s: Failed to verify user space 0x%x\n",
+			pr_debug("%s: Failed to verify user space 0x%lx\n",
 				sc_adapter[card]->devicename, cmdptr);
 			return -EFAULT;
 		}
@@ -195,7 +192,7 @@
 				strlen(Phone),
 				(unsigned int *) Phone);
 
-	pr_debug("%s: Dialing %s on channel %d\n",
+	pr_debug("%s: Dialing %s on channel %lu\n",
 		sc_adapter[card]->devicename, Phone, channel+1);
 	
 	return status;
@@ -217,7 +214,7 @@
 	}
 
 	indicate_status(card, ISDN_STAT_BCONN,channel,NULL);
-	pr_debug("%s: Answered incoming call on channel %s\n",
+	pr_debug("%s: Answered incoming call on channel %lu\n",
 		sc_adapter[card]->devicename, channel+1);
 	return 0;
 }
@@ -240,7 +237,7 @@
 						 (unsigned char) channel+1,
 						 0,
 						 NULL);
-	pr_debug("%s: Sent HANGUP message to channel %d\n",
+	pr_debug("%s: Sent HANGUP message to channel %lu\n",
 		sc_adapter[card]->devicename, channel+1);
 	return status;
 }
@@ -260,9 +257,6 @@
 	protocol = arg >> 8;
 	channel = arg & 0xff;
 	sc_adapter[card]->channel[channel].l2_proto = protocol;
-	pr_debug("%s: Level 2 protocol for channel %d set to %s from %d\n",
-		sc_adapter[card]->devicename, channel+1,
-		l2protos[sc_adapter[card]->channel[channel].l2_proto],protocol);
 
 	/*
 	 * check that the adapter is also set to the correct protocol
@@ -293,8 +287,6 @@
 	}
 
 	sc_adapter[card]->channel[channel].l3_proto = protocol;
-	pr_debug("%s: Level 3 protocol for channel %d set to %s\n",
-		sc_adapter[card]->devicename, channel+1, l3protos[protocol]);
 	return 0;
 }
 
@@ -311,7 +303,7 @@
 		return -ENOBUFS;
 	}
 
-	pr_debug("%s: B-Channel connection accepted on channel %d\n",
+	pr_debug("%s: B-Channel connection accepted on channel %lu\n",
 		sc_adapter[card]->devicename, channel+1);
 	indicate_status(card, ISDN_STAT_BCONN, channel, NULL);
 	return 0;
@@ -326,7 +318,7 @@
 
 	strcpy(sc_adapter[card]->channel[arg].eazlist, "");
 	sc_adapter[card]->channel[arg].eazclear = 1;
-	pr_debug("%s: EAZ List cleared for channel %d\n",
+	pr_debug("%s: EAZ List cleared for channel %lu\n",
 		sc_adapter[card]->devicename, arg+1);
 	return 0;
 }
@@ -340,7 +332,7 @@
 
 	strcpy(sc_adapter[card]->channel[arg].eazlist, num);
 	sc_adapter[card]->channel[arg].eazclear = 0;
-	pr_debug("%s: EAZ list for channel %d set to: %s\n",
+	pr_debug("%s: EAZ list for channel %lu set to: %s\n",
 		sc_adapter[card]->devicename, arg+1,
 		sc_adapter[card]->channel[arg].eazlist);
 	return 0;
diff --git a/drivers/isdn/sc/event.c b/drivers/isdn/sc/event.c
index 5b8c7c1..5736732 100644
--- a/drivers/isdn/sc/event.c
+++ b/drivers/isdn/sc/event.c
@@ -45,8 +45,10 @@
 {
 	isdn_ctrl cmd;
 
+#ifdef DEBUG
 	pr_debug("%s: Indicating event %s on Channel %d\n",
 		sc_adapter[card]->devicename, events[event-256], Channel);
+#endif
 	if (Data != NULL){
 		pr_debug("%s: Event data: %s\n", sc_adapter[card]->devicename,
 			Data);
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c
index 8631d33..ae62631 100644
--- a/drivers/isdn/sc/interrupt.c
+++ b/drivers/isdn/sc/interrupt.c
@@ -91,7 +91,7 @@
 		 */
 		if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Read))
 		{
-			pr_debug("%s: Received packet 0x%x bytes long at 0x%x\n",
+			pr_debug("%s: Received packet 0x%x bytes long at 0x%lx\n",
 						sc_adapter[card]->devicename,
 						rcvmsg.msg_data.response.msg_len,
 						rcvmsg.msg_data.response.buff_offset);
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c
index aced19a..f43282b 100644
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -76,7 +76,7 @@
 		if (sc_adapter[card]->StartOnReset)
 			startproc(card);
 	} else  {
-		pr_debug("%s: No signature yet, waiting another %d jiffies.\n", 
+		pr_debug("%s: No signature yet, waiting another %lu jiffies.\n",
 			sc_adapter[card]->devicename, CHECKRESET_TIME);
 		mod_timer(&sc_adapter[card]->reset_timer, jiffies+CHECKRESET_TIME);
 		spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index d424b44..aecbbe2 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -125,7 +125,7 @@
 
 /**
  * led_classdev_unregister - unregisters a object of led_properties class.
- * @led_cdev: the led device to unreigister
+ * @led_cdev: the led device to unregister
  *
  * Unregisters a previously registered via led_classdev_register object.
  */
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 3b87951..6f2d449 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/leds/locomo.c
+ * linux/drivers/leds/leds-locomo.c
  *
  * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
  *
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index d5d649f..7f8477d 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -186,7 +186,7 @@
 	depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64
 	help
 	  This driver provides some thermostat and fan control for the
-          iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty
+          iBook G4, and the ATI based aluminium PowerBooks, allowing slightly
 	  better fan behaviour by default, and some manual control.
 
 config THERM_PM72
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index efd51e0..b7fb367 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -1,5 +1,5 @@
 /*
- * drivers/input/adbhid.c
+ * drivers/macintosh/adbhid.c
  *
  * ADB HID driver for Power Macintosh computers.
  *
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 80b8964..4f04fd0 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -336,8 +336,10 @@
 			if (gaddr != OF_BAD_ADDR)
 				gpio_reg = ioremap(gaddr, 0x10);
 		}
-		if (gpio_reg == NULL)
+		if (gpio_reg == NULL) {
 			printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n");
+			goto fail_gpio;
+		}
 	} else
 		pmu_kind = PMU_UNKNOWN;
 
@@ -365,6 +367,9 @@
 	return 1;
  fail:
 	of_node_put(vias);
+	iounmap(gpio_reg);
+	gpio_reg = NULL;
+ fail_gpio:
 	vias = NULL;
 	return 0;
 }
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 6dd31a2..c92c152 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -138,16 +138,16 @@
 	  If unsure, say Y.
 
 config MD_RAID5_RESHAPE
-	bool "Support adding drives to a raid-5 array (experimental)"
-	depends on MD_RAID456 && EXPERIMENTAL
+	bool "Support adding drives to a raid-5 array"
+	depends on MD_RAID456
+	default y
 	---help---
 	  A RAID-5 set can be expanded by adding extra drives. This
 	  requires "restriping" the array which means (almost) every
 	  block must be written to a different place.
 
           This option allows such restriping to be done while the array
-	  is online.  However it is still EXPERIMENTAL code.  It should
-	  work, but please be sure that you have backups.
+	  is online.
 
 	  You will need mdadm version 2.4.1 or later to use this
 	  feature safely.  During the early stage of reshape there is
@@ -164,6 +164,8 @@
 	  There should be enough spares already present to make the new
 	  array workable.
 
+	  If unsure, say Y.
+
 config MD_MULTIPATH
 	tristate "Multipath I/O support"
 	depends on BLK_DEV_MD
@@ -201,6 +203,14 @@
 
 	  If unsure, say N.
 
+config DM_DEBUG
+	boolean "Device mapper debugging support"
+	depends on BLK_DEV_DM && EXPERIMENTAL
+	---help---
+	  Enable this for messages that may help debug device-mapper problems.
+
+	  If unsure, say N.
+
 config DM_CRYPT
 	tristate "Crypt target support"
 	depends on BLK_DEV_DM && EXPERIMENTAL
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index ecc5676..8e67634 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -613,6 +613,7 @@
 static inline struct page *filemap_get_page(struct bitmap *bitmap,
 					unsigned long chunk)
 {
+	if (file_page_index(chunk) >= bitmap->file_pages) return NULL;
 	return bitmap->filemap[file_page_index(chunk) - file_page_index(0)];
 }
 
@@ -739,6 +740,7 @@
 	}
 
 	page = filemap_get_page(bitmap, chunk);
+	if (!page) return;
 	bit = file_page_offset(chunk);
 
  	/* set the bit */
@@ -1322,6 +1324,18 @@
 
 }
 
+/* dirty the memory and file bits for bitmap chunks "s" to "e" */
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
+{
+	unsigned long chunk;
+
+	for (chunk = s; chunk <= e; chunk++) {
+		sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap);
+		bitmap_set_memory_bits(bitmap, sec, 1);
+		bitmap_file_set_bit(bitmap, sec);
+	}
+}
+
 /*
  * flush out any pending updates
  */
@@ -1430,8 +1444,7 @@
 	if (err)
 		goto error;
 
-	bitmap->chunkshift = find_first_bit(&bitmap->chunksize,
-					sizeof(bitmap->chunksize));
+	bitmap->chunkshift = ffz(~bitmap->chunksize);
 
 	/* now that chunksize and chunkshift are set, we can use these macros */
  	chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) /
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index bdbd349..655d816 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
  * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
+ * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the GPL.
  */
@@ -22,17 +23,19 @@
 #include "dm.h"
 
 #define DM_MSG_PREFIX "crypt"
+#define MESG_STR(x) x, sizeof(x)
 
 /*
  * per bio private data
  */
 struct crypt_io {
 	struct dm_target *target;
-	struct bio *bio;
+	struct bio *base_bio;
 	struct bio *first_clone;
 	struct work_struct work;
 	atomic_t pending;
 	int error;
+	int post_process;
 };
 
 /*
@@ -63,6 +66,7 @@
  * Crypt: maps a linear range of a block device
  * and encrypts / decrypts at the same time.
  */
+enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID };
 struct crypt_config {
 	struct dm_dev *dev;
 	sector_t start;
@@ -73,6 +77,7 @@
 	 */
 	mempool_t *io_pool;
 	mempool_t *page_pool;
+	struct bio_set *bs;
 
 	/*
 	 * crypto related data
@@ -86,11 +91,12 @@
 	char cipher[CRYPTO_MAX_ALG_NAME];
 	char chainmode[CRYPTO_MAX_ALG_NAME];
 	struct crypto_blkcipher *tfm;
+	unsigned long flags;
 	unsigned int key_size;
 	u8 key[0];
 };
 
-#define MIN_IOS        256
+#define MIN_IOS        16
 #define MIN_POOL_PAGES 32
 #define MIN_BIO_PAGES  8
 
@@ -306,6 +312,14 @@
 	return r;
 }
 
+ static void dm_crypt_bio_destructor(struct bio *bio)
+ {
+	struct crypt_io *io = bio->bi_private;
+	struct crypt_config *cc = io->target->private;
+
+	bio_free(bio, cc->bs);
+ }
+
 /*
  * Generate a new unfragmented bio with the given size
  * This should never violate the device limitations
@@ -315,34 +329,33 @@
 crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
                    struct bio *base_bio, unsigned int *bio_vec_idx)
 {
-	struct bio *bio;
+	struct bio *clone;
 	unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
 	unsigned int i;
 
-	/*
-	 * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and
-	 * to fail earlier.  This is not necessary but increases throughput.
-	 * FIXME: Is this really intelligent?
-	 */
-	if (base_bio)
-		bio = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC);
-	else
-		bio = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs);
-	if (!bio)
+	if (base_bio) {
+		clone = bio_alloc_bioset(GFP_NOIO, base_bio->bi_max_vecs, cc->bs);
+		__bio_clone(clone, base_bio);
+	} else
+		clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
+
+	if (!clone)
 		return NULL;
 
+	clone->bi_destructor = dm_crypt_bio_destructor;
+
 	/* if the last bio was not complete, continue where that one ended */
-	bio->bi_idx = *bio_vec_idx;
-	bio->bi_vcnt = *bio_vec_idx;
-	bio->bi_size = 0;
-	bio->bi_flags &= ~(1 << BIO_SEG_VALID);
+	clone->bi_idx = *bio_vec_idx;
+	clone->bi_vcnt = *bio_vec_idx;
+	clone->bi_size = 0;
+	clone->bi_flags &= ~(1 << BIO_SEG_VALID);
 
-	/* bio->bi_idx pages have already been allocated */
-	size -= bio->bi_idx * PAGE_SIZE;
+	/* clone->bi_idx pages have already been allocated */
+	size -= clone->bi_idx * PAGE_SIZE;
 
-	for(i = bio->bi_idx; i < nr_iovecs; i++) {
-		struct bio_vec *bv = bio_iovec_idx(bio, i);
+	for (i = clone->bi_idx; i < nr_iovecs; i++) {
+		struct bio_vec *bv = bio_iovec_idx(clone, i);
 
 		bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
 		if (!bv->bv_page)
@@ -353,7 +366,7 @@
 		 * return a partially allocated bio, the caller will then try
 		 * to allocate additional bios while submitting this partial bio
 		 */
-		if ((i - bio->bi_idx) == (MIN_BIO_PAGES - 1))
+		if ((i - clone->bi_idx) == (MIN_BIO_PAGES - 1))
 			gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
 
 		bv->bv_offset = 0;
@@ -362,13 +375,13 @@
 		else
 			bv->bv_len = size;
 
-		bio->bi_size += bv->bv_len;
-		bio->bi_vcnt++;
+		clone->bi_size += bv->bv_len;
+		clone->bi_vcnt++;
 		size -= bv->bv_len;
 	}
 
-	if (!bio->bi_size) {
-		bio_put(bio);
+	if (!clone->bi_size) {
+		bio_put(clone);
 		return NULL;
 	}
 
@@ -376,13 +389,13 @@
 	 * Remember the last bio_vec allocated to be able
 	 * to correctly continue after the splitting.
 	 */
-	*bio_vec_idx = bio->bi_vcnt;
+	*bio_vec_idx = clone->bi_vcnt;
 
-	return bio;
+	return clone;
 }
 
 static void crypt_free_buffer_pages(struct crypt_config *cc,
-                                    struct bio *bio, unsigned int bytes)
+                                    struct bio *clone, unsigned int bytes)
 {
 	unsigned int i, start, end;
 	struct bio_vec *bv;
@@ -396,19 +409,19 @@
 	 * A fix to the bi_idx issue in the kernel is in the works, so
 	 * we will hopefully be able to revert to the cleaner solution soon.
 	 */
-	i = bio->bi_vcnt - 1;
-	bv = bio_iovec_idx(bio, i);
-	end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - bio->bi_size;
+	i = clone->bi_vcnt - 1;
+	bv = bio_iovec_idx(clone, i);
+	end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - clone->bi_size;
 	start = end - bytes;
 
 	start >>= PAGE_SHIFT;
-	if (!bio->bi_size)
-		end = bio->bi_vcnt;
+	if (!clone->bi_size)
+		end = clone->bi_vcnt;
 	else
 		end >>= PAGE_SHIFT;
 
-	for(i = start; i < end; i++) {
-		bv = bio_iovec_idx(bio, i);
+	for (i = start; i < end; i++) {
+		bv = bio_iovec_idx(clone, i);
 		BUG_ON(!bv->bv_page);
 		mempool_free(bv->bv_page, cc->page_pool);
 		bv->bv_page = NULL;
@@ -432,7 +445,7 @@
 	if (io->first_clone)
 		bio_put(io->first_clone);
 
-	bio_endio(io->bio, io->bio->bi_size, io->error);
+	bio_endio(io->base_bio, io->base_bio->bi_size, io->error);
 
 	mempool_free(io, cc->io_pool);
 }
@@ -441,24 +454,10 @@
  * kcryptd:
  *
  * Needed because it would be very unwise to do decryption in an
- * interrupt context, so bios returning from read requests get
- * queued here.
+ * interrupt context.
  */
 static struct workqueue_struct *_kcryptd_workqueue;
-
-static void kcryptd_do_work(void *data)
-{
-	struct crypt_io *io = (struct crypt_io *) data;
-	struct crypt_config *cc = (struct crypt_config *) io->target->private;
-	struct convert_context ctx;
-	int r;
-
-	crypt_convert_init(cc, &ctx, io->bio, io->bio,
-	                   io->bio->bi_sector - io->target->begin, 0);
-	r = crypt_convert(cc, &ctx);
-
-	dec_pending(io, r);
-}
+static void kcryptd_do_work(void *data);
 
 static void kcryptd_queue_io(struct crypt_io *io)
 {
@@ -466,6 +465,170 @@
 	queue_work(_kcryptd_workqueue, &io->work);
 }
 
+static int crypt_endio(struct bio *clone, unsigned int done, int error)
+{
+	struct crypt_io *io = clone->bi_private;
+	struct crypt_config *cc = io->target->private;
+	unsigned read_io = bio_data_dir(clone) == READ;
+
+	/*
+	 * free the processed pages, even if
+	 * it's only a partially completed write
+	 */
+	if (!read_io)
+		crypt_free_buffer_pages(cc, clone, done);
+
+	/* keep going - not finished yet */
+	if (unlikely(clone->bi_size))
+		return 1;
+
+	if (!read_io)
+		goto out;
+
+	if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) {
+		error = -EIO;
+		goto out;
+	}
+
+	bio_put(clone);
+	io->post_process = 1;
+	kcryptd_queue_io(io);
+	return 0;
+
+out:
+	bio_put(clone);
+	dec_pending(io, error);
+	return error;
+}
+
+static void clone_init(struct crypt_io *io, struct bio *clone)
+{
+	struct crypt_config *cc = io->target->private;
+
+	clone->bi_private = io;
+	clone->bi_end_io  = crypt_endio;
+	clone->bi_bdev    = cc->dev->bdev;
+	clone->bi_rw      = io->base_bio->bi_rw;
+}
+
+static void process_read(struct crypt_io *io)
+{
+	struct crypt_config *cc = io->target->private;
+	struct bio *base_bio = io->base_bio;
+	struct bio *clone;
+	sector_t sector = base_bio->bi_sector - io->target->begin;
+
+	atomic_inc(&io->pending);
+
+	/*
+	 * The block layer might modify the bvec array, so always
+	 * copy the required bvecs because we need the original
+	 * one in order to decrypt the whole bio data *afterwards*.
+	 */
+	clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs);
+	if (unlikely(!clone)) {
+		dec_pending(io, -ENOMEM);
+		return;
+	}
+
+	clone_init(io, clone);
+	clone->bi_destructor = dm_crypt_bio_destructor;
+	clone->bi_idx = 0;
+	clone->bi_vcnt = bio_segments(base_bio);
+	clone->bi_size = base_bio->bi_size;
+	clone->bi_sector = cc->start + sector;
+	memcpy(clone->bi_io_vec, bio_iovec(base_bio),
+	       sizeof(struct bio_vec) * clone->bi_vcnt);
+
+	generic_make_request(clone);
+}
+
+static void process_write(struct crypt_io *io)
+{
+	struct crypt_config *cc = io->target->private;
+	struct bio *base_bio = io->base_bio;
+	struct bio *clone;
+	struct convert_context ctx;
+	unsigned remaining = base_bio->bi_size;
+	sector_t sector = base_bio->bi_sector - io->target->begin;
+	unsigned bvec_idx = 0;
+
+	atomic_inc(&io->pending);
+
+	crypt_convert_init(cc, &ctx, NULL, base_bio, sector, 1);
+
+	/*
+	 * The allocated buffers can be smaller than the whole bio,
+	 * so repeat the whole process until all the data can be handled.
+	 */
+	while (remaining) {
+		clone = crypt_alloc_buffer(cc, base_bio->bi_size,
+					   io->first_clone, &bvec_idx);
+		if (unlikely(!clone)) {
+			dec_pending(io, -ENOMEM);
+			return;
+		}
+
+		ctx.bio_out = clone;
+
+		if (unlikely(crypt_convert(cc, &ctx) < 0)) {
+			crypt_free_buffer_pages(cc, clone, clone->bi_size);
+			bio_put(clone);
+			dec_pending(io, -EIO);
+			return;
+		}
+
+		clone_init(io, clone);
+		clone->bi_sector = cc->start + sector;
+
+		if (!io->first_clone) {
+			/*
+			 * hold a reference to the first clone, because it
+			 * holds the bio_vec array and that can't be freed
+			 * before all other clones are released
+			 */
+			bio_get(clone);
+			io->first_clone = clone;
+		}
+
+		remaining -= clone->bi_size;
+		sector += bio_sectors(clone);
+
+		/* prevent bio_put of first_clone */
+		if (remaining)
+			atomic_inc(&io->pending);
+
+		generic_make_request(clone);
+
+		/* out of memory -> run queues */
+		if (remaining)
+			blk_congestion_wait(bio_data_dir(clone), HZ/100);
+	}
+}
+
+static void process_read_endio(struct crypt_io *io)
+{
+	struct crypt_config *cc = io->target->private;
+	struct convert_context ctx;
+
+	crypt_convert_init(cc, &ctx, io->base_bio, io->base_bio,
+			   io->base_bio->bi_sector - io->target->begin, 0);
+
+	dec_pending(io, crypt_convert(cc, &ctx));
+}
+
+static void kcryptd_do_work(void *data)
+{
+	struct crypt_io *io = data;
+
+	if (io->post_process)
+		process_read_endio(io);
+	else if (bio_data_dir(io->base_bio) == READ)
+		process_read(io);
+	else
+		process_write(io);
+}
+
 /*
  * Decode key from its hex representation
  */
@@ -477,7 +640,7 @@
 
 	buffer[2] = '\0';
 
-	for(i = 0; i < size; i++) {
+	for (i = 0; i < size; i++) {
 		buffer[0] = *hex++;
 		buffer[1] = *hex++;
 
@@ -500,13 +663,38 @@
 {
 	unsigned int i;
 
-	for(i = 0; i < size; i++) {
+	for (i = 0; i < size; i++) {
 		sprintf(hex, "%02x", *key);
 		hex += 2;
 		key++;
 	}
 }
 
+static int crypt_set_key(struct crypt_config *cc, char *key)
+{
+	unsigned key_size = strlen(key) >> 1;
+
+	if (cc->key_size && cc->key_size != key_size)
+		return -EINVAL;
+
+	cc->key_size = key_size; /* initial settings */
+
+	if ((!key_size && strcmp(key, "-")) ||
+	    (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
+		return -EINVAL;
+
+	set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+
+	return 0;
+}
+
+static int crypt_wipe_key(struct crypt_config *cc)
+{
+	clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+	memset(&cc->key, 0, cc->key_size * sizeof(u8));
+	return 0;
+}
+
 /*
  * Construct an encryption mapping:
  * <cipher> <key> <iv_offset> <dev_path> <start>
@@ -539,16 +727,14 @@
 
 	key_size = strlen(argv[1]) >> 1;
 
-	cc = kmalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
+ 	cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
 	if (cc == NULL) {
 		ti->error =
 			"Cannot allocate transparent encryption context";
 		return -ENOMEM;
 	}
 
-	cc->key_size = key_size;
-	if ((!key_size && strcmp(argv[1], "-") != 0) ||
-	    (key_size && crypt_decode_key(cc->key, argv[1], key_size) < 0)) {
+ 	if (crypt_set_key(cc, argv[1])) {
 		ti->error = "Error decoding key";
 		goto bad1;
 	}
@@ -626,6 +812,12 @@
 		goto bad4;
 	}
 
+	cc->bs = bioset_create(MIN_IOS, MIN_IOS, 4);
+	if (!cc->bs) {
+		ti->error = "Cannot allocate crypt bioset";
+		goto bad_bs;
+	}
+
 	if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
 		ti->error = "Error setting key";
 		goto bad5;
@@ -665,6 +857,8 @@
 	return 0;
 
 bad5:
+	bioset_free(cc->bs);
+bad_bs:
 	mempool_destroy(cc->page_pool);
 bad4:
 	mempool_destroy(cc->io_pool);
@@ -684,6 +878,7 @@
 {
 	struct crypt_config *cc = (struct crypt_config *) ti->private;
 
+	bioset_free(cc->bs);
 	mempool_destroy(cc->page_pool);
 	mempool_destroy(cc->io_pool);
 
@@ -698,147 +893,21 @@
 	kfree(cc);
 }
 
-static int crypt_endio(struct bio *bio, unsigned int done, int error)
-{
-	struct crypt_io *io = (struct crypt_io *) bio->bi_private;
-	struct crypt_config *cc = (struct crypt_config *) io->target->private;
-
-	if (bio_data_dir(bio) == WRITE) {
-		/*
-		 * free the processed pages, even if
-		 * it's only a partially completed write
-		 */
-		crypt_free_buffer_pages(cc, bio, done);
-	}
-
-	if (bio->bi_size)
-		return 1;
-
-	bio_put(bio);
-
-	/*
-	 * successful reads are decrypted by the worker thread
-	 */
-	if ((bio_data_dir(bio) == READ)
-	    && bio_flagged(bio, BIO_UPTODATE)) {
-		kcryptd_queue_io(io);
-		return 0;
-	}
-
-	dec_pending(io, error);
-	return error;
-}
-
-static inline struct bio *
-crypt_clone(struct crypt_config *cc, struct crypt_io *io, struct bio *bio,
-            sector_t sector, unsigned int *bvec_idx,
-            struct convert_context *ctx)
-{
-	struct bio *clone;
-
-	if (bio_data_dir(bio) == WRITE) {
-		clone = crypt_alloc_buffer(cc, bio->bi_size,
-                                 io->first_clone, bvec_idx);
-		if (clone) {
-			ctx->bio_out = clone;
-			if (crypt_convert(cc, ctx) < 0) {
-				crypt_free_buffer_pages(cc, clone,
-				                        clone->bi_size);
-				bio_put(clone);
-				return NULL;
-			}
-		}
-	} else {
-		/*
-		 * The block layer might modify the bvec array, so always
-		 * copy the required bvecs because we need the original
-		 * one in order to decrypt the whole bio data *afterwards*.
-		 */
-		clone = bio_alloc(GFP_NOIO, bio_segments(bio));
-		if (clone) {
-			clone->bi_idx = 0;
-			clone->bi_vcnt = bio_segments(bio);
-			clone->bi_size = bio->bi_size;
-			memcpy(clone->bi_io_vec, bio_iovec(bio),
-			       sizeof(struct bio_vec) * clone->bi_vcnt);
-		}
-	}
-
-	if (!clone)
-		return NULL;
-
-	clone->bi_private = io;
-	clone->bi_end_io = crypt_endio;
-	clone->bi_bdev = cc->dev->bdev;
-	clone->bi_sector = cc->start + sector;
-	clone->bi_rw = bio->bi_rw;
-
-	return clone;
-}
-
 static int crypt_map(struct dm_target *ti, struct bio *bio,
 		     union map_info *map_context)
 {
-	struct crypt_config *cc = (struct crypt_config *) ti->private;
-	struct crypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO);
-	struct convert_context ctx;
-	struct bio *clone;
-	unsigned int remaining = bio->bi_size;
-	sector_t sector = bio->bi_sector - ti->begin;
-	unsigned int bvec_idx = 0;
+	struct crypt_config *cc = ti->private;
+	struct crypt_io *io;
 
+	io = mempool_alloc(cc->io_pool, GFP_NOIO);
 	io->target = ti;
-	io->bio = bio;
+	io->base_bio = bio;
 	io->first_clone = NULL;
-	io->error = 0;
-	atomic_set(&io->pending, 1); /* hold a reference */
+	io->error = io->post_process = 0;
+	atomic_set(&io->pending, 0);
+	kcryptd_queue_io(io);
 
-	if (bio_data_dir(bio) == WRITE)
-		crypt_convert_init(cc, &ctx, NULL, bio, sector, 1);
-
-	/*
-	 * The allocated buffers can be smaller than the whole bio,
-	 * so repeat the whole process until all the data can be handled.
-	 */
-	while (remaining) {
-		clone = crypt_clone(cc, io, bio, sector, &bvec_idx, &ctx);
-		if (!clone)
-			goto cleanup;
-
-		if (!io->first_clone) {
-			/*
-			 * hold a reference to the first clone, because it
-			 * holds the bio_vec array and that can't be freed
-			 * before all other clones are released
-			 */
-			bio_get(clone);
-			io->first_clone = clone;
-		}
-		atomic_inc(&io->pending);
-
-		remaining -= clone->bi_size;
-		sector += bio_sectors(clone);
-
-		generic_make_request(clone);
-
-		/* out of memory -> run queues */
-		if (remaining)
-			blk_congestion_wait(bio_data_dir(clone), HZ/100);
-	}
-
-	/* drop reference, clones could have returned before we reach this */
-	dec_pending(io, 0);
 	return 0;
-
-cleanup:
-	if (io->first_clone) {
-		dec_pending(io, -ENOMEM);
-		return 0;
-	}
-
-	/* if no bio has been dispatched yet, we can directly return the error */
-	mempool_free(io, cc->io_pool);
-	return -ENOMEM;
 }
 
 static int crypt_status(struct dm_target *ti, status_type_t type,
@@ -883,14 +952,71 @@
 	return 0;
 }
 
+static void crypt_postsuspend(struct dm_target *ti)
+{
+	struct crypt_config *cc = ti->private;
+
+	set_bit(DM_CRYPT_SUSPENDED, &cc->flags);
+}
+
+static int crypt_preresume(struct dm_target *ti)
+{
+	struct crypt_config *cc = ti->private;
+
+	if (!test_bit(DM_CRYPT_KEY_VALID, &cc->flags)) {
+		DMERR("aborting resume - crypt key is not set.");
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
+static void crypt_resume(struct dm_target *ti)
+{
+	struct crypt_config *cc = ti->private;
+
+	clear_bit(DM_CRYPT_SUSPENDED, &cc->flags);
+}
+
+/* Message interface
+ *	key set <key>
+ *	key wipe
+ */
+static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+	struct crypt_config *cc = ti->private;
+
+	if (argc < 2)
+		goto error;
+
+	if (!strnicmp(argv[0], MESG_STR("key"))) {
+		if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) {
+			DMWARN("not suspended during key manipulation.");
+			return -EINVAL;
+		}
+		if (argc == 3 && !strnicmp(argv[1], MESG_STR("set")))
+			return crypt_set_key(cc, argv[2]);
+		if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe")))
+			return crypt_wipe_key(cc);
+	}
+
+error:
+	DMWARN("unrecognised message received.");
+	return -EINVAL;
+}
+
 static struct target_type crypt_target = {
 	.name   = "crypt",
-	.version= {1, 1, 0},
+	.version= {1, 3, 0},
 	.module = THIS_MODULE,
 	.ctr    = crypt_ctr,
 	.dtr    = crypt_dtr,
 	.map    = crypt_map,
 	.status = crypt_status,
+	.postsuspend = crypt_postsuspend,
+	.preresume = crypt_preresume,
+	.resume = crypt_resume,
+	.message = crypt_message,
 };
 
 static int __init dm_crypt_init(void)
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index d12379b..99cdffa 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 
 #define DM_MSG_PREFIX "snapshots"
+#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32	/* 16KB */
 
 /*-----------------------------------------------------------------
  * Persistent snapshots, by persistent we mean that the snapshot
@@ -150,6 +151,7 @@
 static void free_area(struct pstore *ps)
 {
 	vfree(ps->area);
+	ps->area = NULL;
 }
 
 /*
@@ -198,48 +200,79 @@
 	int r;
 	struct disk_header *dh;
 	chunk_t chunk_size;
+	int chunk_size_supplied = 1;
+
+	/*
+	 * Use default chunk size (or hardsect_size, if larger) if none supplied
+	 */
+	if (!ps->snap->chunk_size) {
+        	ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+		    bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
+		ps->snap->chunk_mask = ps->snap->chunk_size - 1;
+		ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+		chunk_size_supplied = 0;
+	}
+
+	r = dm_io_get(sectors_to_pages(ps->snap->chunk_size));
+	if (r)
+		return r;
+
+	r = alloc_area(ps);
+	if (r)
+		goto bad1;
 
 	r = chunk_io(ps, 0, READ);
 	if (r)
-		return r;
+		goto bad2;
 
 	dh = (struct disk_header *) ps->area;
 
 	if (le32_to_cpu(dh->magic) == 0) {
 		*new_snapshot = 1;
-
-	} else if (le32_to_cpu(dh->magic) == SNAP_MAGIC) {
-		*new_snapshot = 0;
-		ps->valid = le32_to_cpu(dh->valid);
-		ps->version = le32_to_cpu(dh->version);
-		chunk_size = le32_to_cpu(dh->chunk_size);
-		if (ps->snap->chunk_size != chunk_size) {
-			DMWARN("chunk size %llu in device metadata overrides "
-			       "table chunk size of %llu.",
-			       (unsigned long long)chunk_size,
-			       (unsigned long long)ps->snap->chunk_size);
-
-			/* We had a bogus chunk_size. Fix stuff up. */
-			dm_io_put(sectors_to_pages(ps->snap->chunk_size));
-			free_area(ps);
-
-			ps->snap->chunk_size = chunk_size;
-			ps->snap->chunk_mask = chunk_size - 1;
-			ps->snap->chunk_shift = ffs(chunk_size) - 1;
-
-			r = alloc_area(ps);
-			if (r)
-				return r;
-
-			r = dm_io_get(sectors_to_pages(chunk_size));
-			if (r)
-				return r;
-		}
-	} else {
-		DMWARN("Invalid/corrupt snapshot");
-		r = -ENXIO;
+		return 0;
 	}
 
+	if (le32_to_cpu(dh->magic) != SNAP_MAGIC) {
+		DMWARN("Invalid or corrupt snapshot");
+		r = -ENXIO;
+		goto bad2;
+	}
+
+	*new_snapshot = 0;
+	ps->valid = le32_to_cpu(dh->valid);
+	ps->version = le32_to_cpu(dh->version);
+	chunk_size = le32_to_cpu(dh->chunk_size);
+
+	if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+		return 0;
+
+	DMWARN("chunk size %llu in device metadata overrides "
+	       "table chunk size of %llu.",
+	       (unsigned long long)chunk_size,
+	       (unsigned long long)ps->snap->chunk_size);
+
+	/* We had a bogus chunk_size. Fix stuff up. */
+	dm_io_put(sectors_to_pages(ps->snap->chunk_size));
+	free_area(ps);
+
+	ps->snap->chunk_size = chunk_size;
+	ps->snap->chunk_mask = chunk_size - 1;
+	ps->snap->chunk_shift = ffs(chunk_size) - 1;
+
+	r = dm_io_get(sectors_to_pages(chunk_size));
+	if (r)
+		return r;
+
+	r = alloc_area(ps);
+	if (r)
+		goto bad1;
+
+	return 0;
+
+bad2:
+	free_area(ps);
+bad1:
+	dm_io_put(sectors_to_pages(ps->snap->chunk_size));
 	return r;
 }
 
@@ -263,42 +296,29 @@
  */
 static struct disk_exception *get_exception(struct pstore *ps, uint32_t index)
 {
-	if (index >= ps->exceptions_per_area)
-		return NULL;
+	BUG_ON(index >= ps->exceptions_per_area);
 
 	return ((struct disk_exception *) ps->area) + index;
 }
 
-static int read_exception(struct pstore *ps,
-			  uint32_t index, struct disk_exception *result)
+static void read_exception(struct pstore *ps,
+			   uint32_t index, struct disk_exception *result)
 {
-	struct disk_exception *e;
-
-	e = get_exception(ps, index);
-	if (!e)
-		return -EINVAL;
+	struct disk_exception *e = get_exception(ps, index);
 
 	/* copy it */
 	result->old_chunk = le64_to_cpu(e->old_chunk);
 	result->new_chunk = le64_to_cpu(e->new_chunk);
-
-	return 0;
 }
 
-static int write_exception(struct pstore *ps,
-			   uint32_t index, struct disk_exception *de)
+static void write_exception(struct pstore *ps,
+			    uint32_t index, struct disk_exception *de)
 {
-	struct disk_exception *e;
-
-	e = get_exception(ps, index);
-	if (!e)
-		return -EINVAL;
+	struct disk_exception *e = get_exception(ps, index);
 
 	/* copy it */
 	e->old_chunk = cpu_to_le64(de->old_chunk);
 	e->new_chunk = cpu_to_le64(de->new_chunk);
-
-	return 0;
 }
 
 /*
@@ -316,10 +336,7 @@
 	*full = 1;
 
 	for (i = 0; i < ps->exceptions_per_area; i++) {
-		r = read_exception(ps, i, &de);
-
-		if (r)
-			return r;
+		read_exception(ps, i, &de);
 
 		/*
 		 * If the new_chunk is pointing at the start of
@@ -519,6 +536,16 @@
 		if (r)
 			ps->valid = 0;
 
+		/*
+		 * Have we completely filled the current area ?
+		 */
+		if (ps->current_committed == ps->exceptions_per_area) {
+			ps->current_committed = 0;
+			r = zero_area(ps, ps->current_area + 1);
+			if (r)
+				ps->valid = 0;
+		}
+
 		for (i = 0; i < ps->callback_count; i++) {
 			cb = ps->callbacks + i;
 			cb->callback(cb->context, r == 0 ? 1 : 0);
@@ -526,16 +553,6 @@
 
 		ps->callback_count = 0;
 	}
-
-	/*
-	 * Have we completely filled the current area ?
-	 */
-	if (ps->current_committed == ps->exceptions_per_area) {
-		ps->current_committed = 0;
-		r = zero_area(ps, ps->current_area + 1);
-		if (r)
-			ps->valid = 0;
-	}
 }
 
 static void persistent_drop(struct exception_store *store)
@@ -547,32 +564,22 @@
 		DMWARN("write header failed");
 }
 
-int dm_create_persistent(struct exception_store *store, uint32_t chunk_size)
+int dm_create_persistent(struct exception_store *store)
 {
-	int r;
 	struct pstore *ps;
 
-	r = dm_io_get(sectors_to_pages(chunk_size));
-	if (r)
-		return r;
-
 	/* allocate the pstore */
 	ps = kmalloc(sizeof(*ps), GFP_KERNEL);
-	if (!ps) {
-		r = -ENOMEM;
-		goto bad;
-	}
+	if (!ps)
+		return -ENOMEM;
 
 	ps->snap = store->snap;
 	ps->valid = 1;
 	ps->version = SNAPSHOT_DISK_VERSION;
+	ps->area = NULL;
 	ps->next_free = 2;	/* skipping the header and first area */
 	ps->current_committed = 0;
 
-	r = alloc_area(ps);
-	if (r)
-		goto bad;
-
 	ps->callback_count = 0;
 	atomic_set(&ps->pending_count, 0);
 	ps->callbacks = NULL;
@@ -586,13 +593,6 @@
 	store->context = ps;
 
 	return 0;
-
-      bad:
-	dm_io_put(sectors_to_pages(chunk_size));
-	if (ps && ps->area)
-		free_area(ps);
-	kfree(ps);
-	return r;
 }
 
 /*-----------------------------------------------------------------
@@ -642,18 +642,16 @@
 	*denominator = get_dev_size(store->snap->cow->bdev);
 }
 
-int dm_create_transient(struct exception_store *store,
-			struct dm_snapshot *s, int blocksize)
+int dm_create_transient(struct exception_store *store)
 {
 	struct transient_c *tc;
 
-	memset(store, 0, sizeof(*store));
 	store->destroy = transient_destroy;
 	store->read_metadata = transient_read_metadata;
 	store->prepare_exception = transient_prepare;
 	store->commit_exception = transient_commit;
+	store->drop_snapshot = NULL;
 	store->fraction_full = transient_fraction_full;
-	store->snap = s;
 
 	tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
 	if (!tc)
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 47b3c62..0023490 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -98,14 +98,31 @@
 	return 0;
 }
 
+static int linear_ioctl(struct dm_target *ti, struct inode *inode,
+			struct file *filp, unsigned int cmd,
+			unsigned long arg)
+{
+	struct linear_c *lc = (struct linear_c *) ti->private;
+	struct block_device *bdev = lc->dev->bdev;
+	struct file fake_file = {};
+	struct dentry fake_dentry = {};
+
+	fake_file.f_mode = lc->dev->mode;
+	fake_file.f_dentry = &fake_dentry;
+	fake_dentry.d_inode = bdev->bd_inode;
+
+	return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
+}
+
 static struct target_type linear_target = {
 	.name   = "linear",
-	.version= {1, 0, 1},
+	.version= {1, 0, 2},
 	.module = THIS_MODULE,
 	.ctr    = linear_ctr,
 	.dtr    = linear_dtr,
 	.map    = linear_map,
 	.status = linear_status,
+	.ioctl  = linear_ioctl,
 };
 
 int __init dm_linear_init(void)
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 93f701e..d754e0b 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -114,12 +114,10 @@
 
 static struct pgpath *alloc_pgpath(void)
 {
-	struct pgpath *pgpath = kmalloc(sizeof(*pgpath), GFP_KERNEL);
+	struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL);
 
-	if (pgpath) {
-		memset(pgpath, 0, sizeof(*pgpath));
+	if (pgpath)
 		pgpath->path.is_active = 1;
-	}
 
 	return pgpath;
 }
@@ -133,12 +131,10 @@
 {
 	struct priority_group *pg;
 
-	pg = kmalloc(sizeof(*pg), GFP_KERNEL);
-	if (!pg)
-		return NULL;
+	pg = kzalloc(sizeof(*pg), GFP_KERNEL);
 
-	memset(pg, 0, sizeof(*pg));
-	INIT_LIST_HEAD(&pg->pgpaths);
+	if (pg)
+		INIT_LIST_HEAD(&pg->pgpaths);
 
 	return pg;
 }
@@ -168,13 +164,12 @@
 	kfree(pg);
 }
 
-static struct multipath *alloc_multipath(void)
+static struct multipath *alloc_multipath(struct dm_target *ti)
 {
 	struct multipath *m;
 
-	m = kmalloc(sizeof(*m), GFP_KERNEL);
+	m = kzalloc(sizeof(*m), GFP_KERNEL);
 	if (m) {
-		memset(m, 0, sizeof(*m));
 		INIT_LIST_HEAD(&m->priority_groups);
 		spin_lock_init(&m->lock);
 		m->queue_io = 1;
@@ -185,6 +180,8 @@
 			kfree(m);
 			return NULL;
 		}
+		m->ti = ti;
+		ti->private = m;
 	}
 
 	return m;
@@ -557,8 +554,7 @@
 }
 
 static struct priority_group *parse_priority_group(struct arg_set *as,
-						   struct multipath *m,
-						   struct dm_target *ti)
+						   struct multipath *m)
 {
 	static struct param _params[] = {
 		{1, 1024, "invalid number of paths"},
@@ -568,6 +564,7 @@
 	int r;
 	unsigned i, nr_selector_args, nr_params;
 	struct priority_group *pg;
+	struct dm_target *ti = m->ti;
 
 	if (as->argc < 2) {
 		as->argc = 0;
@@ -624,12 +621,12 @@
 	return NULL;
 }
 
-static int parse_hw_handler(struct arg_set *as, struct multipath *m,
-			    struct dm_target *ti)
+static int parse_hw_handler(struct arg_set *as, struct multipath *m)
 {
 	int r;
 	struct hw_handler_type *hwht;
 	unsigned hw_argc;
+	struct dm_target *ti = m->ti;
 
 	static struct param _params[] = {
 		{0, 1024, "invalid number of hardware handler args"},
@@ -661,11 +658,11 @@
 	return 0;
 }
 
-static int parse_features(struct arg_set *as, struct multipath *m,
-			  struct dm_target *ti)
+static int parse_features(struct arg_set *as, struct multipath *m)
 {
 	int r;
 	unsigned argc;
+	struct dm_target *ti = m->ti;
 
 	static struct param _params[] = {
 		{0, 1, "invalid number of feature args"},
@@ -704,19 +701,17 @@
 	as.argc = argc;
 	as.argv = argv;
 
-	m = alloc_multipath();
+	m = alloc_multipath(ti);
 	if (!m) {
 		ti->error = "can't allocate multipath";
 		return -EINVAL;
 	}
 
-	m->ti = ti;
-
-	r = parse_features(&as, m, ti);
+	r = parse_features(&as, m);
 	if (r)
 		goto bad;
 
-	r = parse_hw_handler(&as, m, ti);
+	r = parse_hw_handler(&as, m);
 	if (r)
 		goto bad;
 
@@ -732,7 +727,7 @@
 	while (as.argc) {
 		struct priority_group *pg;
 
-		pg = parse_priority_group(&as, m, ti);
+		pg = parse_priority_group(&as, m);
 		if (!pg) {
 			r = -EINVAL;
 			goto bad;
@@ -752,8 +747,6 @@
 		goto bad;
 	}
 
-	ti->private = m;
-
 	return 0;
 
  bad:
@@ -1266,12 +1259,47 @@
 	return -EINVAL;
 }
 
+static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
+			   struct file *filp, unsigned int cmd,
+			   unsigned long arg)
+{
+	struct multipath *m = (struct multipath *) ti->private;
+	struct block_device *bdev = NULL;
+	unsigned long flags;
+	struct file fake_file = {};
+	struct dentry fake_dentry = {};
+	int r = 0;
+
+	fake_file.f_dentry = &fake_dentry;
+
+	spin_lock_irqsave(&m->lock, flags);
+
+	if (!m->current_pgpath)
+		__choose_pgpath(m);
+
+	if (m->current_pgpath) {
+		bdev = m->current_pgpath->path.dev->bdev;
+		fake_dentry.d_inode = bdev->bd_inode;
+		fake_file.f_mode = m->current_pgpath->path.dev->mode;
+	}
+
+	if (m->queue_io)
+		r = -EAGAIN;
+	else if (!bdev)
+		r = -EIO;
+
+	spin_unlock_irqrestore(&m->lock, flags);
+
+	return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file,
+					 bdev->bd_disk, cmd, arg);
+}
+
 /*-----------------------------------------------------------------
  * Module setup
  *---------------------------------------------------------------*/
 static struct target_type multipath_target = {
 	.name = "multipath",
-	.version = {1, 0, 4},
+	.version = {1, 0, 5},
 	.module = THIS_MODULE,
 	.ctr = multipath_ctr,
 	.dtr = multipath_dtr,
@@ -1281,6 +1309,7 @@
 	.resume = multipath_resume,
 	.status = multipath_status,
 	.message = multipath_message,
+	.ioctl  = multipath_ioctl,
 };
 
 static int __init dm_multipath_init(void)
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index c54de98..659224c 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1213,9 +1213,9 @@
 		break;
 
 	case STATUSTYPE_TABLE:
-		DMEMIT("%d ", ms->nr_mirrors);
+		DMEMIT("%d", ms->nr_mirrors);
 		for (m = 0; m < ms->nr_mirrors; m++)
-			DMEMIT("%s %llu ", ms->mirror[m].dev->name,
+			DMEMIT(" %s %llu", ms->mirror[m].dev->name,
 				(unsigned long long)ms->mirror[m].offset);
 	}
 
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 1d0fafd..5281e00 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -39,6 +39,9 @@
  */
 #define SNAPSHOT_PAGES 256
 
+struct workqueue_struct *ksnapd;
+static void flush_queued_bios(void *data);
+
 struct pending_exception {
 	struct exception e;
 
@@ -56,7 +59,7 @@
 
 	/*
 	 * The primary pending_exception is the one that holds
-	 * the sibling_count and the list of origin_bios for a
+	 * the ref_count and the list of origin_bios for a
 	 * group of pending_exceptions.  It is always last to get freed.
 	 * These fields get set up when writing to the origin.
 	 */
@@ -69,7 +72,7 @@
 	 * the sibling concerned and not pe->primary_pe->snap->lock unless
 	 * they are the same.
 	 */
-	atomic_t sibling_count;
+	atomic_t ref_count;
 
 	/* Pointer back to snapshot context */
 	struct dm_snapshot *snap;
@@ -387,15 +390,46 @@
 	return (n + size) & ~size;
 }
 
-static void read_snapshot_metadata(struct dm_snapshot *s)
+static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
+			  char **error)
 {
-	if (s->store.read_metadata(&s->store)) {
-		down_write(&s->lock);
-		s->valid = 0;
-		up_write(&s->lock);
+	unsigned long chunk_size;
+	char *value;
 
-		dm_table_event(s->table);
+	chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
+	if (*chunk_size_arg == '\0' || *value != '\0') {
+		*error = "Invalid chunk size";
+		return -EINVAL;
 	}
+
+	if (!chunk_size) {
+		s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
+		return 0;
+	}
+
+	/*
+	 * Chunk size must be multiple of page size.  Silently
+	 * round up if it's not.
+	 */
+	chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
+
+	/* Check chunk_size is a power of 2 */
+	if (chunk_size & (chunk_size - 1)) {
+		*error = "Chunk size is not a power of 2";
+		return -EINVAL;
+	}
+
+	/* Validate the chunk size against the device block size */
+	if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
+		*error = "Chunk size is not a multiple of device blocksize";
+		return -EINVAL;
+	}
+
+	s->chunk_size = chunk_size;
+	s->chunk_mask = chunk_size - 1;
+	s->chunk_shift = ffs(chunk_size) - 1;
+
+	return 0;
 }
 
 /*
@@ -404,15 +438,12 @@
 static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
 	struct dm_snapshot *s;
-	unsigned long chunk_size;
 	int r = -EINVAL;
 	char persistent;
 	char *origin_path;
 	char *cow_path;
-	char *value;
-	int blocksize;
 
-	if (argc < 4) {
+	if (argc != 4) {
 		ti->error = "requires exactly 4 arguments";
 		r = -EINVAL;
 		goto bad1;
@@ -428,13 +459,6 @@
 		goto bad1;
 	}
 
-	chunk_size = simple_strtoul(argv[3], &value, 10);
-	if (chunk_size == 0 || value == NULL) {
-		ti->error = "Invalid chunk size";
-		r = -EINVAL;
-		goto bad1;
-	}
-
 	s = kmalloc(sizeof(*s), GFP_KERNEL);
 	if (s == NULL) {
 		ti->error = "Cannot allocate snapshot context private "
@@ -457,36 +481,17 @@
 		goto bad2;
 	}
 
-	/*
-	 * Chunk size must be multiple of page size.  Silently
-	 * round up if it's not.
-	 */
-	chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
-	/* Validate the chunk size against the device block size */
-	blocksize = s->cow->bdev->bd_disk->queue->hardsect_size;
-	if (chunk_size % (blocksize >> 9)) {
-		ti->error = "Chunk size is not a multiple of device blocksize";
-		r = -EINVAL;
+	r = set_chunk_size(s, argv[3], &ti->error);
+	if (r)
 		goto bad3;
-	}
 
-	/* Check chunk_size is a power of 2 */
-	if (chunk_size & (chunk_size - 1)) {
-		ti->error = "Chunk size is not a power of 2";
-		r = -EINVAL;
-		goto bad3;
-	}
-
-	s->chunk_size = chunk_size;
-	s->chunk_mask = chunk_size - 1;
 	s->type = persistent;
-	s->chunk_shift = ffs(chunk_size) - 1;
 
 	s->valid = 1;
 	s->active = 0;
 	s->last_percent = 0;
 	init_rwsem(&s->lock);
+	spin_lock_init(&s->pe_lock);
 	s->table = ti->table;
 
 	/* Allocate hash table for COW data */
@@ -496,16 +501,12 @@
 		goto bad3;
 	}
 
-	/*
-	 * Check the persistent flag - done here because we need the iobuf
-	 * to check the LV header
-	 */
 	s->store.snap = s;
 
 	if (persistent == 'P')
-		r = dm_create_persistent(&s->store, chunk_size);
+		r = dm_create_persistent(&s->store);
 	else
-		r = dm_create_transient(&s->store, s, blocksize);
+		r = dm_create_transient(&s->store);
 
 	if (r) {
 		ti->error = "Couldn't create exception store";
@@ -520,7 +521,14 @@
 	}
 
 	/* Metadata must only be loaded into one table at once */
-	read_snapshot_metadata(s);
+	r = s->store.read_metadata(&s->store);
+	if (r) {
+		ti->error = "Failed to read snapshot metadata";
+		goto bad6;
+	}
+
+	bio_list_init(&s->queued_bios);
+	INIT_WORK(&s->queued_bios_work, flush_queued_bios, s);
 
 	/* Add snapshot to the list of snapshots for this origin */
 	/* Exceptions aren't triggered till snapshot_resume() is called */
@@ -560,6 +568,8 @@
 {
 	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
 
+	flush_workqueue(ksnapd);
+
 	/* Prevent further origin writes from using this snapshot. */
 	/* After this returns there can be no new kcopyd jobs. */
 	unregister_snapshot(s);
@@ -593,6 +603,19 @@
 	}
 }
 
+static void flush_queued_bios(void *data)
+{
+	struct dm_snapshot *s = (struct dm_snapshot *) data;
+	struct bio *queued_bios;
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->pe_lock, flags);
+	queued_bios = bio_list_get(&s->queued_bios);
+	spin_unlock_irqrestore(&s->pe_lock, flags);
+
+	flush_bios(queued_bios);
+}
+
 /*
  * Error a list of buffers.
  */
@@ -608,28 +631,7 @@
 	}
 }
 
-static inline void error_snapshot_bios(struct pending_exception *pe)
-{
-	error_bios(bio_list_get(&pe->snapshot_bios));
-}
-
-static struct bio *__flush_bios(struct pending_exception *pe)
-{
-	/*
-	 * If this pe is involved in a write to the origin and
-	 * it is the last sibling to complete then release
-	 * the bios for the original write to the origin.
-	 */
-
-	if (pe->primary_pe &&
-	    atomic_dec_and_test(&pe->primary_pe->sibling_count))
-		return bio_list_get(&pe->primary_pe->origin_bios);
-
-	return NULL;
-}
-
-static void __invalidate_snapshot(struct dm_snapshot *s,
-				struct pending_exception *pe, int err)
+static void __invalidate_snapshot(struct dm_snapshot *s, int err)
 {
 	if (!s->valid)
 		return;
@@ -639,9 +641,6 @@
 	else if (err == -ENOMEM)
 		DMERR("Invalidating snapshot: Unable to allocate exception.");
 
-	if (pe)
-		remove_exception(&pe->e);
-
 	if (s->store.drop_snapshot)
 		s->store.drop_snapshot(&s->store);
 
@@ -650,62 +649,26 @@
 	dm_table_event(s->table);
 }
 
-static void pending_complete(struct pending_exception *pe, int success)
+static void get_pending_exception(struct pending_exception *pe)
 {
-	struct exception *e;
+	atomic_inc(&pe->ref_count);
+}
+
+static struct bio *put_pending_exception(struct pending_exception *pe)
+{
 	struct pending_exception *primary_pe;
-	struct dm_snapshot *s = pe->snap;
-	struct bio *flush = NULL;
+	struct bio *origin_bios = NULL;
 
-	if (!success) {
-		/* Read/write error - snapshot is unusable */
-		down_write(&s->lock);
-		__invalidate_snapshot(s, pe, -EIO);
-		flush = __flush_bios(pe);
-		up_write(&s->lock);
-
-		error_snapshot_bios(pe);
-		goto out;
-	}
-
-	e = alloc_exception();
-	if (!e) {
-		down_write(&s->lock);
-		__invalidate_snapshot(s, pe, -ENOMEM);
-		flush = __flush_bios(pe);
-		up_write(&s->lock);
-
-		error_snapshot_bios(pe);
-		goto out;
-	}
-	*e = pe->e;
+	primary_pe = pe->primary_pe;
 
 	/*
-	 * Add a proper exception, and remove the
-	 * in-flight exception from the list.
+	 * If this pe is involved in a write to the origin and
+	 * it is the last sibling to complete then release
+	 * the bios for the original write to the origin.
 	 */
-	down_write(&s->lock);
-	if (!s->valid) {
-		flush = __flush_bios(pe);
-		up_write(&s->lock);
-
-		free_exception(e);
-
-		error_snapshot_bios(pe);
-		goto out;
-	}
-
-	insert_exception(&s->complete, e);
-	remove_exception(&pe->e);
-	flush = __flush_bios(pe);
-
-	up_write(&s->lock);
-
-	/* Submit any pending write bios */
-	flush_bios(bio_list_get(&pe->snapshot_bios));
-
- out:
-	primary_pe = pe->primary_pe;
+	if (primary_pe &&
+	    atomic_dec_and_test(&primary_pe->ref_count))
+		origin_bios = bio_list_get(&primary_pe->origin_bios);
 
 	/*
 	 * Free the pe if it's not linked to an origin write or if
@@ -717,11 +680,64 @@
 	/*
 	 * Free the primary pe if nothing references it.
 	 */
-	if (primary_pe && !atomic_read(&primary_pe->sibling_count))
+	if (primary_pe && !atomic_read(&primary_pe->ref_count))
 		free_pending_exception(primary_pe);
 
-	if (flush)
-		flush_bios(flush);
+	return origin_bios;
+}
+
+static void pending_complete(struct pending_exception *pe, int success)
+{
+	struct exception *e;
+	struct dm_snapshot *s = pe->snap;
+	struct bio *origin_bios = NULL;
+	struct bio *snapshot_bios = NULL;
+	int error = 0;
+
+	if (!success) {
+		/* Read/write error - snapshot is unusable */
+		down_write(&s->lock);
+		__invalidate_snapshot(s, -EIO);
+		error = 1;
+		goto out;
+	}
+
+	e = alloc_exception();
+	if (!e) {
+		down_write(&s->lock);
+		__invalidate_snapshot(s, -ENOMEM);
+		error = 1;
+		goto out;
+	}
+	*e = pe->e;
+
+	down_write(&s->lock);
+	if (!s->valid) {
+		free_exception(e);
+		error = 1;
+		goto out;
+	}
+
+	/*
+	 * Add a proper exception, and remove the
+	 * in-flight exception from the list.
+	 */
+	insert_exception(&s->complete, e);
+
+ out:
+	remove_exception(&pe->e);
+	snapshot_bios = bio_list_get(&pe->snapshot_bios);
+	origin_bios = put_pending_exception(pe);
+
+	up_write(&s->lock);
+
+	/* Submit any pending write bios */
+	if (error)
+		error_bios(snapshot_bios);
+	else
+		flush_bios(snapshot_bios);
+
+	flush_bios(origin_bios);
 }
 
 static void commit_callback(void *context, int success)
@@ -822,7 +838,7 @@
 	bio_list_init(&pe->origin_bios);
 	bio_list_init(&pe->snapshot_bios);
 	pe->primary_pe = NULL;
-	atomic_set(&pe->sibling_count, 1);
+	atomic_set(&pe->ref_count, 0);
 	pe->snap = s;
 	pe->started = 0;
 
@@ -831,6 +847,7 @@
 		return NULL;
 	}
 
+	get_pending_exception(pe);
 	insert_exception(&s->pending, &pe->e);
 
  out:
@@ -850,7 +867,6 @@
 {
 	struct exception *e;
 	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
-	int copy_needed = 0;
 	int r = 1;
 	chunk_t chunk;
 	struct pending_exception *pe = NULL;
@@ -865,32 +881,31 @@
 	if (unlikely(bio_barrier(bio)))
 		return -EOPNOTSUPP;
 
+	/* FIXME: should only take write lock if we need
+	 * to copy an exception */
+	down_write(&s->lock);
+
+	if (!s->valid) {
+		r = -EIO;
+		goto out_unlock;
+	}
+
+	/* If the block is already remapped - use that, else remap it */
+	e = lookup_exception(&s->complete, chunk);
+	if (e) {
+		remap_exception(s, e, bio);
+		goto out_unlock;
+	}
+
 	/*
 	 * Write to snapshot - higher level takes care of RW/RO
 	 * flags so we should only get this if we are
 	 * writeable.
 	 */
 	if (bio_rw(bio) == WRITE) {
-
-		/* FIXME: should only take write lock if we need
-		 * to copy an exception */
-		down_write(&s->lock);
-
-		if (!s->valid) {
-			r = -EIO;
-			goto out_unlock;
-		}
-
-		/* If the block is already remapped - use that, else remap it */
-		e = lookup_exception(&s->complete, chunk);
-		if (e) {
-			remap_exception(s, e, bio);
-			goto out_unlock;
-		}
-
 		pe = __find_pending_exception(s, bio);
 		if (!pe) {
-			__invalidate_snapshot(s, pe, -ENOMEM);
+			__invalidate_snapshot(s, -ENOMEM);
 			r = -EIO;
 			goto out_unlock;
 		}
@@ -898,45 +913,27 @@
 		remap_exception(s, &pe->e, bio);
 		bio_list_add(&pe->snapshot_bios, bio);
 
+		r = 0;
+
 		if (!pe->started) {
 			/* this is protected by snap->lock */
 			pe->started = 1;
-			copy_needed = 1;
-		}
-
-		r = 0;
-
- out_unlock:
-		up_write(&s->lock);
-
-		if (copy_needed)
+			up_write(&s->lock);
 			start_copy(pe);
-	} else {
+			goto out;
+		}
+	} else
 		/*
 		 * FIXME: this read path scares me because we
 		 * always use the origin when we have a pending
 		 * exception.  However I can't think of a
 		 * situation where this is wrong - ejt.
 		 */
+		bio->bi_bdev = s->origin->bdev;
 
-		/* Do reads */
-		down_read(&s->lock);
-
-		if (!s->valid) {
-			up_read(&s->lock);
-			return -EIO;
-		}
-
-		/* See if it it has been remapped */
-		e = lookup_exception(&s->complete, chunk);
-		if (e)
-			remap_exception(s, e, bio);
-		else
-			bio->bi_bdev = s->origin->bdev;
-
-		up_read(&s->lock);
-	}
-
+ out_unlock:
+	up_write(&s->lock);
+ out:
 	return r;
 }
 
@@ -1025,7 +1022,7 @@
 		 * is already remapped in this snapshot
 		 * and trigger an exception if not.
 		 *
-		 * sibling_count is initialised to 1 so pending_complete()
+		 * ref_count is initialised to 1 so pending_complete()
 		 * won't destroy the primary_pe while we're inside this loop.
 		 */
 		e = lookup_exception(&snap->complete, chunk);
@@ -1034,7 +1031,7 @@
 
 		pe = __find_pending_exception(snap, bio);
 		if (!pe) {
-			__invalidate_snapshot(snap, pe, ENOMEM);
+			__invalidate_snapshot(snap, -ENOMEM);
 			goto next_snapshot;
 		}
 
@@ -1056,8 +1053,8 @@
 		}
 
 		if (!pe->primary_pe) {
-			atomic_inc(&primary_pe->sibling_count);
 			pe->primary_pe = primary_pe;
+			get_pending_exception(primary_pe);
 		}
 
 		if (!pe->started) {
@@ -1070,20 +1067,20 @@
 	}
 
 	if (!primary_pe)
-		goto out;
+		return r;
 
 	/*
 	 * If this is the first time we're processing this chunk and
-	 * sibling_count is now 1 it means all the pending exceptions
+	 * ref_count is now 1 it means all the pending exceptions
 	 * got completed while we were in the loop above, so it falls to
 	 * us here to remove the primary_pe and submit any origin_bios.
 	 */
 
-	if (first && atomic_dec_and_test(&primary_pe->sibling_count)) {
+	if (first && atomic_dec_and_test(&primary_pe->ref_count)) {
 		flush_bios(bio_list_get(&primary_pe->origin_bios));
 		free_pending_exception(primary_pe);
 		/* If we got here, pe_queue is necessarily empty. */
-		goto out;
+		return r;
 	}
 
 	/*
@@ -1092,7 +1089,6 @@
 	list_for_each_entry_safe(pe, next_pe, &pe_queue, list)
 		start_copy(pe);
 
- out:
 	return r;
 }
 
@@ -1205,7 +1201,7 @@
 
 static struct target_type origin_target = {
 	.name    = "snapshot-origin",
-	.version = {1, 4, 0},
+	.version = {1, 5, 0},
 	.module  = THIS_MODULE,
 	.ctr     = origin_ctr,
 	.dtr     = origin_dtr,
@@ -1216,7 +1212,7 @@
 
 static struct target_type snapshot_target = {
 	.name    = "snapshot",
-	.version = {1, 4, 0},
+	.version = {1, 5, 0},
 	.module  = THIS_MODULE,
 	.ctr     = snapshot_ctr,
 	.dtr     = snapshot_dtr,
@@ -1275,8 +1271,17 @@
 		goto bad5;
 	}
 
+	ksnapd = create_singlethread_workqueue("ksnapd");
+	if (!ksnapd) {
+		DMERR("Failed to create ksnapd workqueue.");
+		r = -ENOMEM;
+		goto bad6;
+	}
+
 	return 0;
 
+      bad6:
+	mempool_destroy(pending_pool);
       bad5:
 	kmem_cache_destroy(pending_cache);
       bad4:
@@ -1294,6 +1299,8 @@
 {
 	int r;
 
+	destroy_workqueue(ksnapd);
+
 	r = dm_unregister_target(&snapshot_target);
 	if (r)
 		DMERR("snapshot unregister failed %d", r);
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
index fdec1e2..15fa2ae 100644
--- a/drivers/md/dm-snap.h
+++ b/drivers/md/dm-snap.h
@@ -10,7 +10,9 @@
 #define DM_SNAPSHOT_H
 
 #include "dm.h"
+#include "dm-bio-list.h"
 #include <linux/blkdev.h>
+#include <linux/workqueue.h>
 
 struct exception_table {
 	uint32_t hash_mask;
@@ -112,10 +114,20 @@
 	struct exception_table pending;
 	struct exception_table complete;
 
+	/*
+	 * pe_lock protects all pending_exception operations and access
+	 * as well as the snapshot_bios list.
+	 */
+	spinlock_t pe_lock;
+
 	/* The on disk metadata handler */
 	struct exception_store store;
 
 	struct kcopyd_client *kcopyd_client;
+
+	/* Queue of snapshot writes for ksnapd to flush */
+	struct bio_list queued_bios;
+	struct work_struct queued_bios_work;
 };
 
 /*
@@ -128,10 +140,9 @@
  * Constructor and destructor for the default persistent
  * store.
  */
-int dm_create_persistent(struct exception_store *store, uint32_t chunk_size);
+int dm_create_persistent(struct exception_store *store);
 
-int dm_create_transient(struct exception_store *store,
-			struct dm_snapshot *s, int blocksize);
+int dm_create_transient(struct exception_store *store);
 
 /*
  * Return the number of sectors in the device.
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 75fe949..05befa9 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -522,56 +522,61 @@
 	return 0;
 }
 
+void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
+{
+	request_queue_t *q = bdev_get_queue(bdev);
+	struct io_restrictions *rs = &ti->limits;
+
+	/*
+	 * Combine the device limits low.
+	 *
+	 * FIXME: if we move an io_restriction struct
+	 *        into q this would just be a call to
+	 *        combine_restrictions_low()
+	 */
+	rs->max_sectors =
+		min_not_zero(rs->max_sectors, q->max_sectors);
+
+	/* FIXME: Device-Mapper on top of RAID-0 breaks because DM
+	 *        currently doesn't honor MD's merge_bvec_fn routine.
+	 *        In this case, we'll force DM to use PAGE_SIZE or
+	 *        smaller I/O, just to be safe. A better fix is in the
+	 *        works, but add this for the time being so it will at
+	 *        least operate correctly.
+	 */
+	if (q->merge_bvec_fn)
+		rs->max_sectors =
+			min_not_zero(rs->max_sectors,
+				     (unsigned int) (PAGE_SIZE >> 9));
+
+	rs->max_phys_segments =
+		min_not_zero(rs->max_phys_segments,
+			     q->max_phys_segments);
+
+	rs->max_hw_segments =
+		min_not_zero(rs->max_hw_segments, q->max_hw_segments);
+
+	rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
+
+	rs->max_segment_size =
+		min_not_zero(rs->max_segment_size, q->max_segment_size);
+
+	rs->seg_boundary_mask =
+		min_not_zero(rs->seg_boundary_mask,
+			     q->seg_boundary_mask);
+
+	rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
+}
+EXPORT_SYMBOL_GPL(dm_set_device_limits);
 
 int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
 		  sector_t len, int mode, struct dm_dev **result)
 {
 	int r = __table_get_device(ti->table, ti, path,
 				   start, len, mode, result);
-	if (!r) {
-		request_queue_t *q = bdev_get_queue((*result)->bdev);
-		struct io_restrictions *rs = &ti->limits;
 
-		/*
-		 * Combine the device limits low.
-		 *
-		 * FIXME: if we move an io_restriction struct
-		 *        into q this would just be a call to
-		 *        combine_restrictions_low()
-		 */
-		rs->max_sectors =
-			min_not_zero(rs->max_sectors, q->max_sectors);
-
-		/* FIXME: Device-Mapper on top of RAID-0 breaks because DM
-		 *        currently doesn't honor MD's merge_bvec_fn routine.
-		 *        In this case, we'll force DM to use PAGE_SIZE or
-		 *        smaller I/O, just to be safe. A better fix is in the
-		 *        works, but add this for the time being so it will at
-		 *        least operate correctly.
-		 */
-		if (q->merge_bvec_fn)
-			rs->max_sectors =
-				min_not_zero(rs->max_sectors,
-					     (unsigned int) (PAGE_SIZE >> 9));
-
-		rs->max_phys_segments =
-			min_not_zero(rs->max_phys_segments,
-				     q->max_phys_segments);
-
-		rs->max_hw_segments =
-			min_not_zero(rs->max_hw_segments, q->max_hw_segments);
-
-		rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
-
-		rs->max_segment_size =
-			min_not_zero(rs->max_segment_size, q->max_segment_size);
-
-		rs->seg_boundary_mask =
-			min_not_zero(rs->seg_boundary_mask,
-				     q->seg_boundary_mask);
-
-		rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
-	}
+	if (!r)
+		dm_set_device_limits(ti, (*result)->bdev);
 
 	return r;
 }
@@ -939,9 +944,20 @@
 	return suspend_targets(t, 1);
 }
 
-void dm_table_resume_targets(struct dm_table *t)
+int dm_table_resume_targets(struct dm_table *t)
 {
-	int i;
+	int i, r = 0;
+
+	for (i = 0; i < t->num_targets; i++) {
+		struct dm_target *ti = t->targets + i;
+
+		if (!ti->type->preresume)
+			continue;
+
+		r = ti->type->preresume(ti);
+		if (r)
+			return r;
+	}
 
 	for (i = 0; i < t->num_targets; i++) {
 		struct dm_target *ti = t->targets + i;
@@ -949,6 +965,8 @@
 		if (ti->type->resume)
 			ti->type->resume(ti);
 	}
+
+	return 0;
 }
 
 int dm_table_any_congested(struct dm_table *t, int bdi_bits)
@@ -983,6 +1001,11 @@
 {
 	struct list_head *d, *devices = dm_table_get_devices(t);
 	int ret = 0;
+	unsigned i;
+
+	for (i = 0; i < t->num_targets; i++)
+		if (t->targets[i].type->flush)
+			t->targets[i].type->flush(&t->targets[i]);
 
 	for (d = devices->next; d != devices; d = d->next) {
 		struct dm_dev *dd = list_entry(d, struct dm_dev, list);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index c99bf9f..b5764a8 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -20,6 +20,7 @@
 #include <linux/idr.h>
 #include <linux/hdreg.h>
 #include <linux/blktrace_api.h>
+#include <linux/smp_lock.h>
 
 #define DM_MSG_PREFIX "core"
 
@@ -101,6 +102,8 @@
 	mempool_t *io_pool;
 	mempool_t *tio_pool;
 
+	struct bio_set *bs;
+
 	/*
 	 * Event handling.
 	 */
@@ -121,16 +124,10 @@
 static kmem_cache_t *_io_cache;
 static kmem_cache_t *_tio_cache;
 
-static struct bio_set *dm_set;
-
 static int __init local_init(void)
 {
 	int r;
 
-	dm_set = bioset_create(16, 16, 4);
-	if (!dm_set)
-		return -ENOMEM;
-
 	/* allocate a slab for the dm_ios */
 	_io_cache = kmem_cache_create("dm_io",
 				      sizeof(struct dm_io), 0, 0, NULL, NULL);
@@ -164,8 +161,6 @@
 	kmem_cache_destroy(_tio_cache);
 	kmem_cache_destroy(_io_cache);
 
-	bioset_free(dm_set);
-
 	if (unregister_blkdev(_major, _name) < 0)
 		DMERR("unregister_blkdev failed");
 
@@ -288,6 +283,45 @@
 	return dm_get_geometry(md, geo);
 }
 
+static int dm_blk_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	struct mapped_device *md;
+	struct dm_table *map;
+	struct dm_target *tgt;
+	int r = -ENOTTY;
+
+	/* We don't really need this lock, but we do need 'inode'. */
+	unlock_kernel();
+
+	md = inode->i_bdev->bd_disk->private_data;
+
+	map = dm_get_table(md);
+
+	if (!map || !dm_table_get_size(map))
+		goto out;
+
+	/* We only support devices that have a single target */
+	if (dm_table_get_num_targets(map) != 1)
+		goto out;
+
+	tgt = dm_table_get_target(map, 0);
+
+	if (dm_suspended(md)) {
+		r = -EAGAIN;
+		goto out;
+	}
+
+	if (tgt->type->ioctl)
+		r = tgt->type->ioctl(tgt, inode, file, cmd, arg);
+
+out:
+	dm_table_put(map);
+
+	lock_kernel();
+	return r;
+}
+
 static inline struct dm_io *alloc_io(struct mapped_device *md)
 {
 	return mempool_alloc(md->io_pool, GFP_NOIO);
@@ -435,7 +469,7 @@
 {
 	int r = 0;
 	struct target_io *tio = bio->bi_private;
-	struct dm_io *io = tio->io;
+	struct mapped_device *md = tio->io->md;
 	dm_endio_fn endio = tio->ti->type->end_io;
 
 	if (bio->bi_size)
@@ -454,9 +488,15 @@
 			return 1;
 	}
 
-	free_tio(io->md, tio);
-	dec_pending(io, error);
+	dec_pending(tio->io, error);
+
+	/*
+	 * Store md for cleanup instead of tio which is about to get freed.
+	 */
+	bio->bi_private = md->bs;
+
 	bio_put(bio);
+	free_tio(md, tio);
 	return r;
 }
 
@@ -485,6 +525,7 @@
 {
 	int r;
 	sector_t sector;
+	struct mapped_device *md;
 
 	/*
 	 * Sanity checks.
@@ -514,10 +555,14 @@
 
 	else if (r < 0) {
 		/* error the io and bail out */
-		struct dm_io *io = tio->io;
-		free_tio(tio->io->md, tio);
-		dec_pending(io, r);
+		md = tio->io->md;
+		dec_pending(tio->io, r);
+		/*
+		 * Store bio_set for cleanup.
+		 */
+		clone->bi_private = md->bs;
 		bio_put(clone);
+		free_tio(md, tio);
 	}
 }
 
@@ -533,7 +578,9 @@
 
 static void dm_bio_destructor(struct bio *bio)
 {
-	bio_free(bio, dm_set);
+	struct bio_set *bs = bio->bi_private;
+
+	bio_free(bio, bs);
 }
 
 /*
@@ -541,12 +588,12 @@
  */
 static struct bio *split_bvec(struct bio *bio, sector_t sector,
 			      unsigned short idx, unsigned int offset,
-			      unsigned int len)
+			      unsigned int len, struct bio_set *bs)
 {
 	struct bio *clone;
 	struct bio_vec *bv = bio->bi_io_vec + idx;
 
-	clone = bio_alloc_bioset(GFP_NOIO, 1, dm_set);
+	clone = bio_alloc_bioset(GFP_NOIO, 1, bs);
 	clone->bi_destructor = dm_bio_destructor;
 	*clone->bi_io_vec = *bv;
 
@@ -566,11 +613,13 @@
  */
 static struct bio *clone_bio(struct bio *bio, sector_t sector,
 			     unsigned short idx, unsigned short bv_count,
-			     unsigned int len)
+			     unsigned int len, struct bio_set *bs)
 {
 	struct bio *clone;
 
-	clone = bio_clone(bio, GFP_NOIO);
+	clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
+	__bio_clone(clone, bio);
+	clone->bi_destructor = dm_bio_destructor;
 	clone->bi_sector = sector;
 	clone->bi_idx = idx;
 	clone->bi_vcnt = idx + bv_count;
@@ -601,7 +650,8 @@
 		 * the remaining io with a single clone.
 		 */
 		clone = clone_bio(bio, ci->sector, ci->idx,
-				  bio->bi_vcnt - ci->idx, ci->sector_count);
+				  bio->bi_vcnt - ci->idx, ci->sector_count,
+				  ci->md->bs);
 		__map_bio(ti, clone, tio);
 		ci->sector_count = 0;
 
@@ -624,7 +674,8 @@
 			len += bv_len;
 		}
 
-		clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len);
+		clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len,
+				  ci->md->bs);
 		__map_bio(ti, clone, tio);
 
 		ci->sector += len;
@@ -653,7 +704,8 @@
 			len = min(remaining, max);
 
 			clone = split_bvec(bio, ci->sector, ci->idx,
-					   bv->bv_offset + offset, len);
+					   bv->bv_offset + offset, len,
+					   ci->md->bs);
 
 			__map_bio(ti, clone, tio);
 
@@ -903,7 +955,7 @@
 
 	md->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!md->queue)
-		goto bad1;
+		goto bad1_free_minor;
 
 	md->queue->queuedata = md;
 	md->queue->backing_dev_info.congested_fn = dm_any_congested;
@@ -921,6 +973,10 @@
 	if (!md->tio_pool)
 		goto bad3;
 
+	md->bs = bioset_create(16, 16, 4);
+	if (!md->bs)
+		goto bad_no_bioset;
+
 	md->disk = alloc_disk(1);
 	if (!md->disk)
 		goto bad4;
@@ -948,11 +1004,14 @@
 	return md;
 
  bad4:
+	bioset_free(md->bs);
+ bad_no_bioset:
 	mempool_destroy(md->tio_pool);
  bad3:
 	mempool_destroy(md->io_pool);
  bad2:
 	blk_cleanup_queue(md->queue);
+ bad1_free_minor:
 	free_minor(minor);
  bad1:
 	module_put(THIS_MODULE);
@@ -971,6 +1030,7 @@
 	}
 	mempool_destroy(md->tio_pool);
 	mempool_destroy(md->io_pool);
+	bioset_free(md->bs);
 	del_gendisk(md->disk);
 	free_minor(minor);
 
@@ -1319,7 +1379,9 @@
 	if (!map || !dm_table_get_size(map))
 		goto out;
 
-	dm_table_resume_targets(map);
+	r = dm_table_resume_targets(map);
+	if (r)
+		goto out;
 
 	down_write(&md->io_lock);
 	clear_bit(DMF_BLOCK_IO, &md->flags);
@@ -1337,6 +1399,8 @@
 
 	dm_table_unplug_all(map);
 
+	kobject_uevent(&md->disk->kobj, KOBJ_CHANGE);
+
 	r = 0;
 
 out:
@@ -1377,6 +1441,7 @@
 static struct block_device_operations dm_blk_dops = {
 	.open = dm_blk_open,
 	.release = dm_blk_close,
+	.ioctl = dm_blk_ioctl,
 	.getgeo = dm_blk_getgeo,
 	.owner = THIS_MODULE
 };
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 3c03c0e..a48ec5e 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -21,6 +21,11 @@
 #define DMERR(f, arg...) printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMWARN(f, arg...) printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMINFO(f, arg...) printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#ifdef CONFIG_DM_DEBUG
+#  define DMDEBUG(f, arg...) printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
+#else
+#  define DMDEBUG(f, arg...) do {} while (0)
+#endif
 
 #define DMEMIT(x...) sz += ((sz >= maxlen) ? \
 			  0 : scnprintf(result + sz, maxlen - sz, x))
@@ -52,7 +57,7 @@
 struct list_head *dm_table_get_devices(struct dm_table *t);
 void dm_table_presuspend_targets(struct dm_table *t);
 void dm_table_postsuspend_targets(struct dm_table *t);
-void dm_table_resume_targets(struct dm_table *t);
+int dm_table_resume_targets(struct dm_table *t);
 int dm_table_any_congested(struct dm_table *t, int bdi_bits);
 void dm_table_unplug_all(struct dm_table *t);
 int dm_table_flush_all(struct dm_table *t);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b99c19c..c625ddb 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -111,6 +111,19 @@
 	return ret;
 }
 
+static int linear_congested(void *data, int bits)
+{
+	mddev_t *mddev = data;
+	linear_conf_t *conf = mddev_to_conf(mddev);
+	int i, ret = 0;
+
+	for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+		request_queue_t *q = bdev_get_queue(conf->disks[i].rdev->bdev);
+		ret |= bdi_congested(&q->backing_dev_info, bits);
+	}
+	return ret;
+}
+
 static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
 {
 	linear_conf_t *conf;
@@ -269,6 +282,8 @@
 	blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
 	mddev->queue->unplug_fn = linear_unplug;
 	mddev->queue->issue_flush_fn = linear_issue_flush;
+	mddev->queue->backing_dev_info.congested_fn = linear_congested;
+	mddev->queue->backing_dev_info.congested_data = mddev;
 	return 0;
 }
 
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 8dbab2e..cb82816 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -389,8 +389,12 @@
 	if (bio->bi_size)
 		return 1;
 
-	if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
+	if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+		printk("md: super_written gets error=%d, uptodate=%d\n",
+		       error, test_bit(BIO_UPTODATE, &bio->bi_flags));
+		WARN_ON(test_bit(BIO_UPTODATE, &bio->bi_flags));
 		md_error(mddev, rdev);
+	}
 
 	if (atomic_dec_and_test(&mddev->pending_writes))
 		wake_up(&mddev->sb_wait);
@@ -1587,7 +1591,7 @@
 	}
 }
 
-void md_update_sb(mddev_t * mddev)
+static void md_update_sb(mddev_t * mddev, int force_change)
 {
 	int err;
 	struct list_head *tmp;
@@ -1598,7 +1602,18 @@
 repeat:
 	spin_lock_irq(&mddev->write_lock);
 
-	if (mddev->degraded && mddev->sb_dirty == 3)
+	set_bit(MD_CHANGE_PENDING, &mddev->flags);
+	if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
+		force_change = 1;
+	if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags))
+		/* just a clean<-> dirty transition, possibly leave spares alone,
+		 * though if events isn't the right even/odd, we will have to do
+		 * spares after all
+		 */
+		nospares = 1;
+	if (force_change)
+		nospares = 0;
+	if (mddev->degraded)
 		/* If the array is degraded, then skipping spares is both
 		 * dangerous and fairly pointless.
 		 * Dangerous because a device that was removed from the array
@@ -1608,20 +1623,14 @@
 		 * then a recovery will happen and soon that array won't
 		 * be degraded any more and the spare can go back to sleep then.
 		 */
-		mddev->sb_dirty = 1;
+		nospares = 0;
 
 	sync_req = mddev->in_sync;
 	mddev->utime = get_seconds();
-	if (mddev->sb_dirty == 3)
-		/* just a clean<-> dirty transition, possibly leave spares alone,
-		 * though if events isn't the right even/odd, we will have to do
-		 * spares after all
-		 */
-		nospares = 1;
 
 	/* If this is just a dirty<->clean transition, and the array is clean
 	 * and 'events' is odd, we can roll back to the previous clean state */
-	if (mddev->sb_dirty == 3
+	if (nospares
 	    && (mddev->in_sync && mddev->recovery_cp == MaxSector)
 	    && (mddev->events & 1))
 		mddev->events--;
@@ -1652,7 +1661,6 @@
 		MD_BUG();
 		mddev->events --;
 	}
-	mddev->sb_dirty = 2;
 	sync_sbs(mddev, nospares);
 
 	/*
@@ -1660,7 +1668,7 @@
 	 * nonpersistent superblocks
 	 */
 	if (!mddev->persistent) {
-		mddev->sb_dirty = 0;
+		clear_bit(MD_CHANGE_PENDING, &mddev->flags);
 		spin_unlock_irq(&mddev->write_lock);
 		wake_up(&mddev->sb_wait);
 		return;
@@ -1697,20 +1705,20 @@
 			break;
 	}
 	md_super_wait(mddev);
-	/* if there was a failure, sb_dirty was set to 1, and we re-write super */
+	/* if there was a failure, MD_CHANGE_DEVS was set, and we re-write super */
 
 	spin_lock_irq(&mddev->write_lock);
-	if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
+	if (mddev->in_sync != sync_req ||
+	    test_bit(MD_CHANGE_DEVS, &mddev->flags)) {
 		/* have to write it out again */
 		spin_unlock_irq(&mddev->write_lock);
 		goto repeat;
 	}
-	mddev->sb_dirty = 0;
+	clear_bit(MD_CHANGE_PENDING, &mddev->flags);
 	spin_unlock_irq(&mddev->write_lock);
 	wake_up(&mddev->sb_wait);
 
 }
-EXPORT_SYMBOL_GPL(md_update_sb);
 
 /* words written to sysfs files may, or my not, be \n terminated.
  * We want to accept with case. For this we use cmd_match.
@@ -1783,7 +1791,7 @@
 		else {
 			mddev_t *mddev = rdev->mddev;
 			kick_rdev_from_array(rdev);
-			md_update_sb(mddev);
+			md_update_sb(mddev, 1);
 			md_new_event(mddev);
 			err = 0;
 		}
@@ -2426,7 +2434,7 @@
 			spin_lock_irq(&mddev->write_lock);
 			if (atomic_read(&mddev->writes_pending) == 0) {
 				mddev->in_sync = 1;
-				mddev->sb_dirty = 1;
+				set_bit(MD_CHANGE_CLEAN, &mddev->flags);
 			}
 			spin_unlock_irq(&mddev->write_lock);
 		} else {
@@ -2438,7 +2446,7 @@
 	case active:
 		if (mddev->pers) {
 			restart_array(mddev);
-			mddev->sb_dirty = 0;
+			clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
 			wake_up(&mddev->sb_wait);
 			err = 0;
 		} else {
@@ -2520,6 +2528,36 @@
 __ATTR(new_dev, S_IWUSR, null_show, new_dev_store);
 
 static ssize_t
+bitmap_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	char *end;
+	unsigned long chunk, end_chunk;
+
+	if (!mddev->bitmap)
+		goto out;
+	/* buf should be <chunk> <chunk> ... or <chunk>-<chunk> ... (range) */
+	while (*buf) {
+		chunk = end_chunk = simple_strtoul(buf, &end, 0);
+		if (buf == end) break;
+		if (*end == '-') { /* range */
+			buf = end + 1;
+			end_chunk = simple_strtoul(buf, &end, 0);
+			if (buf == end) break;
+		}
+		if (*end && !isspace(*end)) break;
+		bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk);
+		buf = end;
+		while (isspace(*buf)) buf++;
+	}
+	bitmap_unplug(mddev->bitmap); /* flush the bits to disk */
+out:
+	return len;
+}
+
+static struct md_sysfs_entry md_bitmap =
+__ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store);
+
+static ssize_t
 size_show(mddev_t *mddev, char *page)
 {
 	return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
@@ -2543,7 +2581,7 @@
 
 	if (mddev->pers) {
 		err = update_size(mddev, size);
-		md_update_sb(mddev);
+		md_update_sb(mddev, 1);
 	} else {
 		if (mddev->size == 0 ||
 		    mddev->size > size)
@@ -2839,6 +2877,7 @@
 	&md_sync_completed.attr,
 	&md_suspend_lo.attr,
 	&md_suspend_hi.attr,
+	&md_bitmap.attr,
 	NULL,
 };
 static struct attribute_group md_redundancy_group = {
@@ -3111,8 +3150,8 @@
 	
 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	
-	if (mddev->sb_dirty)
-		md_update_sb(mddev);
+	if (mddev->flags)
+		md_update_sb(mddev, 0);
 
 	set_capacity(disk, mddev->array_size<<1);
 
@@ -3275,10 +3314,10 @@
 			if (mddev->ro)
 				mddev->ro = 0;
 		}
-		if (!mddev->in_sync || mddev->sb_dirty) {
+		if (!mddev->in_sync || mddev->flags) {
 			/* mark array as shutdown cleanly */
 			mddev->in_sync = 1;
-			md_update_sb(mddev);
+			md_update_sb(mddev, 1);
 		}
 		if (mode == 1)
 			set_disk_ro(disk, 1);
@@ -3374,6 +3413,7 @@
 
 	printk(KERN_INFO "md: autorun ...\n");
 	while (!list_empty(&pending_raid_disks)) {
+		int unit;
 		dev_t dev;
 		LIST_HEAD(candidates);
 		rdev0 = list_entry(pending_raid_disks.next,
@@ -3393,16 +3433,19 @@
 		 * mostly sane superblocks. It's time to allocate the
 		 * mddev.
 		 */
-		if (rdev0->preferred_minor < 0 || rdev0->preferred_minor >= MAX_MD_DEVS) {
+		if (part) {
+			dev = MKDEV(mdp_major,
+				    rdev0->preferred_minor << MdpMinorShift);
+			unit = MINOR(dev) >> MdpMinorShift;
+		} else {
+			dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
+			unit = MINOR(dev);
+		}
+		if (rdev0->preferred_minor != unit) {
 			printk(KERN_INFO "md: unit number in %s is bad: %d\n",
 			       bdevname(rdev0->bdev, b), rdev0->preferred_minor);
 			break;
 		}
-		if (part)
-			dev = MKDEV(mdp_major,
-				    rdev0->preferred_minor << MdpMinorShift);
-		else
-			dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
 
 		md_probe(dev, NULL, NULL);
 		mddev = mddev_find(dev);
@@ -3440,67 +3483,6 @@
 	printk(KERN_INFO "md: ... autorun DONE.\n");
 }
 
-/*
- * import RAID devices based on one partition
- * if possible, the array gets run as well.
- */
-
-static int autostart_array(dev_t startdev)
-{
-	char b[BDEVNAME_SIZE];
-	int err = -EINVAL, i;
-	mdp_super_t *sb = NULL;
-	mdk_rdev_t *start_rdev = NULL, *rdev;
-
-	start_rdev = md_import_device(startdev, 0, 0);
-	if (IS_ERR(start_rdev))
-		return err;
-
-
-	/* NOTE: this can only work for 0.90.0 superblocks */
-	sb = (mdp_super_t*)page_address(start_rdev->sb_page);
-	if (sb->major_version != 0 ||
-	    sb->minor_version != 90 ) {
-		printk(KERN_WARNING "md: can only autostart 0.90.0 arrays\n");
-		export_rdev(start_rdev);
-		return err;
-	}
-
-	if (test_bit(Faulty, &start_rdev->flags)) {
-		printk(KERN_WARNING 
-			"md: can not autostart based on faulty %s!\n",
-			bdevname(start_rdev->bdev,b));
-		export_rdev(start_rdev);
-		return err;
-	}
-	list_add(&start_rdev->same_set, &pending_raid_disks);
-
-	for (i = 0; i < MD_SB_DISKS; i++) {
-		mdp_disk_t *desc = sb->disks + i;
-		dev_t dev = MKDEV(desc->major, desc->minor);
-
-		if (!dev)
-			continue;
-		if (dev == startdev)
-			continue;
-		if (MAJOR(dev) != desc->major || MINOR(dev) != desc->minor)
-			continue;
-		rdev = md_import_device(dev, 0, 0);
-		if (IS_ERR(rdev))
-			continue;
-
-		list_add(&rdev->same_set, &pending_raid_disks);
-	}
-
-	/*
-	 * possibly return codes
-	 */
-	autorun_devices(0);
-	return 0;
-
-}
-
-
 static int get_version(void __user * arg)
 {
 	mdu_version_t ver;
@@ -3808,7 +3790,7 @@
 		goto busy;
 
 	kick_rdev_from_array(rdev);
-	md_update_sb(mddev);
+	md_update_sb(mddev, 1);
 	md_new_event(mddev);
 
 	return 0;
@@ -3885,7 +3867,7 @@
 
 	rdev->raid_disk = -1;
 
-	md_update_sb(mddev);
+	md_update_sb(mddev, 1);
 
 	/*
 	 * Kick recovery, maybe this spare has to be added to the
@@ -4016,7 +3998,8 @@
 
 	mddev->max_disks     = MD_SB_DISKS;
 
-	mddev->sb_dirty      = 1;
+	mddev->flags         = 0;
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
 	mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
 	mddev->bitmap_offset = 0;
@@ -4185,7 +4168,7 @@
 			mddev->bitmap_offset = 0;
 		}
 	}
-	md_update_sb(mddev);
+	md_update_sb(mddev, 1);
 	return rv;
 }
 
@@ -4259,27 +4242,6 @@
 		goto abort;
 	}
 
-
-	if (cmd == START_ARRAY) {
-		/* START_ARRAY doesn't need to lock the array as autostart_array
-		 * does the locking, and it could even be a different array
-		 */
-		static int cnt = 3;
-		if (cnt > 0 ) {
-			printk(KERN_WARNING
-			       "md: %s(pid %d) used deprecated START_ARRAY ioctl. "
-			       "This will not be supported beyond July 2006\n",
-			       current->comm, current->pid);
-			cnt--;
-		}
-		err = autostart_array(new_decode_dev(arg));
-		if (err) {
-			printk(KERN_WARNING "md: autostart failed!\n");
-			goto abort;
-		}
-		goto done;
-	}
-
 	err = mddev_lock(mddev);
 	if (err) {
 		printk(KERN_INFO 
@@ -4476,8 +4438,7 @@
 {
  	mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
 
-	if (!mddev)
-		BUG();
+	BUG_ON(!mddev);
 	mddev_put(mddev);
 
 	return 0;
@@ -4687,9 +4648,11 @@
 	seq_printf(seq, " %s =%3u.%u%% (%llu/%llu)",
 		   (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)?
 		    "reshape" :
-		      (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
-		       "resync" : "recovery")),
-		      per_milli/10, per_milli % 10,
+		    (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)?
+		     "check" :
+		     (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
+		      "resync" : "recovery"))),
+		   per_milli/10, per_milli % 10,
 		   (unsigned long long) resync,
 		   (unsigned long long) max_blocks);
 
@@ -5042,12 +5005,12 @@
 		spin_lock_irq(&mddev->write_lock);
 		if (mddev->in_sync) {
 			mddev->in_sync = 0;
-			mddev->sb_dirty = 3;
+			set_bit(MD_CHANGE_CLEAN, &mddev->flags);
 			md_wakeup_thread(mddev->thread);
 		}
 		spin_unlock_irq(&mddev->write_lock);
 	}
-	wait_event(mddev->sb_wait, mddev->sb_dirty==0);
+	wait_event(mddev->sb_wait, mddev->flags==0);
 }
 
 void md_write_end(mddev_t *mddev)
@@ -5078,6 +5041,7 @@
 	int skipped = 0;
 	struct list_head *rtmp;
 	mdk_rdev_t *rdev;
+	char *desc;
 
 	/* just incase thread restarts... */
 	if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
@@ -5085,6 +5049,18 @@
 	if (mddev->ro) /* never try to sync a read-only array */
 		return;
 
+	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
+		if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
+			desc = "data-check";
+		else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+			desc = "requested-resync";
+		else
+			desc = "resync";
+	} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
+		desc = "reshape";
+	else
+		desc = "recovery";
+
 	/* we overload curr_resync somewhat here.
 	 * 0 == not engaged in resync at all
 	 * 2 == checking that there is no conflict with another sync
@@ -5128,10 +5104,10 @@
 				prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
 				if (!kthread_should_stop() &&
 				    mddev2->curr_resync >= mddev->curr_resync) {
-					printk(KERN_INFO "md: delaying resync of %s"
-					       " until %s has finished resync (they"
+					printk(KERN_INFO "md: delaying %s of %s"
+					       " until %s has finished (they"
 					       " share one or more physical units)\n",
-					       mdname(mddev), mdname(mddev2));
+					       desc, mdname(mddev), mdname(mddev2));
 					mddev_put(mddev2);
 					schedule();
 					finish_wait(&resync_wait, &wq);
@@ -5167,12 +5143,12 @@
 				j = rdev->recovery_offset;
 	}
 
-	printk(KERN_INFO "md: syncing RAID array %s\n", mdname(mddev));
-	printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:"
-		" %d KB/sec/disc.\n", speed_min(mddev));
+	printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
+	printk(KERN_INFO "md: minimum _guaranteed_  speed:"
+		" %d KB/sec/disk.\n", speed_min(mddev));
 	printk(KERN_INFO "md: using maximum available idle IO bandwidth "
-	       "(but not more than %d KB/sec) for reconstruction.\n",
-	       speed_max(mddev));
+	       "(but not more than %d KB/sec) for %s.\n",
+	       speed_max(mddev), desc);
 
 	is_mddev_idle(mddev); /* this also initializes IO event counters */
 
@@ -5198,8 +5174,8 @@
 
 	if (j>2) {
 		printk(KERN_INFO 
-			"md: resuming recovery of %s from checkpoint.\n",
-			mdname(mddev));
+		       "md: resuming %s of %s from checkpoint.\n",
+		       desc, mdname(mddev));
 		mddev->curr_resync = j;
 	}
 
@@ -5282,7 +5258,7 @@
 			}
 		}
 	}
-	printk(KERN_INFO "md: %s: sync done.\n",mdname(mddev));
+	printk(KERN_INFO "md: %s: %s done.\n",mdname(mddev), desc);
 	/*
 	 * this also signals 'finished resyncing' to md_stop
 	 */
@@ -5302,8 +5278,8 @@
 			if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
 				if (mddev->curr_resync >= mddev->recovery_cp) {
 					printk(KERN_INFO
-					       "md: checkpointing recovery of %s.\n",
-					       mdname(mddev));
+					       "md: checkpointing %s of %s.\n",
+					       desc, mdname(mddev));
 					mddev->recovery_cp = mddev->curr_resync;
 				}
 			} else
@@ -5317,7 +5293,6 @@
 				    !test_bit(In_sync, &rdev->flags) &&
 				    rdev->recovery_offset < mddev->curr_resync)
 					rdev->recovery_offset = mddev->curr_resync;
-			mddev->sb_dirty = 1;
 		}
 	}
 
@@ -5374,7 +5349,7 @@
 	}
 
 	if ( ! (
-		mddev->sb_dirty ||
+		mddev->flags ||
 		test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
 		test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
 		(mddev->safemode == 1) ||
@@ -5390,14 +5365,14 @@
 		if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
 		    !mddev->in_sync && mddev->recovery_cp == MaxSector) {
 			mddev->in_sync = 1;
-			mddev->sb_dirty = 3;
+			set_bit(MD_CHANGE_CLEAN, &mddev->flags);
 		}
 		if (mddev->safemode == 1)
 			mddev->safemode = 0;
 		spin_unlock_irq(&mddev->write_lock);
 
-		if (mddev->sb_dirty)
-			md_update_sb(mddev);
+		if (mddev->flags)
+			md_update_sb(mddev, 0);
 
 
 		if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
@@ -5416,7 +5391,7 @@
 				/* activate any spares */
 				mddev->pers->spare_active(mddev);
 			}
-			md_update_sb(mddev);
+			md_update_sb(mddev, 1);
 
 			/* if array is no-longer degraded, then any saved_raid_disk
 			 * information must be scrapped
@@ -5556,22 +5531,15 @@
 
 static int __init md_init(void)
 {
-	printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d,"
-			" MD_SB_DISKS=%d\n",
-			MD_MAJOR_VERSION, MD_MINOR_VERSION,
-			MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
-	printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
-			BITMAP_MINOR);
-
 	if (register_blkdev(MAJOR_NR, "md"))
 		return -1;
 	if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
 		unregister_blkdev(MAJOR_NR, "md");
 		return -1;
 	}
-	blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE,
-				md_probe, NULL, NULL);
-	blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE,
+	blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+			    md_probe, NULL, NULL);
+	blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
 			    md_probe, NULL, NULL);
 
 	register_reboot_notifier(&md_notifier);
@@ -5630,8 +5598,8 @@
 	mddev_t *mddev;
 	struct list_head *tmp;
 
-	blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS);
-	blk_unregister_region(MKDEV(mdp_major,0), MAX_MD_DEVS << MdpMinorShift);
+	blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+	blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
 
 	unregister_blkdev(MAJOR_NR,"md");
 	unregister_blkdev(mdp_major, "mdp");
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 1cc9de4..171ff41 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -228,6 +228,28 @@
 	rcu_read_unlock();
 	return ret;
 }
+static int multipath_congested(void *data, int bits)
+{
+	mddev_t *mddev = data;
+	multipath_conf_t *conf = mddev_to_conf(mddev);
+	int i, ret = 0;
+
+	rcu_read_lock();
+	for (i = 0; i < mddev->raid_disks ; i++) {
+		mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
+		if (rdev && !test_bit(Faulty, &rdev->flags)) {
+			request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+			ret |= bdi_congested(&q->backing_dev_info, bits);
+			/* Just like multipath_map, we just check the
+			 * first available device
+			 */
+			break;
+		}
+	}
+	rcu_read_unlock();
+	return ret;
+}
 
 /*
  * Careful, this can execute in IRQ contexts as well!
@@ -253,7 +275,7 @@
 			char b[BDEVNAME_SIZE];
 			clear_bit(In_sync, &rdev->flags);
 			set_bit(Faulty, &rdev->flags);
-			mddev->sb_dirty = 1;
+			set_bit(MD_CHANGE_DEVS, &mddev->flags);
 			conf->working_disks--;
 			printk(KERN_ALERT "multipath: IO failure on %s,"
 				" disabling IO path. \n	Operation continuing"
@@ -470,7 +492,6 @@
 	}
 
 	conf->raid_disks = mddev->raid_disks;
-	mddev->sb_dirty = 1;
 	conf->mddev = mddev;
 	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
@@ -510,6 +531,8 @@
 
 	mddev->queue->unplug_fn = multipath_unplug;
 	mddev->queue->issue_flush_fn = multipath_issue_flush;
+	mddev->queue->backing_dev_info.congested_fn = multipath_congested;
+	mddev->queue->backing_dev_info.congested_data = mddev;
 
 	return 0;
 
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index cb8c631..dfe3214 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -60,6 +60,21 @@
 	return ret;
 }
 
+static int raid0_congested(void *data, int bits)
+{
+	mddev_t *mddev = data;
+	raid0_conf_t *conf = mddev_to_conf(mddev);
+	mdk_rdev_t **devlist = conf->strip_zone[0].dev;
+	int i, ret = 0;
+
+	for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+		request_queue_t *q = bdev_get_queue(devlist[i]->bdev);
+
+		ret |= bdi_congested(&q->backing_dev_info, bits);
+	}
+	return ret;
+}
+
 
 static int create_strip_zones (mddev_t *mddev)
 {
@@ -236,6 +251,8 @@
 	mddev->queue->unplug_fn = raid0_unplug;
 
 	mddev->queue->issue_flush_fn = raid0_issue_flush;
+	mddev->queue->backing_dev_info.congested_fn = raid0_congested;
+	mddev->queue->backing_dev_info.congested_data = mddev;
 
 	printk("raid0: done.\n");
 	return 0;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3b4d69c..dc9d2de 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -271,7 +271,7 @@
 	 */
 	update_head_pos(mirror, r1_bio);
 
-	if (uptodate || conf->working_disks <= 1) {
+	if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) {
 		/*
 		 * Set R1BIO_Uptodate in our master bio, so that
 		 * we will return a good error code for to the higher
@@ -601,6 +601,32 @@
 	return ret;
 }
 
+static int raid1_congested(void *data, int bits)
+{
+	mddev_t *mddev = data;
+	conf_t *conf = mddev_to_conf(mddev);
+	int i, ret = 0;
+
+	rcu_read_lock();
+	for (i = 0; i < mddev->raid_disks; i++) {
+		mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+		if (rdev && !test_bit(Faulty, &rdev->flags)) {
+			request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+			/* Note the '|| 1' - when read_balance prefers
+			 * non-congested targets, it can be removed
+			 */
+			if ((bits & (1<<BDI_write_congested)) || 1)
+				ret |= bdi_congested(&q->backing_dev_info, bits);
+			else
+				ret &= bdi_congested(&q->backing_dev_info, bits);
+		}
+	}
+	rcu_read_unlock();
+	return ret;
+}
+
+
 /* Barriers....
  * Sometimes we need to suspend IO while we do something else,
  * either some resync/recovery, or reconfigure the array.
@@ -929,7 +955,7 @@
 	int i;
 
 	seq_printf(seq, " [%d/%d] [", conf->raid_disks,
-						conf->working_disks);
+		   conf->raid_disks - mddev->degraded);
 	rcu_read_lock();
 	for (i = 0; i < conf->raid_disks; i++) {
 		mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
@@ -953,26 +979,27 @@
 	 * else mark the drive as failed
 	 */
 	if (test_bit(In_sync, &rdev->flags)
-	    && conf->working_disks == 1)
+	    && (conf->raid_disks - mddev->degraded) == 1)
 		/*
 		 * Don't fail the drive, act as though we were just a
 		 * normal single drive
 		 */
 		return;
-	if (test_bit(In_sync, &rdev->flags)) {
+	if (test_and_clear_bit(In_sync, &rdev->flags)) {
+		unsigned long flags;
+		spin_lock_irqsave(&conf->device_lock, flags);
 		mddev->degraded++;
-		conf->working_disks--;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
 		/*
 		 * if recovery is running, make sure it aborts.
 		 */
 		set_bit(MD_RECOVERY_ERR, &mddev->recovery);
 	}
-	clear_bit(In_sync, &rdev->flags);
 	set_bit(Faulty, &rdev->flags);
-	mddev->sb_dirty = 1;
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
 	printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
 		"	Operation continuing on %d devices\n",
-		bdevname(rdev->bdev,b), conf->working_disks);
+		bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
 }
 
 static void print_conf(conf_t *conf)
@@ -984,7 +1011,7 @@
 		printk("(!conf)\n");
 		return;
 	}
-	printk(" --- wd:%d rd:%d\n", conf->working_disks,
+	printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
 		conf->raid_disks);
 
 	rcu_read_lock();
@@ -1023,10 +1050,11 @@
 		mdk_rdev_t *rdev = conf->mirrors[i].rdev;
 		if (rdev
 		    && !test_bit(Faulty, &rdev->flags)
-		    && !test_bit(In_sync, &rdev->flags)) {
-			conf->working_disks++;
+		    && !test_and_set_bit(In_sync, &rdev->flags)) {
+			unsigned long flags;
+			spin_lock_irqsave(&conf->device_lock, flags);
 			mddev->degraded--;
-			set_bit(In_sync, &rdev->flags);
+			spin_unlock_irqrestore(&conf->device_lock, flags);
 		}
 	}
 
@@ -1368,6 +1396,95 @@
  *	3.	Performs writes following reads for array syncronising.
  */
 
+static void fix_read_error(conf_t *conf, int read_disk,
+			   sector_t sect, int sectors)
+{
+	mddev_t *mddev = conf->mddev;
+	while(sectors) {
+		int s = sectors;
+		int d = read_disk;
+		int success = 0;
+		int start;
+		mdk_rdev_t *rdev;
+
+		if (s > (PAGE_SIZE>>9))
+			s = PAGE_SIZE >> 9;
+
+		do {
+			/* Note: no rcu protection needed here
+			 * as this is synchronous in the raid1d thread
+			 * which is the thread that might remove
+			 * a device.  If raid1d ever becomes multi-threaded....
+			 */
+			rdev = conf->mirrors[d].rdev;
+			if (rdev &&
+			    test_bit(In_sync, &rdev->flags) &&
+			    sync_page_io(rdev->bdev,
+					 sect + rdev->data_offset,
+					 s<<9,
+					 conf->tmppage, READ))
+				success = 1;
+			else {
+				d++;
+				if (d == conf->raid_disks)
+					d = 0;
+			}
+		} while (!success && d != read_disk);
+
+		if (!success) {
+			/* Cannot read from anywhere -- bye bye array */
+			md_error(mddev, conf->mirrors[read_disk].rdev);
+			break;
+		}
+		/* write it back and re-read */
+		start = d;
+		while (d != read_disk) {
+			if (d==0)
+				d = conf->raid_disks;
+			d--;
+			rdev = conf->mirrors[d].rdev;
+			if (rdev &&
+			    test_bit(In_sync, &rdev->flags)) {
+				if (sync_page_io(rdev->bdev,
+						 sect + rdev->data_offset,
+						 s<<9, conf->tmppage, WRITE)
+				    == 0)
+					/* Well, this device is dead */
+					md_error(mddev, rdev);
+			}
+		}
+		d = start;
+		while (d != read_disk) {
+			char b[BDEVNAME_SIZE];
+			if (d==0)
+				d = conf->raid_disks;
+			d--;
+			rdev = conf->mirrors[d].rdev;
+			if (rdev &&
+			    test_bit(In_sync, &rdev->flags)) {
+				if (sync_page_io(rdev->bdev,
+						 sect + rdev->data_offset,
+						 s<<9, conf->tmppage, READ)
+				    == 0)
+					/* Well, this device is dead */
+					md_error(mddev, rdev);
+				else {
+					atomic_add(s, &rdev->corrected_errors);
+					printk(KERN_INFO
+					       "raid1:%s: read error corrected "
+					       "(%d sectors at %llu on %s)\n",
+					       mdname(mddev), s,
+					       (unsigned long long)sect +
+					           rdev->data_offset,
+					       bdevname(rdev->bdev, b));
+				}
+			}
+		}
+		sectors -= s;
+		sect += s;
+	}
+}
+
 static void raid1d(mddev_t *mddev)
 {
 	r1bio_t *r1_bio;
@@ -1460,86 +1577,14 @@
 			 * This is all done synchronously while the array is
 			 * frozen
 			 */
-			sector_t sect = r1_bio->sector;
-			int sectors = r1_bio->sectors;
-			freeze_array(conf);
-			if (mddev->ro == 0) while(sectors) {
-				int s = sectors;
-				int d = r1_bio->read_disk;
-				int success = 0;
-
-				if (s > (PAGE_SIZE>>9))
-					s = PAGE_SIZE >> 9;
-
-				do {
-					/* Note: no rcu protection needed here
-					 * as this is synchronous in the raid1d thread
-					 * which is the thread that might remove
-					 * a device.  If raid1d ever becomes multi-threaded....
-					 */
-					rdev = conf->mirrors[d].rdev;
-					if (rdev &&
-					    test_bit(In_sync, &rdev->flags) &&
-					    sync_page_io(rdev->bdev,
-							 sect + rdev->data_offset,
-							 s<<9,
-							 conf->tmppage, READ))
-						success = 1;
-					else {
-						d++;
-						if (d == conf->raid_disks)
-							d = 0;
-					}
-				} while (!success && d != r1_bio->read_disk);
-
-				if (success) {
-					/* write it back and re-read */
-					int start = d;
-					while (d != r1_bio->read_disk) {
-						if (d==0)
-							d = conf->raid_disks;
-						d--;
-						rdev = conf->mirrors[d].rdev;
-						if (rdev &&
-						    test_bit(In_sync, &rdev->flags)) {
-							if (sync_page_io(rdev->bdev,
-									 sect + rdev->data_offset,
-									 s<<9, conf->tmppage, WRITE) == 0)
-								/* Well, this device is dead */
-								md_error(mddev, rdev);
-						}
-					}
-					d = start;
-					while (d != r1_bio->read_disk) {
-						if (d==0)
-							d = conf->raid_disks;
-						d--;
-						rdev = conf->mirrors[d].rdev;
-						if (rdev &&
-						    test_bit(In_sync, &rdev->flags)) {
-							if (sync_page_io(rdev->bdev,
-									 sect + rdev->data_offset,
-									 s<<9, conf->tmppage, READ) == 0)
-								/* Well, this device is dead */
-								md_error(mddev, rdev);
-							else {
-								atomic_add(s, &rdev->corrected_errors);
-								printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n",
-								       mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b));
-							}
-						}
-					}
-				} else {
-					/* Cannot read from anywhere -- bye bye array */
-					md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
-					break;
-				}
-				sectors -= s;
-				sect += s;
+			if (mddev->ro == 0) {
+				freeze_array(conf);
+				fix_read_error(conf, r1_bio->read_disk,
+					       r1_bio->sector,
+					       r1_bio->sectors);
+				unfreeze_array(conf);
 			}
 
-			unfreeze_array(conf);
-
 			bio = r1_bio->bios[r1_bio->read_disk];
 			if ((disk=read_balance(conf, r1_bio)) == -1) {
 				printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
@@ -1884,15 +1929,11 @@
 			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
 		disk->head_position = 0;
-		if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
-			conf->working_disks++;
 	}
 	conf->raid_disks = mddev->raid_disks;
 	conf->mddev = mddev;
 	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
-	if (conf->working_disks == 1)
-		mddev->recovery_cp = MaxSector;
 
 	spin_lock_init(&conf->resync_lock);
 	init_waitqueue_head(&conf->wait_barrier);
@@ -1900,11 +1941,6 @@
 	bio_list_init(&conf->pending_bio_list);
 	bio_list_init(&conf->flushing_bio_list);
 
-	if (!conf->working_disks) {
-		printk(KERN_ERR "raid1: no operational mirrors for %s\n",
-			mdname(mddev));
-		goto out_free_conf;
-	}
 
 	mddev->degraded = 0;
 	for (i = 0; i < conf->raid_disks; i++) {
@@ -1917,6 +1953,13 @@
 			mddev->degraded++;
 		}
 	}
+	if (mddev->degraded == conf->raid_disks) {
+		printk(KERN_ERR "raid1: no operational mirrors for %s\n",
+			mdname(mddev));
+		goto out_free_conf;
+	}
+	if (conf->raid_disks - mddev->degraded == 1)
+		mddev->recovery_cp = MaxSector;
 
 	/*
 	 * find the first working one and use it as a starting point
@@ -1948,6 +1991,8 @@
 
 	mddev->queue->unplug_fn = raid1_unplug;
 	mddev->queue->issue_flush_fn = raid1_issue_flush;
+	mddev->queue->backing_dev_info.congested_fn = raid1_congested;
+	mddev->queue->backing_dev_info.congested_data = mddev;
 
 	return 0;
 
@@ -2035,7 +2080,7 @@
 	mirror_info_t *newmirrors;
 	conf_t *conf = mddev_to_conf(mddev);
 	int cnt, raid_disks;
-
+	unsigned long flags;
 	int d, d2;
 
 	/* Cannot change chunk_size, layout, or level */
@@ -2094,7 +2139,9 @@
 	kfree(conf->poolinfo);
 	conf->poolinfo = newpoolinfo;
 
+	spin_lock_irqsave(&conf->device_lock, flags);
 	mddev->degraded += (raid_disks - conf->raid_disks);
+	spin_unlock_irqrestore(&conf->device_lock, flags);
 	conf->raid_disks = mddev->raid_disks = raid_disks;
 	mddev->delta_disks = 0;
 
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 016ddb8..1250f0e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -648,6 +648,26 @@
 	return ret;
 }
 
+static int raid10_congested(void *data, int bits)
+{
+	mddev_t *mddev = data;
+	conf_t *conf = mddev_to_conf(mddev);
+	int i, ret = 0;
+
+	rcu_read_lock();
+	for (i = 0; i < mddev->raid_disks && ret == 0; i++) {
+		mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+		if (rdev && !test_bit(Faulty, &rdev->flags)) {
+			request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+			ret |= bdi_congested(&q->backing_dev_info, bits);
+		}
+	}
+	rcu_read_unlock();
+	return ret;
+}
+
+
 /* Barriers....
  * Sometimes we need to suspend IO while we do something else,
  * either some resync/recovery, or reconfigure the array.
@@ -921,7 +941,7 @@
 			seq_printf(seq, " %d far-copies", conf->far_copies);
 	}
 	seq_printf(seq, " [%d/%d] [", conf->raid_disks,
-						conf->working_disks);
+					conf->raid_disks - mddev->degraded);
 	for (i = 0; i < conf->raid_disks; i++)
 		seq_printf(seq, "%s",
 			      conf->mirrors[i].rdev &&
@@ -941,7 +961,7 @@
 	 * else mark the drive as failed
 	 */
 	if (test_bit(In_sync, &rdev->flags)
-	    && conf->working_disks == 1)
+	    && conf->raid_disks-mddev->degraded == 1)
 		/*
 		 * Don't fail the drive, just return an IO error.
 		 * The test should really be more sophisticated than
@@ -950,20 +970,21 @@
 		 * really dead" tests...
 		 */
 		return;
-	if (test_bit(In_sync, &rdev->flags)) {
+	if (test_and_clear_bit(In_sync, &rdev->flags)) {
+		unsigned long flags;
+		spin_lock_irqsave(&conf->device_lock, flags);
 		mddev->degraded++;
-		conf->working_disks--;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
 		/*
 		 * if recovery is running, make sure it aborts.
 		 */
 		set_bit(MD_RECOVERY_ERR, &mddev->recovery);
 	}
-	clear_bit(In_sync, &rdev->flags);
 	set_bit(Faulty, &rdev->flags);
-	mddev->sb_dirty = 1;
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
 	printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
 		"	Operation continuing on %d devices\n",
-		bdevname(rdev->bdev,b), conf->working_disks);
+		bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
 }
 
 static void print_conf(conf_t *conf)
@@ -976,7 +997,7 @@
 		printk("(!conf)\n");
 		return;
 	}
-	printk(" --- wd:%d rd:%d\n", conf->working_disks,
+	printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
 		conf->raid_disks);
 
 	for (i = 0; i < conf->raid_disks; i++) {
@@ -1034,10 +1055,11 @@
 		tmp = conf->mirrors + i;
 		if (tmp->rdev
 		    && !test_bit(Faulty, &tmp->rdev->flags)
-		    && !test_bit(In_sync, &tmp->rdev->flags)) {
-			conf->working_disks++;
+		    && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
+			unsigned long flags;
+			spin_lock_irqsave(&conf->device_lock, flags);
 			mddev->degraded--;
-			set_bit(In_sync, &tmp->rdev->flags);
+			spin_unlock_irqrestore(&conf->device_lock, flags);
 		}
 	}
 
@@ -1350,9 +1372,119 @@
  *
  *	1.	Retries failed read operations on working mirrors.
  *	2.	Updates the raid superblock when problems encounter.
- *	3.	Performs writes following reads for array syncronising.
+ *	3.	Performs writes following reads for array synchronising.
  */
 
+static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
+{
+	int sect = 0; /* Offset from r10_bio->sector */
+	int sectors = r10_bio->sectors;
+	mdk_rdev_t*rdev;
+	while(sectors) {
+		int s = sectors;
+		int sl = r10_bio->read_slot;
+		int success = 0;
+		int start;
+
+		if (s > (PAGE_SIZE>>9))
+			s = PAGE_SIZE >> 9;
+
+		rcu_read_lock();
+		do {
+			int d = r10_bio->devs[sl].devnum;
+			rdev = rcu_dereference(conf->mirrors[d].rdev);
+			if (rdev &&
+			    test_bit(In_sync, &rdev->flags)) {
+				atomic_inc(&rdev->nr_pending);
+				rcu_read_unlock();
+				success = sync_page_io(rdev->bdev,
+						       r10_bio->devs[sl].addr +
+						       sect + rdev->data_offset,
+						       s<<9,
+						       conf->tmppage, READ);
+				rdev_dec_pending(rdev, mddev);
+				rcu_read_lock();
+				if (success)
+					break;
+			}
+			sl++;
+			if (sl == conf->copies)
+				sl = 0;
+		} while (!success && sl != r10_bio->read_slot);
+		rcu_read_unlock();
+
+		if (!success) {
+			/* Cannot read from anywhere -- bye bye array */
+			int dn = r10_bio->devs[r10_bio->read_slot].devnum;
+			md_error(mddev, conf->mirrors[dn].rdev);
+			break;
+		}
+
+		start = sl;
+		/* write it back and re-read */
+		rcu_read_lock();
+		while (sl != r10_bio->read_slot) {
+			int d;
+			if (sl==0)
+				sl = conf->copies;
+			sl--;
+			d = r10_bio->devs[sl].devnum;
+			rdev = rcu_dereference(conf->mirrors[d].rdev);
+			if (rdev &&
+			    test_bit(In_sync, &rdev->flags)) {
+				atomic_inc(&rdev->nr_pending);
+				rcu_read_unlock();
+				atomic_add(s, &rdev->corrected_errors);
+				if (sync_page_io(rdev->bdev,
+						 r10_bio->devs[sl].addr +
+						 sect + rdev->data_offset,
+						 s<<9, conf->tmppage, WRITE)
+				    == 0)
+					/* Well, this device is dead */
+					md_error(mddev, rdev);
+				rdev_dec_pending(rdev, mddev);
+				rcu_read_lock();
+			}
+		}
+		sl = start;
+		while (sl != r10_bio->read_slot) {
+			int d;
+			if (sl==0)
+				sl = conf->copies;
+			sl--;
+			d = r10_bio->devs[sl].devnum;
+			rdev = rcu_dereference(conf->mirrors[d].rdev);
+			if (rdev &&
+			    test_bit(In_sync, &rdev->flags)) {
+				char b[BDEVNAME_SIZE];
+				atomic_inc(&rdev->nr_pending);
+				rcu_read_unlock();
+				if (sync_page_io(rdev->bdev,
+						 r10_bio->devs[sl].addr +
+						 sect + rdev->data_offset,
+						 s<<9, conf->tmppage, READ) == 0)
+					/* Well, this device is dead */
+					md_error(mddev, rdev);
+				else
+					printk(KERN_INFO
+					       "raid10:%s: read error corrected"
+					       " (%d sectors at %llu on %s)\n",
+					       mdname(mddev), s,
+					       (unsigned long long)sect+
+					            rdev->data_offset,
+					       bdevname(rdev->bdev, b));
+
+				rdev_dec_pending(rdev, mddev);
+				rcu_read_lock();
+			}
+		}
+		rcu_read_unlock();
+
+		sectors -= s;
+		sect += s;
+	}
+}
+
 static void raid10d(mddev_t *mddev)
 {
 	r10bio_t *r10_bio;
@@ -1413,105 +1545,12 @@
 			 * This is all done synchronously while the array is
 			 * frozen.
 			 */
-			int sect = 0; /* Offset from r10_bio->sector */
-			int sectors = r10_bio->sectors;
-			freeze_array(conf);
-			if (mddev->ro == 0) while(sectors) {
-				int s = sectors;
-				int sl = r10_bio->read_slot;
-				int success = 0;
-
-				if (s > (PAGE_SIZE>>9))
-					s = PAGE_SIZE >> 9;
-
-				rcu_read_lock();
-				do {
-					int d = r10_bio->devs[sl].devnum;
-					rdev = rcu_dereference(conf->mirrors[d].rdev);
-					if (rdev &&
-					    test_bit(In_sync, &rdev->flags)) {
-						atomic_inc(&rdev->nr_pending);
-						rcu_read_unlock();
-						success = sync_page_io(rdev->bdev,
-								       r10_bio->devs[sl].addr +
-								       sect + rdev->data_offset,
-								       s<<9,
-								       conf->tmppage, READ);
-						rdev_dec_pending(rdev, mddev);
-						rcu_read_lock();
-						if (success)
-							break;
-					}
-					sl++;
-					if (sl == conf->copies)
-						sl = 0;
-				} while (!success && sl != r10_bio->read_slot);
-				rcu_read_unlock();
-
-				if (success) {
-					int start = sl;
-					/* write it back and re-read */
-					rcu_read_lock();
-					while (sl != r10_bio->read_slot) {
-						int d;
-						if (sl==0)
-							sl = conf->copies;
-						sl--;
-						d = r10_bio->devs[sl].devnum;
-						rdev = rcu_dereference(conf->mirrors[d].rdev);
-						if (rdev &&
-						    test_bit(In_sync, &rdev->flags)) {
-							atomic_inc(&rdev->nr_pending);
-							rcu_read_unlock();
-							atomic_add(s, &rdev->corrected_errors);
-							if (sync_page_io(rdev->bdev,
-									 r10_bio->devs[sl].addr +
-									 sect + rdev->data_offset,
-									 s<<9, conf->tmppage, WRITE) == 0)
-								/* Well, this device is dead */
-								md_error(mddev, rdev);
-							rdev_dec_pending(rdev, mddev);
-							rcu_read_lock();
-						}
-					}
-					sl = start;
-					while (sl != r10_bio->read_slot) {
-						int d;
-						if (sl==0)
-							sl = conf->copies;
-						sl--;
-						d = r10_bio->devs[sl].devnum;
-						rdev = rcu_dereference(conf->mirrors[d].rdev);
-						if (rdev &&
-						    test_bit(In_sync, &rdev->flags)) {
-							atomic_inc(&rdev->nr_pending);
-							rcu_read_unlock();
-							if (sync_page_io(rdev->bdev,
-									 r10_bio->devs[sl].addr +
-									 sect + rdev->data_offset,
-									 s<<9, conf->tmppage, READ) == 0)
-								/* Well, this device is dead */
-								md_error(mddev, rdev);
-							else
-								printk(KERN_INFO "raid10:%s: read error corrected (%d sectors at %llu on %s)\n",
-								       mdname(mddev), s, (unsigned long long)(sect+rdev->data_offset), bdevname(rdev->bdev, b));
-
-							rdev_dec_pending(rdev, mddev);
-							rcu_read_lock();
-						}
-					}
-					rcu_read_unlock();
-				} else {
-					/* Cannot read from anywhere -- bye bye array */
-					md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev);
-					break;
-				}
-				sectors -= s;
-				sect += s;
+			if (mddev->ro == 0) {
+				freeze_array(conf);
+				fix_read_error(conf, mddev, r10_bio);
+				unfreeze_array(conf);
 			}
 
-			unfreeze_array(conf);
-
 			bio = r10_bio->devs[r10_bio->read_slot].bio;
 			r10_bio->devs[r10_bio->read_slot].bio =
 				mddev->ro ? IO_BLOCKED : NULL;
@@ -2018,8 +2057,6 @@
 			mddev->queue->max_sectors = (PAGE_SIZE>>9);
 
 		disk->head_position = 0;
-		if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
-			conf->working_disks++;
 	}
 	conf->raid_disks = mddev->raid_disks;
 	conf->mddev = mddev;
@@ -2077,6 +2114,8 @@
 
 	mddev->queue->unplug_fn = raid10_unplug;
 	mddev->queue->issue_flush_fn = raid10_issue_flush;
+	mddev->queue->backing_dev_info.congested_fn = raid10_congested;
+	mddev->queue->backing_dev_info.congested_data = mddev;
 
 	/* Calculate max read-ahead size.
 	 * We need to readahead at least twice a whole stripe....
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 4500660..e14f457 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -636,7 +636,6 @@
  	struct stripe_head *sh = bi->bi_private;
 	raid5_conf_t *conf = sh->raid_conf;
 	int disks = sh->disks, i;
-	unsigned long flags;
 	int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
 
 	if (bi->bi_size)
@@ -654,7 +653,6 @@
 		return 0;
 	}
 
-	spin_lock_irqsave(&conf->device_lock, flags);
 	if (!uptodate)
 		md_error(conf->mddev, conf->disks[i].rdev);
 
@@ -662,8 +660,7 @@
 	
 	clear_bit(R5_LOCKED, &sh->dev[i].flags);
 	set_bit(STRIPE_HANDLE, &sh->state);
-	__release_stripe(conf, sh);
-	spin_unlock_irqrestore(&conf->device_lock, flags);
+	release_stripe(sh);
 	return 0;
 }
 
@@ -696,12 +693,12 @@
 	PRINTK("raid5: error called\n");
 
 	if (!test_bit(Faulty, &rdev->flags)) {
-		mddev->sb_dirty = 1;
-		if (test_bit(In_sync, &rdev->flags)) {
-			conf->working_disks--;
+		set_bit(MD_CHANGE_DEVS, &mddev->flags);
+		if (test_and_clear_bit(In_sync, &rdev->flags)) {
+			unsigned long flags;
+			spin_lock_irqsave(&conf->device_lock, flags);
 			mddev->degraded++;
-			conf->failed_disks++;
-			clear_bit(In_sync, &rdev->flags);
+			spin_unlock_irqrestore(&conf->device_lock, flags);
 			/*
 			 * if recovery was running, make sure it aborts.
 			 */
@@ -711,7 +708,7 @@
 		printk (KERN_ALERT
 			"raid5: Disk failure on %s, disabling device."
 			" Operation continuing on %d devices\n",
-			bdevname(rdev->bdev,b), conf->working_disks);
+			bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
 	}
 }
 
@@ -1108,7 +1105,7 @@
 				if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
 					wake_up(&conf->wait_for_overlap);
 
-				if (sh->dev[i].written) BUG();
+				BUG_ON(sh->dev[i].written);
 				sh->dev[i].written = chosen;
 			}
 		break;
@@ -1353,10 +1350,9 @@
 static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
 {
 	int sectors_per_chunk = conf->chunk_size >> 9;
-	sector_t x = stripe;
 	int pd_idx, dd_idx;
-	int chunk_offset = sector_div(x, sectors_per_chunk);
-	stripe = x;
+	int chunk_offset = sector_div(stripe, sectors_per_chunk);
+
 	raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk
 			     + chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf);
 	return pd_idx;
@@ -2597,6 +2593,24 @@
 	return ret;
 }
 
+static int raid5_congested(void *data, int bits)
+{
+	mddev_t *mddev = data;
+	raid5_conf_t *conf = mddev_to_conf(mddev);
+
+	/* No difference between reads and writes.  Just check
+	 * how busy the stripe_cache is
+	 */
+	if (conf->inactive_blocked)
+		return 1;
+	if (conf->quiesce)
+		return 1;
+	if (list_empty_careful(&conf->inactive_list))
+		return 1;
+
+	return 0;
+}
+
 static int make_request(request_queue_t *q, struct bio * bi)
 {
 	mddev_t *mddev = q->queuedata;
@@ -2781,9 +2795,9 @@
 		wait_event(conf->wait_for_overlap,
 			   atomic_read(&conf->reshape_stripes)==0);
 		mddev->reshape_position = conf->expand_progress;
-		mddev->sb_dirty = 1;
+		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		md_wakeup_thread(mddev->thread);
-		wait_event(mddev->sb_wait, mddev->sb_dirty == 0 ||
+		wait_event(mddev->sb_wait, mddev->flags == 0 ||
 			   kthread_should_stop());
 		spin_lock_irq(&conf->device_lock);
 		conf->expand_lo = mddev->reshape_position;
@@ -3074,6 +3088,7 @@
 	mdk_rdev_t *rdev;
 	struct disk_info *disk;
 	struct list_head *tmp;
+	int working_disks = 0;
 
 	if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
 		printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
@@ -3176,14 +3191,14 @@
 			printk(KERN_INFO "raid5: device %s operational as raid"
 				" disk %d\n", bdevname(rdev->bdev,b),
 				raid_disk);
-			conf->working_disks++;
+			working_disks++;
 		}
 	}
 
 	/*
 	 * 0 for a fully functional array, 1 or 2 for a degraded array.
 	 */
-	mddev->degraded = conf->failed_disks = conf->raid_disks - conf->working_disks;
+	mddev->degraded = conf->raid_disks - working_disks;
 	conf->mddev = mddev;
 	conf->chunk_size = mddev->chunk_size;
 	conf->level = mddev->level;
@@ -3218,7 +3233,7 @@
 	if (mddev->degraded > conf->max_degraded) {
 		printk(KERN_ERR "raid5: not enough operational devices for %s"
 			" (%d/%d failed)\n",
-			mdname(mddev), conf->failed_disks, conf->raid_disks);
+			mdname(mddev), mddev->degraded, conf->raid_disks);
 		goto abort;
 	}
 
@@ -3299,6 +3314,9 @@
 
 	mddev->queue->unplug_fn = raid5_unplug_device;
 	mddev->queue->issue_flush_fn = raid5_issue_flush;
+	mddev->queue->backing_dev_info.congested_fn = raid5_congested;
+	mddev->queue->backing_dev_info.congested_data = mddev;
+
 	mddev->array_size =  mddev->size * (conf->previous_raid_disks -
 					    conf->max_degraded);
 
@@ -3375,7 +3393,7 @@
 	int i;
 
 	seq_printf (seq, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout);
-	seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->working_disks);
+	seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->raid_disks - mddev->degraded);
 	for (i = 0; i < conf->raid_disks; i++)
 		seq_printf (seq, "%s",
 			       conf->disks[i].rdev &&
@@ -3397,8 +3415,8 @@
 		printk("(conf==NULL)\n");
 		return;
 	}
-	printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks,
-		 conf->working_disks, conf->failed_disks);
+	printk(" --- rd:%d wd:%d\n", conf->raid_disks,
+		 conf->raid_disks - conf->mddev->degraded);
 
 	for (i = 0; i < conf->raid_disks; i++) {
 		char b[BDEVNAME_SIZE];
@@ -3420,11 +3438,11 @@
 		tmp = conf->disks + i;
 		if (tmp->rdev
 		    && !test_bit(Faulty, &tmp->rdev->flags)
-		    && !test_bit(In_sync, &tmp->rdev->flags)) {
+		    && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
+			unsigned long flags;
+			spin_lock_irqsave(&conf->device_lock, flags);
 			mddev->degraded--;
-			conf->failed_disks--;
-			conf->working_disks++;
-			set_bit(In_sync, &tmp->rdev->flags);
+			spin_unlock_irqrestore(&conf->device_lock, flags);
 		}
 	}
 	print_raid5_conf(conf);
@@ -3560,6 +3578,7 @@
 	struct list_head *rtmp;
 	int spares = 0;
 	int added_devices = 0;
+	unsigned long flags;
 
 	if (mddev->degraded ||
 	    test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
@@ -3593,7 +3612,6 @@
 			if (raid5_add_disk(mddev, rdev)) {
 				char nm[20];
 				set_bit(In_sync, &rdev->flags);
-				conf->working_disks++;
 				added_devices++;
 				rdev->recovery_offset = 0;
 				sprintf(nm, "rd%d", rdev->raid_disk);
@@ -3602,10 +3620,12 @@
 				break;
 		}
 
+	spin_lock_irqsave(&conf->device_lock, flags);
 	mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
+	spin_unlock_irqrestore(&conf->device_lock, flags);
 	mddev->raid_disks = conf->raid_disks;
 	mddev->reshape_position = 0;
-	mddev->sb_dirty = 1;
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
 	clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
 	clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index b5cdd57..3d778c5 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -56,7 +56,7 @@
 	  measurements.
 
 	  Please keep in mind that these updates cause traffic on the tuner
-	  control bus and thus may or may not affect receiption sensitivity.
+	  control bus and thus may or may not affect reception sensitivity.
 
 	  The default value should be a safe choice for common applications.
 
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 3dd5dbaf..53304e6 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1014,6 +1014,13 @@
 	if ((ret = dvb_generic_open (inode, file)) < 0)
 		return ret;
 
+	if (fe->ops.ts_bus_ctrl) {
+		if ((ret = fe->ops.ts_bus_ctrl (fe, 1)) < 0) {
+			dvb_generic_release (inode, file);
+			return ret;
+		}
+	}
+
 	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
 
 		/* normal tune mode when opened R/W */
@@ -1043,6 +1050,9 @@
 	if ((file->f_flags & O_ACCMODE) != O_RDONLY)
 		fepriv->release_jiffies = jiffies;
 
+	if (fe->ops.ts_bus_ctrl)
+		fe->ops.ts_bus_ctrl (fe, 0);
+
 	return dvb_generic_release (inode, file);
 }
 
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index e5d5028..f233d78 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -129,6 +129,7 @@
 	int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
 	int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
 	int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
+	int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
 
 	struct dvb_tuner_ops tuner_ops;
 };
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index c972fe0..9878183 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -26,7 +26,6 @@
 
 
 
-#define __KERNEL_SYSCALLS__
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 0a3c353..67cefdd 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -39,20 +39,8 @@
 	  Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
 
-	  Devices supported by this driver:
-	    Artec T1 USB1.1 boxes
-	    Avermedia AverTV DVBT USB1.1
-	    Compro Videomate DVB-U2000 - DVB-T USB
-	    DiBcom USB1.1 reference devices (non-public)
-	    Grandtec DVB-T USB
-	    Hama DVB-T USB1.1-Box
-	    KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
-	    TwinhanDTV Magic Box (VP7041e)
-	    TwinhanDTV USB-Ter (VP7041)
-	    Ultima Electronic/Artec T1 USB TVBOX
-
-	  The VP7041 seems to be identical to "CTS Portable" (Chinese
-	  Television System).
+	  For an up-to-date list of devices supported by this driver, have a look
+	  on the Linux-DVB Wiki at www.linuxtv.org.
 
 	  Say Y if you own such a device and want to use it. You should build it as
 	  a module.
@@ -69,12 +57,29 @@
 	select DVB_DIB3000MC
 	select DVB_TUNER_MT2060
 	help
-	  Support for 2.0 DVB-T receivers based on reference designs made by
+	  Support for USB2.0 DVB-T receivers based on reference designs made by
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
 
-	  Devices supported by this driver:
-	    Artec T1 USB2.0 boxes
-	    DiBcom USB2.0 reference devices (non-public)
+	  For an up-to-date list of devices supported by this driver, have a look
+	  on the Linux-DVB Wiki at www.linuxtv.org.
+
+	  Say Y if you own such a device and want to use it. You should build it as
+	  a module.
+
+config DVB_USB_DIB0700
+	tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
+	depends on DVB_USB
+	select DVB_DIB7000M
+	select DVB_DIB3000MC
+	select DVB_TUNER_MT2060
+	help
+	  Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
+	  USB bridge is also present in devices having the DiB7700 DVB-T-USB
+	  silicon. This chip can be found in devices offered by Hauppauge,
+	  Avermedia and other big and small companies.
+
+	  For an up-to-date list of devices supported by this driver, have a look
+	  on the Linux-DVB Wiki at www.linuxtv.org.
 
 	  Say Y if you own such a device and want to use it. You should build it as
 	  a module.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 9643f56..e239107 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -1,4 +1,4 @@
-dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
+dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
 obj-$(CONFIG_DVB_USB) += dvb-usb.o
 
 dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
@@ -36,4 +36,7 @@
 dvb-usb-cxusb-objs = cxusb.o
 obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
 
+dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
+obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
+
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index df0c384..2ed3eb6 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -27,7 +27,8 @@
 }
 
 /* assure to put cold to 0 for iManufacturer == 1 */
-static int a800_identify_state(struct usb_device *udev, struct dvb_usb_properties *props,struct dvb_usb_device_description **desc, int *cold)
+static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+	struct dvb_usb_device_description **desc, int *cold)
 {
 	*cold = udev->descriptor.iManufacturer != 1;
 	return 0;
@@ -88,7 +89,7 @@
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties a800_properties;
+static struct dvb_usb_device_properties a800_properties;
 
 static int a800_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -104,22 +105,41 @@
 };
 MODULE_DEVICE_TABLE (usb, a800_table);
 
-static struct dvb_usb_properties a800_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-	.pid_filter_count = 32,
+static struct dvb_usb_device_properties a800_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
-
 	.firmware = "dvb-usb-avertv-a800-02.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
-
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+			.pid_filter_count = 32,
 	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
 	.pid_filter       = dibusb_pid_filter,
 	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-	.power_ctrl       = a800_power_ctrl,
+
 	.frontend_attach  = dibusb_dib3000mc_frontend_attach,
 	.tuner_attach     = dibusb_dib3000mc_tuner_attach,
+
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+			.size_of_priv     = sizeof(struct dibusb_state),
+		},
+	},
+
+	.power_ctrl       = a800_power_ctrl,
 	.identify_state   = a800_identify_state,
 
 	.rc_interval      = DEFAULT_RC_INTERVAL,
@@ -130,18 +150,6 @@
 	.i2c_algo         = &dibusb_i2c_algo,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x06,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
-
 	.num_device_descs = 1,
 	.devices = {
 		{   "AVerMedia AverTV DVB-T USB 2.0 (A800)",
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index c710c01..43f3906 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -161,13 +161,13 @@
 		return 0;
 }
 
-static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
 	u8 buf[2] = { 0x03, 0x00 };
 	if (onoff)
-		cxusb_ctrl_msg(d,CMD_STREAMING_ON, buf, 2, NULL, 0);
+		cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
 	else
-		cxusb_ctrl_msg(d,CMD_STREAMING_OFF, NULL, 0, NULL, 0);
+		cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
 
 	return 0;
 }
@@ -327,8 +327,8 @@
 static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe,
 					  struct dvb_frontend_parameters *fep)
 {
-	struct dvb_usb_device *d = fe->dvb->priv;
-	return lg_h06xf_pll_set(fe, &d->i2c_adap, fep);
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	return lg_h06xf_pll_set(fe, &adap->dev->i2c_adap, fep);
 }
 
 static struct cx22702_config cxusb_cx22702_config = {
@@ -359,98 +359,99 @@
 };
 
 /* Callbacks for DVB USB */
-static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
-	d->pll_addr = 0x61;
-	memcpy(d->pll_init, bpll, 4);
-	d->pll_desc = &dvb_pll_fmd1216me;
+	adap->pll_addr = 0x61;
+	memcpy(adap->pll_init, bpll, 4);
+	adap->pll_desc = &dvb_pll_fmd1216me;
 
-	d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
-	d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+	adap->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
+	adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
 
 	return 0;
 }
 
-static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	d->pll_addr = 0x61;
-	d->pll_desc = &dvb_pll_thomson_dtt7579;
-	d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+	adap->pll_addr = 0x61;
+	adap->pll_desc = &dvb_pll_thomson_dtt7579;
+	adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
 	return 0;
 }
 
-static int cxusb_lgz201_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	d->pll_addr = 0x61;
-	d->pll_desc = &dvb_pll_lg_z201;
-	d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+	adap->pll_addr = 0x61;
+	adap->pll_desc = &dvb_pll_lg_z201;
+	adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
 	return 0;
 }
 
-static int cxusb_dtt7579_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	d->pll_addr = 0x60;
-	d->pll_desc = &dvb_pll_thomson_dtt7579;
-	d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+	adap->pll_addr = 0x60;
+	adap->pll_desc = &dvb_pll_thomson_dtt7579;
+	adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
 	return 0;
 }
 
-static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	d->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params;
+	adap->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params;
 	return 0;
 }
 
-static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	u8 b;
-	if (usb_set_interface(d->udev,0,6) < 0)
+	if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
 		err("set interface failed");
 
-	cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1);
+	cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
 
-	if ((d->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, &d->i2c_adap)) != NULL)
+	if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, &adap->dev->i2c_adap)) != NULL)
 		return 0;
 
 	return -EIO;
 }
 
-static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	if (usb_set_interface(d->udev,0,7) < 0)
+	if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
 		err("set interface failed");
 
-	cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
+	cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 
-	if ((d->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, &d->i2c_adap)) != NULL)
+	if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, &adap->dev->i2c_adap)) != NULL)
 		return 0;
 
 	return -EIO;
 }
 
-static int cxusb_mt352_frontend_attach(struct dvb_usb_device *d)
-{	/* used in both lgz201 and th7579 */
-	if (usb_set_interface(d->udev,0,0) < 0)
-		err("set interface failed");
-
-	cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
-
-	if ((d->fe = dvb_attach(mt352_attach, &cxusb_mt352_config, &d->i2c_adap)) != NULL)
-		return 0;
-
-	return -EIO;
-}
-
-static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	if (usb_set_interface(d->udev,0,0) < 0)
+	/* used in both lgz201 and th7579 */
+	if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
 		err("set interface failed");
 
-	cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
+	cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 
-	if (((d->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
-		((d->fe = dvb_attach(zl10353_attach, &cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
+	if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config, &adap->dev->i2c_adap)) != NULL)
+		return 0;
+
+	return -EIO;
+}
+
+static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
+		err("set interface failed");
+
+	cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
+
+	if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, &adap->dev->i2c_adap)) != NULL) ||
+		((adap->fe = dvb_attach(zl10353_attach, &cxusb_zl10353_dee1601_config, &adap->dev->i2c_adap)) != NULL))
 		return 0;
 
 	return -EIO;
@@ -480,11 +481,11 @@
 }
 
 /* DVB USB Driver stuff */
-static struct dvb_usb_properties cxusb_medion_properties;
-static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties;
-static struct dvb_usb_properties cxusb_bluebird_dee1601_properties;
-static struct dvb_usb_properties cxusb_bluebird_lgz201_properties;
-static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties;
+static struct dvb_usb_device_properties cxusb_medion_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -504,36 +505,36 @@
 		{ USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
 		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
 		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
-		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_COLD) },
-		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_WARM) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
 		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
 		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
 		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
 		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
-		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_COLD) },
-		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_WARM) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
 		{}		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
 
-static struct dvb_usb_properties cxusb_medion_properties = {
+static struct dvb_usb_device_properties cxusb_medion_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 
 	.size_of_priv     = sizeof(struct cxusb_state),
 
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.streaming_ctrl   = cxusb_streaming_ctrl,
-	.power_ctrl       = cxusb_power_ctrl,
 	.frontend_attach  = cxusb_cx22702_frontend_attach,
 	.tuner_attach     = cxusb_fmd1216me_tuner_attach,
-
-	.i2c_algo         = &cxusb_i2c_algo,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 5,
 		.endpoint = 0x02,
 		.u = {
@@ -543,6 +544,14 @@
 		}
 	},
 
+		},
+	},
+	.power_ctrl       = cxusb_power_ctrl,
+
+	.i2c_algo         = &cxusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
 	.num_device_descs = 1,
 	.devices = {
 		{   "Medion MD95700 (MDUSBTV-HYBRID)",
@@ -552,7 +561,7 @@
 	}
 };
 
-static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl          = DEVICE_SPECIFIC,
@@ -563,11 +572,29 @@
 
 	.size_of_priv     = sizeof(struct cxusb_state),
 
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.streaming_ctrl   = cxusb_streaming_ctrl,
-	.power_ctrl       = cxusb_bluebird_power_ctrl,
 	.frontend_attach  = cxusb_lgdt3303_frontend_attach,
 	.tuner_attach     = cxusb_lgdt3303_tuner_attach,
 
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 5,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 8192,
+			}
+		}
+	},
+		},
+	},
+
+	.power_ctrl       = cxusb_bluebird_power_ctrl,
+
 	.i2c_algo         = &cxusb_i2c_algo,
 
 	.rc_interval      = 100,
@@ -576,17 +603,6 @@
 	.rc_query         = cxusb_rc_query,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 5,
-		.endpoint = 0x02,
-		.u = {
-			.bulk = {
-				.buffersize = 8192,
-			}
-		}
-	},
 
 	.num_device_descs = 1,
 	.devices = {
@@ -597,7 +613,7 @@
 	}
 };
 
-static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl          = DEVICE_SPECIFIC,
@@ -608,10 +624,27 @@
 
 	.size_of_priv     = sizeof(struct cxusb_state),
 
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.streaming_ctrl   = cxusb_streaming_ctrl,
-	.power_ctrl       = cxusb_bluebird_power_ctrl,
 	.frontend_attach  = cxusb_dee1601_frontend_attach,
 	.tuner_attach     = cxusb_dee1601_tuner_attach,
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 5,
+		.endpoint = 0x04,
+		.u = {
+			.bulk = {
+				.buffersize = 8192,
+			}
+		}
+	},
+		},
+	},
+
+	.power_ctrl       = cxusb_bluebird_power_ctrl,
 
 	.i2c_algo         = &cxusb_i2c_algo,
 
@@ -621,19 +654,8 @@
 	.rc_query         = cxusb_rc_query,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 5,
-		.endpoint = 0x04,
-		.u = {
-			.bulk = {
-				.buffersize = 8192,
-			}
-		}
-	},
 
-	.num_device_descs = 2,
+	.num_device_descs = 3,
 	.devices = {
 		{   "DViCO FusionHDTV DVB-T Dual USB",
 			{ &cxusb_table[3], NULL },
@@ -643,10 +665,14 @@
 			{ &cxusb_table[9],  NULL },
 			{ &cxusb_table[10], NULL },
 		},
+		{   "DViCO FusionHDTV DVB-T Dual Digital 2",
+			{ &cxusb_table[11], NULL },
+			{ &cxusb_table[12], NULL },
+		},
 	}
 };
 
-static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl          = DEVICE_SPECIFIC,
@@ -657,11 +683,28 @@
 
 	.size_of_priv     = sizeof(struct cxusb_state),
 
+	.num_adapters = 2,
+	.adapter = {
+		{
 	.streaming_ctrl   = cxusb_streaming_ctrl,
-	.power_ctrl       = cxusb_bluebird_power_ctrl,
 	.frontend_attach  = cxusb_mt352_frontend_attach,
 	.tuner_attach     = cxusb_lgz201_tuner_attach,
 
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 5,
+		.endpoint = 0x04,
+		.u = {
+			.bulk = {
+				.buffersize = 8192,
+			}
+		}
+	},
+		},
+	},
+	.power_ctrl       = cxusb_bluebird_power_ctrl,
+
 	.i2c_algo         = &cxusb_i2c_algo,
 
 	.rc_interval      = 100,
@@ -670,18 +713,6 @@
 	.rc_query         = cxusb_rc_query,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 5,
-		.endpoint = 0x04,
-		.u = {
-			.bulk = {
-				.buffersize = 8192,
-			}
-		}
-	},
-
 	.num_device_descs = 1,
 	.devices = {
 		{   "DViCO FusionHDTV DVB-T USB (LGZ201)",
@@ -691,7 +722,7 @@
 	}
 };
 
-static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl          = DEVICE_SPECIFIC,
@@ -702,11 +733,28 @@
 
 	.size_of_priv     = sizeof(struct cxusb_state),
 
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.streaming_ctrl   = cxusb_streaming_ctrl,
-	.power_ctrl       = cxusb_bluebird_power_ctrl,
 	.frontend_attach  = cxusb_mt352_frontend_attach,
 	.tuner_attach     = cxusb_dtt7579_tuner_attach,
 
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 5,
+		.endpoint = 0x04,
+		.u = {
+			.bulk = {
+				.buffersize = 8192,
+			}
+		}
+	},
+		},
+	},
+	.power_ctrl       = cxusb_bluebird_power_ctrl,
+
 	.i2c_algo         = &cxusb_i2c_algo,
 
 	.rc_interval      = 100,
@@ -715,17 +763,6 @@
 	.rc_query         = cxusb_rc_query,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 5,
-		.endpoint = 0x04,
-		.u = {
-			.bulk = {
-				.buffersize = 8192,
-			}
-		}
-	},
 
 	.num_device_descs = 1,
 	.devices = {
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
new file mode 100644
index 0000000..ac84347
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -0,0 +1,49 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *	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, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#ifndef _DIB0700_H_
+#define _DIB0700_H_
+
+#define DVB_USB_LOG_PREFIX "dib0700"
+#include "dvb-usb.h"
+
+#include "dib07x0.h"
+
+extern int dvb_usb_dib0700_debug;
+#define deb_info(args...)   dprintk(dvb_usb_dib0700_debug,0x01,args)
+#define deb_fw(args...)     dprintk(dvb_usb_dib0700_debug,0x02,args)
+#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
+#define deb_data(args...)   dprintk(dvb_usb_dib0700_debug,0x08,args)
+
+#define REQUEST_I2C_READ     0x2
+#define REQUEST_I2C_WRITE    0x3
+#define REQUEST_POLL_RC      0x4
+#define REQUEST_JUMPRAM      0x8
+#define REQUEST_SET_GPIO     0xC
+#define REQUEST_ENABLE_VIDEO 0xF
+	// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
+	// 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
+	// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
+
+struct dib0700_state {
+	u8 channel_state;
+	u16 mt2060_if1[2];
+};
+
+extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
+extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
+extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
+extern struct i2c_algorithm dib0700_i2c_algo;
+extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+			struct dvb_usb_device_description **desc, int *cold);
+
+extern int dib0700_device_count;
+extern struct dvb_usb_device_properties dib0700_devices[];
+extern struct usb_device_id dib0700_usb_id_table[];
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
new file mode 100644
index 0000000..dca6c69
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -0,0 +1,279 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *	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, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#include "dib0700.h"
+
+/* debug */
+int dvb_usb_dib0700_debug;
+module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
+
+/* expecting rx buffer: request data[0] data[1] ... data[2] */
+static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
+{
+	int status;
+
+	deb_data(">>> ");
+	debug_dump(tx,txlen,deb_data);
+
+	status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
+		tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
+		USB_CTRL_GET_TIMEOUT);
+
+	if (status != txlen)
+		deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);
+
+	return status < 0 ? status : 0;
+}
+
+/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
+static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+{
+	u16 index, value;
+	int status;
+
+	if (txlen < 2) {
+		err("tx buffer length is smaller than 2. Makes no sense.");
+		return -EINVAL;
+	}
+	if (txlen > 4) {
+		err("tx buffer length is larger than 4. Not supported.");
+		return -EINVAL;
+	}
+
+	deb_data(">>> ");
+	debug_dump(tx,txlen,deb_data);
+
+	value = ((txlen - 2) << 8) | tx[1];
+	index = 0;
+	if (txlen > 2)
+		index |= (tx[2] << 8);
+	if (txlen > 3)
+		index |= tx[3];
+
+	/* think about swapping here */
+	value = le16_to_cpu(value);
+	index = le16_to_cpu(index);
+
+	status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
+			USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
+			USB_CTRL_GET_TIMEOUT);
+
+	if (status < 0)
+		deb_info("ep 0 read error (status = %d)\n",status);
+
+	deb_data("<<< ");
+	debug_dump(rx,rxlen,deb_data);
+
+	return status; /* length in case of success */
+}
+
+int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
+{
+	u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) };
+	return dib0700_ctrl_wr(d,buf,3);
+}
+
+/*
+ * I2C master xfer function
+ */
+static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i,len;
+	u8 buf[255];
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	for (i = 0; i < num; i++) {
+		/* fill in the address */
+		buf[1] = (msg[i].addr << 1);
+		/* fill the buffer */
+		memcpy(&buf[2], msg[i].buf, msg[i].len);
+
+		/* write/read request */
+		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+			buf[0] = REQUEST_I2C_READ;
+			buf[1] |= 1;
+
+			/* special thing in the current firmware: when length is zero the read-failed */
+			if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) {
+				deb_info("I2C read failed on address %x\n", msg[i].addr);
+				break;
+			}
+
+			msg[i+1].len = len;
+
+			i++;
+		} else {
+			buf[0] = REQUEST_I2C_WRITE;
+			if (dib0700_ctrl_wr(d, buf, msg[i].len + 2) < 0)
+				break;
+		}
+	}
+
+	mutex_unlock(&d->i2c_mutex);
+	return i;
+}
+
+static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm dib0700_i2c_algo = {
+	.master_xfer   = dib0700_i2c_xfer,
+	.functionality = dib0700_i2c_func,
+};
+
+int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+			struct dvb_usb_device_description **desc, int *cold)
+{
+	u8 buf[3] = { REQUEST_SET_GPIO, 4, (GPIO_IN << 7) | (0 << 6) }; // GPIO4 is save - used for I2C
+	*cold = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+		buf[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, buf, 3, USB_CTRL_GET_TIMEOUT) != 3;
+
+	deb_info("cold: %d\n", *cold);
+	return 0;
+}
+
+static int dib0700_jumpram(struct usb_device *udev, u32 address)
+{
+	int ret, actlen;
+	u8 buf[8] = { REQUEST_JUMPRAM, 0, 0, 0,
+		(address >> 24) & 0xff,
+		(address >> 16) & 0xff,
+		(address >> 8)  & 0xff,
+		 address        & 0xff };
+
+	if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
+		deb_fw("jumpram to 0x%x failed\n",address);
+		return ret;
+	}
+	if (actlen != 8) {
+		deb_fw("jumpram to 0x%x failed\n",address);
+		return -EIO;
+	}
+	return 0;
+}
+
+int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
+{
+	struct hexline hx;
+	int pos = 0, ret, act_len;
+
+	u8 buf[260];
+
+	while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
+		deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",hx.addr, hx.len, hx.chk);
+
+		buf[0] = hx.len;
+		buf[1] = (hx.addr >> 8) & 0xff;
+		buf[2] =  hx.addr       & 0xff;
+		buf[3] = hx.type;
+		memcpy(&buf[4],hx.data,hx.len);
+		buf[4+hx.len] = hx.chk;
+
+		ret = usb_bulk_msg(udev,
+			usb_sndbulkpipe(udev, 0x01),
+			buf,
+			hx.len + 5,
+			&act_len,
+			1000);
+
+		if (ret < 0) {
+			err("firmware download failed at %d with %d",pos,ret);
+			return ret;
+		}
+	}
+
+	if (ret == 0) {
+		/* start the firmware */
+		if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
+			info("firmware started successfully.");
+			msleep(100);
+		}
+	} else
+		ret = -EIO;
+
+	return ret;
+}
+
+int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct dib0700_state *st = adap->dev->priv;
+	u8 b[4];
+
+	b[0] = REQUEST_ENABLE_VIDEO;
+	b[1] = 0x00;
+	b[2] = (0x01 << 4); /* Master mode */
+	b[3] = 0x00;
+
+	deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
+
+	if (onoff)
+		st->channel_state |=   1 << adap->id;
+	else
+		st->channel_state &= ~(1 << adap->id);
+
+	b[2] |= st->channel_state;
+
+	if (st->channel_state) /* if at least one channel is active */
+		b[1] = (0x01 << 4) | 0x00;
+
+	deb_info("data for streaming: %x %x\n",b[1],b[2]);
+
+	return dib0700_ctrl_wr(adap->dev, b, 4);
+}
+
+static int dib0700_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	int i;
+
+	for (i = 0; i < dib0700_device_count; i++)
+		if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, NULL) == 0)
+			return 0;
+
+	return -ENODEV;
+}
+
+static struct usb_driver dib0700_driver = {
+	.name       = "dvb_usb_dib0700",
+	.probe      = dib0700_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table   = dib0700_usb_id_table,
+};
+
+/* module stuff */
+static int __init dib0700_module_init(void)
+{
+	int result;
+	info("loaded with support for %d different device-types", dib0700_device_count);
+	if ((result = usb_register(&dib0700_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit dib0700_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&dib0700_driver);
+}
+
+module_init (dib0700_module_init);
+module_exit (dib0700_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
new file mode 100644
index 0000000..e473bfe
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -0,0 +1,212 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *	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, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#include "dib0700.h"
+
+#include "dib3000mc.h"
+#include "mt2060.h"
+
+static int force_lna_activation;
+module_param(force_lna_activation, int, 0644);
+MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
+		"if applicable for the device (default: 0=automatic/off).");
+
+/* Hauppauge Nova-T 500
+ *  has a LNA on GPIO0 which is enabled by setting 1 */
+static struct mt2060_config bristol_mt2060_config[2] = {
+	{
+		.i2c_address = 0x60,
+		.clock_out   = 3,
+	}, {
+		.i2c_address = 0x61,
+	}
+};
+
+static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
+	.band_caps = BAND_VHF | BAND_UHF,
+	.setup     = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
+
+	.agc1_max = 42598,
+	.agc1_min = 17694,
+	.agc2_max = 45875,
+	.agc2_min = 0,
+
+	.agc1_pt1 = 0,
+	.agc1_pt2 = 59,
+
+	.agc1_slope1 = 0,
+	.agc1_slope2 = 69,
+
+	.agc2_pt1 = 0,
+	.agc2_pt2 = 59,
+
+	.agc2_slope1 = 111,
+	.agc2_slope2 = 28,
+};
+
+static struct dib3000mc_config bristol_dib3000mc_config[2] = {
+	{	.agc          = &bristol_dib3000p_mt2060_agc_config,
+		.max_time     = 0x196,
+		.ln_adc_level = 0x1cc7,
+		.output_mpeg2_in_188_bytes = 1,
+	},
+	{	.agc          = &bristol_dib3000p_mt2060_agc_config,
+		.max_time     = 0x196,
+		.ln_adc_level = 0x1cc7,
+		.output_mpeg2_in_188_bytes = 1,
+	}
+};
+
+static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_state *st = adap->dev->priv;
+	if (adap->id == 0) {
+		dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(10);
+		dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
+		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
+		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
+
+		if (force_lna_activation)
+			dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+		else
+			dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
+
+		if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
+			dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
+			return -ENODEV;
+		}
+	}
+	st->mt2060_if1[adap->id] = 1220;
+	return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
+		(10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
+}
+
+static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_state *st = adap->dev->priv;
+	struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
+	return dvb_attach(mt2060_attach,adap->fe, tun_i2c, &bristol_mt2060_config[adap->id],
+		st->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0;
+}
+
+/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
+/*
+static struct mt2060_config stk7000p_mt2060_config = {
+	0x60
+};
+*/
+
+static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	/* unless there is no real power management in DVB - we leave the device on GPIO6 */
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
+
+//	adap->fe = dib7000m_attach(&adap->dev->i2c_adap, &stk7700p_dib7000m_config, 18);
+	return 0;
+}
+
+static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+//	tun_i2c = dib7000m_get_tuner_i2c_master(adap->fe, 1);
+//	return mt2060_attach(adap->fe, tun_i2c, &stk3000p_mt2060_config, if1);
+	return 0;
+}
+
+struct usb_device_id dib0700_usb_id_table[] = {
+		{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
+		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
+		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
+		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
+		{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
+		{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
+
+#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
+	.caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
+	.usb_ctrl          = DEVICE_SPECIFIC, \
+	.firmware          = "dvb-usb-dib0700-01.fw", \
+	.download_firmware = dib0700_download_firmware, \
+	.no_reconnect      = 1, \
+	.size_of_priv      = sizeof(struct dib0700_state), \
+	.i2c_algo          = &dib0700_i2c_algo, \
+	.identify_state    = dib0700_identify_state
+
+#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
+	.streaming_ctrl   = dib0700_streaming_ctrl, \
+	.stream = { \
+		.type = USB_BULK, \
+		.count = 4, \
+		.endpoint = ep, \
+		.u = { \
+			.bulk = { \
+				.buffersize = 39480, \
+			} \
+		} \
+	}
+
+struct dvb_usb_device_properties dib0700_devices[] = {
+	{
+		DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.frontend_attach  = stk7700p_frontend_attach,
+				.tuner_attach     = stk7700p_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+			},
+		},
+
+		.num_device_descs = 3,
+		.devices = {
+			{   "DiBcom STK7700P reference design",
+				{ &dib0700_usb_id_table[0], NULL },
+				{ NULL },
+			},
+			{   "Hauppauge Nova-T Stick",
+				{ &dib0700_usb_id_table[3], NULL },
+				{ NULL },
+			},
+			{   "AVerMedia AVerTV DVB-T Volar",
+				{ &dib0700_usb_id_table[4], NULL },
+				{ NULL },
+			},
+		}
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+		.num_adapters = 2,
+		.adapter = {
+			{
+				.frontend_attach  = bristol_frontend_attach,
+				.tuner_attach     = bristol_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+			}, {
+				.frontend_attach  = bristol_frontend_attach,
+				.tuner_attach     = bristol_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+			}
+		},
+
+		.num_device_descs = 1,
+		.devices = {
+			{   "Hauppauge Nova-T 500 Dual DVB-T",
+				{ &dib0700_usb_id_table[1], &dib0700_usb_id_table[2], NULL },
+				{ NULL },
+			},
+		}
+	}
+};
+
+int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
diff --git a/drivers/media/dvb/dvb-usb/dib07x0.h b/drivers/media/dvb/dvb-usb/dib07x0.h
new file mode 100644
index 0000000..7e62c10
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib07x0.h
@@ -0,0 +1,21 @@
+#ifndef _DIB07X0_H_
+#define _DIB07X0_H_
+
+enum dib07x0_gpios {
+	GPIO0  =  0,
+	GPIO1  =  2,
+	GPIO2  =  3,
+	GPIO3  =  4,
+	GPIO4  =  5,
+	GPIO5  =  6,
+	GPIO6  =  8,
+	GPIO7  = 10,
+	GPIO8  = 11,
+	GPIO9  = 14,
+	GPIO10 = 15,
+};
+
+#define GPIO_IN  0
+#define GPIO_OUT 1
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 124e25a..fd3a990 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -18,12 +18,12 @@
 #define deb_info(args...) dprintk(debug,0x01,args)
 
 /* common stuff used by the different dibusb modules */
-int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-	if (d->priv != NULL) {
-		struct dibusb_state *st = d->priv;
+	if (adap->priv != NULL) {
+		struct dibusb_state *st = adap->priv;
 		if (st->ops.fifo_ctrl != NULL)
-			if (st->ops.fifo_ctrl(d->fe,onoff)) {
+			if (st->ops.fifo_ctrl(adap->fe,onoff)) {
 				err("error while controlling the fifo of the demod.");
 				return -ENODEV;
 			}
@@ -32,23 +32,23 @@
 }
 EXPORT_SYMBOL(dibusb_streaming_ctrl);
 
-int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
 {
-	if (d->priv != NULL) {
-		struct dibusb_state *st = d->priv;
+	if (adap->priv != NULL) {
+		struct dibusb_state *st = adap->priv;
 		if (st->ops.pid_ctrl != NULL)
-			st->ops.pid_ctrl(d->fe,index,pid,onoff);
+			st->ops.pid_ctrl(adap->fe,index,pid,onoff);
 	}
 	return 0;
 }
 EXPORT_SYMBOL(dibusb_pid_filter);
 
-int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
+int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-	if (d->priv != NULL) {
-		struct dibusb_state *st = d->priv;
+	if (adap->priv != NULL) {
+		struct dibusb_state *st = adap->priv;
 		if (st->ops.pid_parse != NULL)
-			if (st->ops.pid_parse(d->fe,onoff) < 0)
+			if (st->ops.pid_parse(adap->fe,onoff) < 0)
 				err("could not handle pid_parser");
 	}
 	return 0;
@@ -68,24 +68,24 @@
 }
 EXPORT_SYMBOL(dibusb_power_ctrl);
 
-int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
 	u8 b[3] = { 0 };
 	int ret;
 
-	if ((ret = dibusb_streaming_ctrl(d,onoff)) < 0)
+	if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
 		return ret;
 
 	if (onoff) {
 		b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
 		b[1] = 0x00;
-		if ((ret = dvb_usb_generic_write(d,b,2)) < 0)
+		if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0)
 			return ret;
 	}
 
 	b[0] = DIBUSB_REQ_SET_IOCTL;
 	b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
-	return dvb_usb_generic_write(d,b,3);
+	return dvb_usb_generic_write(adap->dev,b,3);
 }
 EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
 
@@ -228,12 +228,12 @@
 	.output_mpeg2_in_188_bytes = 1,
 };
 
-int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
+int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	if (dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000P_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0 ||
-		dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000MC_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0) {
-		if (d->priv != NULL) {
-			struct dibusb_state *st = d->priv;
+	if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS,  &mod3000p_dib3000p_config)) != NULL ||
+		(adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
+		if (adap->priv != NULL) {
+			struct dibusb_state *st = adap->priv;
 			st->ops.pid_parse = dib3000mc_pid_parse;
 			st->ops.pid_ctrl  = dib3000mc_pid_control;
 		}
@@ -247,20 +247,19 @@
 	0x60
 };
 
-int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
+int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	struct dibusb_state *st = d->priv;
-	int ret;
+	struct dibusb_state *st = adap->priv;
 	u8 a,b;
 	u16 if1 = 1220;
 	struct i2c_adapter *tun_i2c;
 
 	// First IF calibration for Liteon Sticks
-	if (d->udev->descriptor.idVendor == USB_VID_LITEON &&
-		d->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
+	if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
+		adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
 
-		dibusb_read_eeprom_byte(d,0x7E,&a);
-		dibusb_read_eeprom_byte(d,0x7F,&b);
+		dibusb_read_eeprom_byte(adap->dev,0x7E,&a);
+		dibusb_read_eeprom_byte(adap->dev,0x7F,&b);
 
 		if (a == 0x00)
 			if1 += b;
@@ -269,14 +268,14 @@
 		else
 			warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
 
-	} else if (d->udev->descriptor.idVendor  == USB_VID_DIBCOM &&
-		   d->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
+	} else if (adap->dev->udev->descriptor.idVendor  == USB_VID_DIBCOM &&
+		   adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
 		u8 desc;
-		dibusb_read_eeprom_byte(d, 7, &desc);
+		dibusb_read_eeprom_byte(adap->dev, 7, &desc);
 		if (desc == 2) {
 			a = 127;
 			do {
-				dibusb_read_eeprom_byte(d, a, &desc);
+				dibusb_read_eeprom_byte(adap->dev, a, &desc);
 				a--;
 			} while (a > 7 && (desc == 0xff || desc == 0x00));
 			if (desc & 0x80)
@@ -286,15 +285,15 @@
 		}
 	}
 
-	tun_i2c = dib3000mc_get_tuner_i2c_master(d->fe, 1);
-	if ((ret = mt2060_attach(d->fe, tun_i2c, &stk3000p_mt2060_config, if1)) != 0) {
+	tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
+	if (dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) {
 		/* not found - use panasonic pll parameters */
-		if (dvb_pll_attach(d->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL)
+		if (dvb_attach(dvb_pll_attach, adap->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL)
 			return -ENOMEM;
 	} else {
 		st->mt2060_present = 1;
 		/* set the correct parameters for the dib3000p */
-		dib3000mc_set_config(d->fe, &stk3000p_dib3000p_config);
+		dib3000mc_set_config(adap->fe, &stk3000p_dib3000p_config);
 	}
 	return 0;
 }
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index effd34c..4fe363e 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -14,35 +14,35 @@
  */
 #include "dibusb.h"
 
-static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
+static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	struct dib3000_config demod_cfg;
-	struct dibusb_state *st = d->priv;
+	struct dibusb_state *st = adap->priv;
 
 	demod_cfg.demod_address = 0x8;
 
-	if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
+	if ((adap->fe = dib3000mb_attach(&demod_cfg,&adap->dev->i2c_adap,&st->ops)) == NULL)
 		return -ENODEV;
 
-	d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
-	d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+	adap->fe->ops.tuner_ops.init       = dvb_usb_tuner_init_i2c;
+	adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
 
-	d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
+	adap->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
 
 	return 0;
 }
 
-static int dibusb_thomson_tuner_attach(struct dvb_usb_device *d)
+static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	d->pll_addr = 0x61;
-	d->pll_desc = &dvb_pll_tua6010xs;
+	adap->pll_addr = 0x61;
+	adap->pll_desc = &dvb_pll_tua6010xs;
 	return 0;
 }
 
 /* Some of the Artec 1.1 device aren't equipped with the default tuner
  * (Thomson Cable), but with a Panasonic ENV77H11D5.  This function figures
  * this out. */
-static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
+static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
 {
 	u8 b[2] = { 0,0 }, b2[1];
 	int ret = 0;
@@ -54,36 +54,36 @@
 	/* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
 	msg[0].addr = msg[1].addr = 0x60;
 
-	if (d->tuner_pass_ctrl)
-		d->tuner_pass_ctrl(d->fe,1,msg[0].addr);
+	if (adap->tuner_pass_ctrl)
+		adap->tuner_pass_ctrl(adap->fe,1,msg[0].addr);
 
-	if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) {
+	if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
 		err("tuner i2c write failed.");
 		ret = -EREMOTEIO;
 	}
 
-	if (d->tuner_pass_ctrl)
-		d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
+	if (adap->tuner_pass_ctrl)
+		adap->tuner_pass_ctrl(adap->fe,0,msg[0].addr);
 
 	if (b2[0] == 0xfe) {
 		info("This device has the Thomson Cable onboard. Which is default.");
-		dibusb_thomson_tuner_attach(d);
+		dibusb_thomson_tuner_attach(adap);
 	} else {
 		u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
 		info("This device has the Panasonic ENV77H11D5 onboard.");
-		d->pll_addr = 0x60;
-		memcpy(d->pll_init,bpll,4);
-		d->pll_desc = &dvb_pll_tda665x;
+		adap->pll_addr = 0x60;
+		memcpy(adap->pll_init,bpll,4);
+		adap->pll_desc = &dvb_pll_tda665x;
 	}
 
 	return ret;
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties dibusb1_1_properties;
-static struct dvb_usb_properties dibusb1_1_an2235_properties;
-static struct dvb_usb_properties dibusb2_0b_properties;
-static struct dvb_usb_properties artec_t1_usb2_properties;
+static struct dvb_usb_device_properties dibusb1_1_properties;
+static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
+static struct dvb_usb_device_properties dibusb2_0b_properties;
+static struct dvb_usb_device_properties artec_t1_usb2_properties;
 
 static int dibusb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -150,23 +150,42 @@
 };
 MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
 
-static struct dvb_usb_properties dibusb1_1_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-	.pid_filter_count = 16,
+static struct dvb_usb_device_properties dibusb1_1_properties = {
+	.caps =  DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_AN2135,
 
 	.firmware = "dvb-usb-dibusb-5.0.0.11.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+			.pid_filter_count = 16,
 
 	.streaming_ctrl   = dibusb_streaming_ctrl,
 	.pid_filter       = dibusb_pid_filter,
 	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-	.power_ctrl       = dibusb_power_ctrl,
 	.frontend_attach  = dibusb_dib3000mb_frontend_attach,
 	.tuner_attach     = dibusb_tuner_probe_and_attach,
 
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+			.size_of_priv     = sizeof(struct dibusb_state),
+		}
+	},
+
+	.power_ctrl       = dibusb_power_ctrl,
+
 	.rc_interval      = DEFAULT_RC_INTERVAL,
 	.rc_key_map       = dibusb_rc_keys,
 	.rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
@@ -175,17 +194,6 @@
 	.i2c_algo         = &dibusb_i2c_algo,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x02,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
 
 	.num_device_descs = 9,
 	.devices = {
@@ -228,23 +236,40 @@
 	}
 };
 
-static struct dvb_usb_properties dibusb1_1_an2235_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-	.pid_filter_count = 16,
-
+static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 	.usb_ctrl = CYPRESS_AN2235,
 
 	.firmware = "dvb-usb-dibusb-an2235-01.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
+			.pid_filter_count = 16,
 
 	.streaming_ctrl   = dibusb_streaming_ctrl,
 	.pid_filter       = dibusb_pid_filter,
 	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-	.power_ctrl       = dibusb_power_ctrl,
 	.frontend_attach  = dibusb_dib3000mb_frontend_attach,
 	.tuner_attach     = dibusb_tuner_probe_and_attach,
 
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+			.size_of_priv     = sizeof(struct dibusb_state),
+		},
+	},
+	.power_ctrl       = dibusb_power_ctrl,
+
 	.rc_interval      = DEFAULT_RC_INTERVAL,
 	.rc_key_map       = dibusb_rc_keys,
 	.rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
@@ -253,17 +278,6 @@
 	.i2c_algo         = &dibusb_i2c_algo,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x02,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
 
 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
 	.num_device_descs = 2,
@@ -285,22 +299,39 @@
 	}
 };
 
-static struct dvb_usb_properties dibusb2_0b_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-	.pid_filter_count = 16,
+static struct dvb_usb_device_properties dibusb2_0b_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 
 	.firmware = "dvb-usb-adstech-usb2-02.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+			.pid_filter_count = 16,
 
 	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
 	.pid_filter       = dibusb_pid_filter,
 	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-	.power_ctrl       = dibusb2_0_power_ctrl,
 	.frontend_attach  = dibusb_dib3000mb_frontend_attach,
 	.tuner_attach     = dibusb_thomson_tuner_attach,
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+			.size_of_priv     = sizeof(struct dibusb_state),
+		}
+	},
+	.power_ctrl       = dibusb2_0_power_ctrl,
 
 	.rc_interval      = DEFAULT_RC_INTERVAL,
 	.rc_key_map       = dibusb_rc_keys,
@@ -310,17 +341,6 @@
 	.i2c_algo         = &dibusb_i2c_algo,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x06,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
 
 	.num_device_descs = 2,
 	.devices = {
@@ -336,22 +356,39 @@
 	}
 };
 
-static struct dvb_usb_properties artec_t1_usb2_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-	.pid_filter_count = 16,
+static struct dvb_usb_device_properties artec_t1_usb2_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 
 	.firmware = "dvb-usb-dibusb-6.0.0.8.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+			.pid_filter_count = 16,
 
 	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
 	.pid_filter       = dibusb_pid_filter,
 	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-	.power_ctrl       = dibusb2_0_power_ctrl,
 	.frontend_attach  = dibusb_dib3000mb_frontend_attach,
 	.tuner_attach     = dibusb_tuner_probe_and_attach,
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+			.size_of_priv     = sizeof(struct dibusb_state),
+		}
+	},
+	.power_ctrl       = dibusb2_0_power_ctrl,
 
 	.rc_interval      = DEFAULT_RC_INTERVAL,
 	.rc_key_map       = dibusb_rc_keys,
@@ -361,17 +398,6 @@
 	.i2c_algo         = &dibusb_i2c_algo,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x06,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
 
 	.num_device_descs = 1,
 	.devices = {
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index eca4082..a0fd37e 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -15,7 +15,7 @@
 #include "dibusb.h"
 
 /* USB Driver stuff */
-static struct dvb_usb_properties dibusb_mc_properties;
+static struct dvb_usb_device_properties dibusb_mc_properties;
 
 static int dibusb_mc_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -43,22 +43,39 @@
 };
 MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
 
-static struct dvb_usb_properties dibusb_mc_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-	.pid_filter_count = 32,
+static struct dvb_usb_device_properties dibusb_mc_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-dibusb-6.0.0.8.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
-
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+			.pid_filter_count = 32,
 	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
 	.pid_filter       = dibusb_pid_filter,
 	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-	.power_ctrl       = dibusb2_0_power_ctrl,
 	.frontend_attach  = dibusb_dib3000mc_frontend_attach,
 	.tuner_attach     = dibusb_dib3000mc_tuner_attach,
 
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+			.size_of_priv     = sizeof(struct dibusb_state),
+		}
+	},
+	.power_ctrl       = dibusb2_0_power_ctrl,
+
 	.rc_interval      = DEFAULT_RC_INTERVAL,
 	.rc_key_map       = dibusb_rc_keys,
 	.rc_key_map_size  = 111, /* FIXME */
@@ -67,17 +84,6 @@
 	.i2c_algo         = &dibusb_i2c_algo,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x06,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
 
 	.num_device_descs = 7,
 	.devices = {
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index a43f874..5153fb9 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -107,14 +107,15 @@
 
 extern struct i2c_algorithm dibusb_i2c_algo;
 
-extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *);
-extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *);
+extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *);
+extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *);
 
-extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int);
-extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int);
-extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int);
+extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int);
+extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int);
+extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int);
+extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int);
+
 extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
-extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int);
 extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
 
 #define DEFAULT_RC_INTERVAL 150
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 0158544..8fb3437 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -83,7 +83,7 @@
 
 /* Callbacks for DVB USB */
 static int digitv_identify_state (struct usb_device *udev, struct
-		dvb_usb_properties *props, struct dvb_usb_device_description **desc,
+		dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
 		int *cold)
 {
 	*cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
@@ -116,33 +116,33 @@
 
 static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
 {
-	struct dvb_usb_device *d = fe->dvb->priv;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
 	u8 b[5];
 	dvb_usb_tuner_calc_regs(fe,fep,b, 5);
-	return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
+	return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0);
 }
 
 static struct nxt6000_config digitv_nxt6000_config = {
 	.clock_inversion = 1,
 };
 
-static int digitv_frontend_attach(struct dvb_usb_device *d)
+static int digitv_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	if ((d->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &d->i2c_adap)) != NULL) {
-		d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+	if ((adap->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &adap->dev->i2c_adap)) != NULL) {
+		adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
 		return 0;
 	}
-	if ((d->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
-		d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
+	if ((adap->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &adap->dev->i2c_adap)) != NULL) {
+		adap->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
 		return 0;
 	}
 	return -EIO;
 }
 
-static int digitv_tuner_attach(struct dvb_usb_device *d)
+static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	d->pll_addr = 0x60;
-	d->pll_desc = &dvb_pll_tded4;
+	adap->pll_addr = 0x60;
+	adap->pll_desc = &dvb_pll_tded4;
 	return 0;
 }
 
@@ -238,7 +238,7 @@
 }
 
 /* DVB USB Driver stuff */
-static struct dvb_usb_properties digitv_properties;
+static struct dvb_usb_device_properties digitv_properties;
 
 static int digitv_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -265,30 +265,21 @@
 };
 MODULE_DEVICE_TABLE (usb, digitv_table);
 
-static struct dvb_usb_properties digitv_properties = {
+static struct dvb_usb_device_properties digitv_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-digitv-02.fw",
 
-	.size_of_priv     = 0,
-
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.frontend_attach  = digitv_frontend_attach,
 	.tuner_attach     = digitv_tuner_attach,
 
-	.rc_interval      = 1000,
-	.rc_key_map       = digitv_rc_keys,
-	.rc_key_map_size  = ARRAY_SIZE(digitv_rc_keys),
-	.rc_query         = digitv_rc_query,
-
-	.identify_state   = digitv_identify_state,
-
-	.i2c_algo         = &digitv_i2c_algo,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 7,
 		.endpoint = 0x02,
 		.u = {
@@ -297,6 +288,18 @@
 			}
 		}
 	},
+		}
+	},
+	.identify_state   = digitv_identify_state,
+
+	.rc_interval      = 1000,
+	.rc_key_map       = digitv_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(digitv_rc_keys),
+	.rc_query         = digitv_rc_query,
+
+	.i2c_algo         = &digitv_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
 
 	.num_device_descs = 1,
 	.devices = {
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 27af4e4..fa43a41 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -28,19 +28,19 @@
 	return 0;
 }
 
-static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
 	u8 b_streaming[2] = { SET_STREAMING, onoff };
 	u8 b_rst_pid = RESET_PID_FILTER;
 
-	dvb_usb_generic_write(d,b_streaming,2);
+	dvb_usb_generic_write(adap->dev, b_streaming, 2);
 
 	if (onoff == 0)
-		dvb_usb_generic_write(d,&b_rst_pid,1);
+		dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
 	return 0;
 }
 
-static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
 {
 	u8 b_pid[4];
 	pid = onoff ? pid : 0;
@@ -50,7 +50,7 @@
 	b_pid[2] = pid & 0xff;
 	b_pid[3] = (pid >> 8) & 0x1f;
 
-	return dvb_usb_generic_write(d,b_pid,4);
+	return dvb_usb_generic_write(adap->dev, b_pid, 4);
 }
 
 /* remote control */
@@ -86,16 +86,16 @@
 	return 0;
 }
 
-static int dtt200u_frontend_attach(struct dvb_usb_device *d)
+static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	d->fe = dtt200u_fe_attach(d);
+	adap->fe = dtt200u_fe_attach(adap->dev);
 	return 0;
 }
 
-static struct dvb_usb_properties dtt200u_properties;
-static struct dvb_usb_properties wt220u_fc_properties;
-static struct dvb_usb_properties wt220u_properties;
-static struct dvb_usb_properties wt220u_zl0353_properties;
+static struct dvb_usb_device_properties dtt200u_properties;
+static struct dvb_usb_device_properties wt220u_fc_properties;
+static struct dvb_usb_device_properties wt220u_properties;
+static struct dvb_usb_device_properties wt220u_zl0353_properties;
 
 static int dtt200u_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -123,28 +123,22 @@
 };
 MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
 
-static struct dvb_usb_properties dtt200u_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-	.pid_filter_count = 15,
-
+static struct dvb_usb_device_properties dtt200u_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-dtt200u-01.fw",
 
-	.power_ctrl      = dtt200u_power_ctrl,
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+			.pid_filter_count = 15,
+
 	.streaming_ctrl  = dtt200u_streaming_ctrl,
 	.pid_filter      = dtt200u_pid_filter,
 	.frontend_attach = dtt200u_frontend_attach,
-
-	.rc_interval     = 300,
-	.rc_key_map      = dtt200u_rc_keys,
-	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
-	.rc_query        = dtt200u_rc_query,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
-
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 7,
 		.endpoint = 0x02,
 		.u = {
@@ -153,6 +147,16 @@
 			}
 		}
 	},
+		}
+	},
+	.power_ctrl      = dtt200u_power_ctrl,
+
+	.rc_interval     = 300,
+	.rc_key_map      = dtt200u_rc_keys,
+	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+	.rc_query        = dtt200u_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
 
 	.num_device_descs = 1,
 	.devices = {
@@ -164,28 +168,22 @@
 	}
 };
 
-static struct dvb_usb_properties wt220u_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-	.pid_filter_count = 15,
-
+static struct dvb_usb_device_properties wt220u_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-wt220u-02.fw",
 
-	.power_ctrl      = dtt200u_power_ctrl,
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+			.pid_filter_count = 15,
+
 	.streaming_ctrl  = dtt200u_streaming_ctrl,
 	.pid_filter      = dtt200u_pid_filter,
 	.frontend_attach = dtt200u_frontend_attach,
-
-	.rc_interval     = 300,
-	.rc_key_map      = dtt200u_rc_keys,
-	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
-	.rc_query        = dtt200u_rc_query,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
-
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 7,
 		.endpoint = 0x02,
 		.u = {
@@ -194,6 +192,16 @@
 			}
 		}
 	},
+		}
+	},
+	.power_ctrl      = dtt200u_power_ctrl,
+
+	.rc_interval     = 300,
+	.rc_key_map      = dtt200u_rc_keys,
+	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+	.rc_query        = dtt200u_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
 
 	.num_device_descs = 1,
 	.devices = {
@@ -205,17 +213,33 @@
 	}
 };
 
-static struct dvb_usb_properties wt220u_fc_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-	.pid_filter_count = 15,
-
+static struct dvb_usb_device_properties wt220u_fc_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-wt220u-fc03.fw",
 
-	.power_ctrl      = dtt200u_power_ctrl,
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+			.pid_filter_count = 15,
+
 	.streaming_ctrl  = dtt200u_streaming_ctrl,
 	.pid_filter      = dtt200u_pid_filter,
 	.frontend_attach = dtt200u_frontend_attach,
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+				.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+		}
+	},
+	.power_ctrl      = dtt200u_power_ctrl,
 
 	.rc_interval     = 300,
 	.rc_key_map      = dtt200u_rc_keys,
@@ -224,18 +248,6 @@
 
 	.generic_bulk_ctrl_endpoint = 0x01,
 
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x86,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
-
 	.num_device_descs = 1,
 	.devices = {
 		{ .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
@@ -246,28 +258,22 @@
 	}
 };
 
-static struct dvb_usb_properties wt220u_zl0353_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-	.pid_filter_count = 15,
-
+static struct dvb_usb_device_properties wt220u_zl0353_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-wt220u-zl0353-01.fw",
 
-	.power_ctrl      = dtt200u_power_ctrl,
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+			.pid_filter_count = 15,
+
 	.streaming_ctrl  = dtt200u_streaming_ctrl,
 	.pid_filter      = dtt200u_pid_filter,
 	.frontend_attach = dtt200u_frontend_attach,
-
-	.rc_interval     = 300,
-	.rc_key_map      = dtt200u_rc_keys,
-	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
-	.rc_query        = dtt200u_rc_query,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
-
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 7,
 		.endpoint = 0x02,
 		.u = {
@@ -276,6 +282,16 @@
 			}
 		}
 	},
+		}
+	},
+	.power_ctrl      = dtt200u_power_ctrl,
+
+	.rc_interval     = 300,
+	.rc_key_map      = dtt200u_rc_keys,
+	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+	.rc_query        = dtt200u_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
 
 	.num_device_descs = 1,
 	.devices = {
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
index a3460bf..35ab68f 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -14,31 +14,36 @@
 extern int dvb_usb_debug;
 extern int dvb_usb_disable_rc_polling;
 
-#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
-#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
-#define deb_pll(args...)  dprintk(dvb_usb_debug,0x04,args)
-#define deb_ts(args...)   dprintk(dvb_usb_debug,0x08,args)
-#define deb_err(args...)  dprintk(dvb_usb_debug,0x10,args)
-#define deb_rc(args...)   dprintk(dvb_usb_debug,0x20,args)
-#define deb_fw(args...)   dprintk(dvb_usb_debug,0x40,args)
-#define deb_mem(args...)  dprintk(dvb_usb_debug,0x80,args)
+#define deb_info(args...)  dprintk(dvb_usb_debug,0x001,args)
+#define deb_xfer(args...)  dprintk(dvb_usb_debug,0x002,args)
+#define deb_pll(args...)   dprintk(dvb_usb_debug,0x004,args)
+#define deb_ts(args...)    dprintk(dvb_usb_debug,0x008,args)
+#define deb_err(args...)   dprintk(dvb_usb_debug,0x010,args)
+#define deb_rc(args...)    dprintk(dvb_usb_debug,0x020,args)
+#define deb_fw(args...)    dprintk(dvb_usb_debug,0x040,args)
+#define deb_mem(args...)   dprintk(dvb_usb_debug,0x080,args)
+#define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args)
 
 /* commonly used  methods */
-extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_properties *);
+extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *);
 
-extern int dvb_usb_urb_submit(struct dvb_usb_device *);
-extern int dvb_usb_urb_kill(struct dvb_usb_device *);
-extern int dvb_usb_urb_init(struct dvb_usb_device *);
-extern int dvb_usb_urb_exit(struct dvb_usb_device *);
+extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff);
+
+extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props);
+extern int usb_urb_exit(struct usb_data_stream *stream);
+extern int usb_urb_submit(struct usb_data_stream *stream);
+extern int usb_urb_kill(struct usb_data_stream *stream);
+
+extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap);
 
 extern int dvb_usb_i2c_init(struct dvb_usb_device *);
 extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
 
-extern int dvb_usb_dvb_init(struct dvb_usb_device *);
-extern int dvb_usb_dvb_exit(struct dvb_usb_device *);
-
-extern int dvb_usb_fe_init(struct dvb_usb_device *);
-extern int dvb_usb_fe_exit(struct dvb_usb_device *);
+extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap);
 
 extern int dvb_usb_remote_init(struct dvb_usb_device *);
 extern int dvb_usb_remote_exit(struct dvb_usb_device *);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index fe6208a..4561a67 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -1,6 +1,6 @@
 /* dvb-usb-dvb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for initializing and handling the
@@ -8,55 +8,55 @@
  */
 #include "dvb-usb-common.h"
 
+/* does the complete input transfer handling */
 static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
 {
-	struct dvb_usb_device *d = dvbdmxfeed->demux->priv;
+	struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
 	int newfeedcount,ret;
 
-	if (d == NULL)
+	if (adap == NULL)
 		return -ENODEV;
 
-	newfeedcount = d->feedcount + (onoff ? 1 : -1);
+	newfeedcount = adap->feedcount + (onoff ? 1 : -1);
 
-	/*
-	 * stop feed before setting a new pid if there will be no pid anymore
-	 */
+	/* stop feed before setting a new pid if there will be no pid anymore */
 	if (newfeedcount == 0) {
 		deb_ts("stop feeding\n");
-		dvb_usb_urb_kill(d);
+		usb_urb_kill(&adap->stream);
 
-		if (d->props.streaming_ctrl != NULL)
-			if ((ret = d->props.streaming_ctrl(d,0)))
+		if (adap->props.streaming_ctrl != NULL)
+			if ((ret = adap->props.streaming_ctrl(adap,0)))
 				err("error while stopping stream.");
-
 	}
 
-	d->feedcount = newfeedcount;
+	adap->feedcount = newfeedcount;
 
 	/* activate the pid on the device specific pid_filter */
-	deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
-	if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
-		d->pid_filtering &&
-		d->props.pid_filter != NULL)
-		d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+	deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",adap->pid_filtering ?
+		"yes" : "no", dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ?
+		"on" : "off");
+	if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+		adap->pid_filtering &&
+		adap->props.pid_filter != NULL)
+		adap->props.pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid,onoff);
 
 	/* start the feed if this was the first feed and there is still a feed
 	 * for reception.
 	 */
-	if (d->feedcount == onoff && d->feedcount > 0) {
+	if (adap->feedcount == onoff && adap->feedcount > 0) {
 		deb_ts("submitting all URBs\n");
-		dvb_usb_urb_submit(d);
+		usb_urb_submit(&adap->stream);
 
 		deb_ts("controlling pid parser\n");
-		if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
-			d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF &&
-			d->props.pid_filter_ctrl != NULL)
-			if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0)
+		if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+			adap->props.caps & DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+			adap->props.pid_filter_ctrl != NULL)
+			if (adap->props.pid_filter_ctrl(adap,adap->pid_filtering) < 0)
 				err("could not handle pid_parser");
 
 		deb_ts("start feeding\n");
-		if (d->props.streaming_ctrl != NULL)
-			if (d->props.streaming_ctrl(d,1)) {
+		if (adap->props.streaming_ctrl != NULL)
+			if (adap->props.streaming_ctrl(adap,1)) {
 				err("error while enabling fifo.");
 				return -ENODEV;
 			}
@@ -77,134 +77,130 @@
 	return dvb_usb_ctrl_feed(dvbdmxfeed,0);
 }
 
-int dvb_usb_dvb_init(struct dvb_usb_device *d)
+int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap)
 {
 	int ret;
 
-	if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
-			d->owner, &d->udev->dev)) < 0) {
+	if ((ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
+			adap->dev->owner, &adap->dev->udev->dev)) < 0) {
 		deb_info("dvb_register_adapter failed: error %d", ret);
 		goto err;
 	}
-	d->dvb_adap.priv = d;
+	adap->dvb_adap.priv = adap;
 
-	if (d->props.read_mac_address) {
-		if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0)
-			info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0],
-					d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2],
-					d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4],
-					d->dvb_adap.proposed_mac[5]);
+	if (adap->dev->props.read_mac_address) {
+		if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
+			info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",adap->dvb_adap.proposed_mac[0],
+					adap->dvb_adap.proposed_mac[1], adap->dvb_adap.proposed_mac[2],
+					adap->dvb_adap.proposed_mac[3], adap->dvb_adap.proposed_mac[4],
+					adap->dvb_adap.proposed_mac[5]);
 		else
 			err("MAC address reading failed.");
 	}
 
 
-	d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-	d->demux.priv = d;
+	adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+	adap->demux.priv             = adap;
 
-	d->demux.feednum = d->demux.filternum = d->max_feed_count;
-	d->demux.start_feed = dvb_usb_start_feed;
-	d->demux.stop_feed  = dvb_usb_stop_feed;
-	d->demux.write_to_decoder = NULL;
-	if ((ret = dvb_dmx_init(&d->demux)) < 0) {
+	adap->demux.feednum          = adap->demux.filternum = adap->max_feed_count;
+	adap->demux.start_feed       = dvb_usb_start_feed;
+	adap->demux.stop_feed        = dvb_usb_stop_feed;
+	adap->demux.write_to_decoder = NULL;
+	if ((ret = dvb_dmx_init(&adap->demux)) < 0) {
 		err("dvb_dmx_init failed: error %d",ret);
 		goto err_dmx;
 	}
 
-	d->dmxdev.filternum = d->demux.filternum;
-	d->dmxdev.demux = &d->demux.dmx;
-	d->dmxdev.capabilities = 0;
-	if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) {
+	adap->dmxdev.filternum       = adap->demux.filternum;
+	adap->dmxdev.demux           = &adap->demux.dmx;
+	adap->dmxdev.capabilities    = 0;
+	if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) {
 		err("dvb_dmxdev_init failed: error %d",ret);
 		goto err_dmx_dev;
 	}
 
-	dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
+	dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
 
-	d->state |= DVB_USB_STATE_DVB;
+	adap->state |= DVB_USB_ADAP_STATE_DVB;
 	return 0;
 
 err_dmx_dev:
-	dvb_dmx_release(&d->demux);
+	dvb_dmx_release(&adap->demux);
 err_dmx:
-	dvb_unregister_adapter(&d->dvb_adap);
+	dvb_unregister_adapter(&adap->dvb_adap);
 err:
 	return ret;
 }
 
-int dvb_usb_dvb_exit(struct dvb_usb_device *d)
+int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap)
 {
-	if (d->state & DVB_USB_STATE_DVB) {
+	if (adap->state & DVB_USB_ADAP_STATE_DVB) {
 		deb_info("unregistering DVB part\n");
-		dvb_net_release(&d->dvb_net);
-		d->demux.dmx.close(&d->demux.dmx);
-		dvb_dmxdev_release(&d->dmxdev);
-		dvb_dmx_release(&d->demux);
-		dvb_unregister_adapter(&d->dvb_adap);
-		d->state &= ~DVB_USB_STATE_DVB;
+		dvb_net_release(&adap->dvb_net);
+		adap->demux.dmx.close(&adap->demux.dmx);
+		dvb_dmxdev_release(&adap->dmxdev);
+		dvb_dmx_release(&adap->demux);
+		dvb_unregister_adapter(&adap->dvb_adap);
+		adap->state &= ~DVB_USB_ADAP_STATE_DVB;
 	}
 	return 0;
 }
 
 static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
 {
-	struct dvb_usb_device *d = fe->dvb->priv;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
 
-	if (d->props.power_ctrl)
-		d->props.power_ctrl(d,1);
+	dvb_usb_device_power_ctrl(adap->dev, 1);
 
-	if (d->fe_init)
-		d->fe_init(fe);
+	if (adap->fe_init)
+		adap->fe_init(fe);
 
 	return 0;
 }
 
 static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
 {
-	struct dvb_usb_device *d = fe->dvb->priv;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
 
-	if (d->fe_sleep)
-		d->fe_sleep(fe);
+	if (adap->fe_sleep)
+		adap->fe_sleep(fe);
 
-	if (d->props.power_ctrl)
-		d->props.power_ctrl(d,0);
-
-	return 0;
+	return dvb_usb_device_power_ctrl(adap->dev, 0);
 }
 
-int dvb_usb_fe_init(struct dvb_usb_device* d)
+int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
 {
-	if (d->props.frontend_attach == NULL) {
-		err("strange: '%s' doesn't want to attach a frontend.",d->desc->name);
+	if (adap->props.frontend_attach == NULL) {
+		err("strange: '%s' #%d doesn't want to attach a frontend.",adap->dev->desc->name, adap->id);
 		return 0;
 	}
 
 	/* re-assign sleep and wakeup functions */
-	if (d->props.frontend_attach(d) == 0 && d->fe != NULL) {
-		d->fe_init = d->fe->ops.init;   d->fe->ops.init  = dvb_usb_fe_wakeup;
-		d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep;
+	if (adap->props.frontend_attach(adap) == 0 && adap->fe != NULL) {
+		adap->fe_init  = adap->fe->ops.init;  adap->fe->ops.init  = dvb_usb_fe_wakeup;
+		adap->fe_sleep = adap->fe->ops.sleep; adap->fe->ops.sleep = dvb_usb_fe_sleep;
 
-		if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
 			err("Frontend registration failed.");
-			dvb_frontend_detach(d->fe);
-			d->fe = NULL;
+			dvb_frontend_detach(adap->fe);
+			adap->fe = NULL;
 			return -ENODEV;
 		}
 
 		/* only attach the tuner if the demod is there */
-		if (d->props.tuner_attach != NULL)
-			d->props.tuner_attach(d);
+		if (adap->props.tuner_attach != NULL)
+			adap->props.tuner_attach(adap);
 	} else
-		err("no frontend was attached by '%s'",d->desc->name);
+		err("no frontend was attached by '%s'",adap->dev->desc->name);
 
 	return 0;
 }
 
-int dvb_usb_fe_exit(struct dvb_usb_device *d)
+int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
 {
-	if (d->fe != NULL) {
-		dvb_unregister_frontend(d->fe);
-		dvb_frontend_detach(d->fe);
+	if (adap->fe != NULL) {
+		dvb_unregister_frontend(adap->fe);
+		dvb_frontend_detach(adap->fe);
 	}
 	return 0;
 }
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
index 9222b0a..e1112e3 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -1,6 +1,6 @@
 /* dvb-usb-firmware.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
@@ -24,9 +24,6 @@
 	{ .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
 };
 
-static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
-			       int *pos);
-
 /*
  * load a firmware packet to the device
  */
@@ -78,7 +75,7 @@
 }
 EXPORT_SYMBOL(usb_cypress_load_firmware);
 
-int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties *props)
+int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props)
 {
 	int ret;
 	const struct firmware *fw = NULL;
@@ -115,7 +112,7 @@
 	return ret;
 }
 
-static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
 			       int *pos)
 {
 	u8 *b = (u8 *) &fw->data[*pos];
@@ -146,3 +143,4 @@
 
 	return *pos;
 }
+EXPORT_SYMBOL(dvb_usb_get_hexline);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 6b611a7..55ba020 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -1,6 +1,6 @@
 /* dvb-usb-i2c.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for (de-)initializing an I2C adapter.
@@ -48,48 +48,48 @@
 
 int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe)
 {
-	struct dvb_usb_device *d = fe->dvb->priv;
-	struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct i2c_msg msg = { .addr = adap->pll_addr, .flags = 0, .buf = adap->pll_init, .len = 4 };
 	int ret = 0;
 
 	/* if pll_desc is not used */
-	if (d->pll_desc == NULL)
+	if (adap->pll_desc == NULL)
 		return 0;
 
-	if (d->tuner_pass_ctrl)
-		d->tuner_pass_ctrl(fe,1,d->pll_addr);
+	if (adap->tuner_pass_ctrl)
+		adap->tuner_pass_ctrl(fe, 1, adap->pll_addr);
 
-	deb_pll("pll init: %x\n",d->pll_addr);
-	deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
-			d->pll_init[2],d->pll_init[3]);
+	deb_pll("pll init: %x\n",adap->pll_addr);
+	deb_pll("pll-buf: %x %x %x %x\n",adap->pll_init[0], adap->pll_init[1],
+			adap->pll_init[2], adap->pll_init[3]);
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+	if (i2c_transfer (&adap->dev->i2c_adap, &msg, 1) != 1) {
 		err("tuner i2c write failed for pll_init.");
 		ret = -EREMOTEIO;
 	}
 	msleep(1);
 
-	if (d->tuner_pass_ctrl)
-		d->tuner_pass_ctrl(fe,0,d->pll_addr);
+	if (adap->tuner_pass_ctrl)
+		adap->tuner_pass_ctrl(fe,0,adap->pll_addr);
 	return ret;
 }
 EXPORT_SYMBOL(dvb_usb_tuner_init_i2c);
 
 int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len)
 {
-	struct dvb_usb_device *d = fe->dvb->priv;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
 
 	if (buf_len != 5)
 		return -EINVAL;
-	if (d->pll_desc == NULL)
+	if (adap->pll_desc == NULL)
 		return 0;
 
-	deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
+	deb_pll("pll addr: %x, freq: %d %p\n",adap->pll_addr, fep->frequency, adap->pll_desc);
 
-	b[0] = d->pll_addr;
-	dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
+	b[0] = adap->pll_addr;
+	dvb_pll_configure(adap->pll_desc, &b[1], fep->frequency, fep->u.ofdm.bandwidth);
 
 	deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
 
@@ -99,26 +99,27 @@
 
 int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
 {
-	struct dvb_usb_device *d = fe->dvb->priv;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
 	int ret = 0;
 	u8 b[5];
-	struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
+	struct i2c_msg msg = { .addr = adap->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
 
 	dvb_usb_tuner_calc_regs(fe,fep,b,5);
 
-	if (d->tuner_pass_ctrl)
-		d->tuner_pass_ctrl(fe,1,d->pll_addr);
+	if (adap->tuner_pass_ctrl)
+		adap->tuner_pass_ctrl(fe, 1, adap->pll_addr);
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+
+	if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) {
 		err("tuner i2c write failed for pll_set.");
 		ret = -EREMOTEIO;
 	}
 	msleep(1);
 
-	if (d->tuner_pass_ctrl)
-		d->tuner_pass_ctrl(fe,0,d->pll_addr);
+	if (adap->tuner_pass_ctrl)
+		adap->tuner_pass_ctrl(fe, 0, adap->pll_addr);
 
 	return ret;
 }
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 57a10de..4d6b069 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -52,8 +52,7 @@
 #define USB_PID_DIBCOM_MOD3000_WARM			0x0bb9
 #define USB_PID_DIBCOM_MOD3001_COLD			0x0bc6
 #define USB_PID_DIBCOM_MOD3001_WARM			0x0bc7
-#define USB_PID_DIBCOM_STK7700				0x1e14
-#define USB_PID_DIBCOM_STK7700_REENUM			0x1e15
+#define USB_PID_DIBCOM_STK7700P				0x1e14
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD			0x2131
 #define USB_PID_GRANDTEC_DVBT_USB_COLD			0x0fa0
 #define USB_PID_GRANDTEC_DVBT_USB_WARM			0x0fa1
@@ -95,6 +94,10 @@
 #define USB_PID_WT220U_ZL0353_WARM			0x022b
 #define USB_PID_WINTV_NOVA_T_USB2_COLD			0x9300
 #define USB_PID_WINTV_NOVA_T_USB2_WARM			0x9301
+#define USB_PID_HAUPPAUGE_NOVA_T_500			0x9941
+#define USB_PID_HAUPPAUGE_NOVA_T_500_2			0x9950
+#define USB_PID_HAUPPAUGE_NOVA_T_STICK			0x7050
+#define USB_PID_AVERMEDIA_VOLAR				0x1234
 #define USB_PID_NEBULA_DIGITV				0x0201
 #define USB_PID_DVICO_BLUEBIRD_LGDT			0xd820
 #define USB_PID_DVICO_BLUEBIRD_LG064F_COLD		0xd500
@@ -103,10 +106,12 @@
 #define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM		0xdb01
 #define USB_PID_DVICO_BLUEBIRD_TH7579_COLD		0xdb10
 #define USB_PID_DVICO_BLUEBIRD_TH7579_WARM		0xdb11
-#define USB_PID_DVICO_BLUEBIRD_DEE1601_COLD		0xdb50
-#define USB_PID_DVICO_BLUEBIRD_DEE1601_WARM		0xdb51
-#define USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_COLD	0xdb54
-#define USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_WARM	0xdb55
+#define USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD		0xdb50
+#define USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM		0xdb51
+#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD		0xdb58
+#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM		0xdb59
+#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD	0xdb54
+#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM	0xdb55
 #define USB_PID_MEDION_MD95700				0x0932
 #define USB_PID_KYE_DVB_T_COLD				0x701e
 #define USB_PID_KYE_DVB_T_WARM				0x701f
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index a1705ec..ffdde83 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -3,7 +3,7 @@
  *
  * dvb-usb-init.c
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  *	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
@@ -16,21 +16,105 @@
 /* debug */
 int dvb_usb_debug;
 module_param_named(debug,dvb_usb_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256  (or-able))." DVB_USB_DEBUG_STATUS);
 
 int dvb_usb_disable_rc_polling;
 module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
 MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
 
+static int dvb_usb_force_pid_filter_usage;
+module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
+MODULE_PARM_DESC(disable_rc_polling, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
+
+static int dvb_usb_adapter_init(struct dvb_usb_device *d)
+{
+	struct dvb_usb_adapter *adap;
+	int ret,n;
+
+	for (n = 0; n < d->props.num_adapters; n++) {
+		adap = &d->adapter[n];
+		adap->dev = d;
+		adap->id  = n;
+
+		memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties));
+
+/* speed - when running at FULL speed we need a HW PID filter */
+		if (d->udev->speed == USB_SPEED_FULL && !(adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
+			err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
+			return -ENODEV;
+		}
+
+		if ((d->udev->speed == USB_SPEED_FULL && adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
+			(adap->props.caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
+			info("will use the device's hardware PID filter (table count: %d).",adap->props.pid_filter_count);
+			adap->pid_filtering  = 1;
+			adap->max_feed_count = adap->props.pid_filter_count;
+		} else {
+			info("will pass the complete MPEG2 transport stream to the software demuxer.");
+			adap->pid_filtering  = 0;
+			adap->max_feed_count = 255;
+		}
+
+		if (!adap->pid_filtering &&
+			dvb_usb_force_pid_filter_usage &&
+			adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) {
+			info("pid filter enabled by module option.");
+			adap->pid_filtering  = 1;
+			adap->max_feed_count = adap->props.pid_filter_count;
+		}
+
+		if (adap->props.size_of_priv > 0) {
+			adap->priv = kzalloc(adap->props.size_of_priv,GFP_KERNEL);
+			if (adap->priv == NULL) {
+				err("no memory for priv for adapter %d.",n);
+				return -ENOMEM;
+			}
+		}
+
+		if ((ret = dvb_usb_adapter_stream_init(adap)) ||
+			(ret = dvb_usb_adapter_dvb_init(adap)) ||
+			(ret = dvb_usb_adapter_frontend_init(adap))) {
+			return ret;
+		}
+
+		d->num_adapters_initialized++;
+		d->state |= DVB_USB_STATE_DVB;
+	}
+
+	/*
+	 * when reloading the driver w/o replugging the device
+	 * sometimes a timeout occures, this helps
+	 */
+	if (d->props.generic_bulk_ctrl_endpoint != 0) {
+		usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+		usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+	}
+
+	return 0;
+}
+
+static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
+{
+	int n;
+	for (n = 0; n < d->num_adapters_initialized; n++) {
+		dvb_usb_adapter_frontend_exit(&d->adapter[n]);
+		dvb_usb_adapter_dvb_exit(&d->adapter[n]);
+		dvb_usb_adapter_stream_exit(&d->adapter[n]);
+		kfree(d->adapter[n].priv);
+	}
+	d->num_adapters_initialized = 0;
+	d->state &= ~DVB_USB_STATE_DVB;
+	return 0;
+}
+
+
 /* general initialization functions */
 static int dvb_usb_exit(struct dvb_usb_device *d)
 {
 	deb_info("state before exiting everything: %x\n",d->state);
 	dvb_usb_remote_exit(d);
-	dvb_usb_fe_exit(d);
+	dvb_usb_adapter_exit(d);
 	dvb_usb_i2c_exit(d);
-	dvb_usb_dvb_exit(d);
-	dvb_usb_urb_exit(d);
 	deb_info("state should be zero now: %x\n",d->state);
 	d->state = DVB_USB_STATE_INIT;
 	kfree(d->priv);
@@ -47,32 +131,19 @@
 
 	d->state = DVB_USB_STATE_INIT;
 
+	if (d->props.size_of_priv > 0) {
+		d->priv = kzalloc(d->props.size_of_priv,GFP_KERNEL);
+		if (d->priv == NULL) {
+			err("no memory for priv in 'struct dvb_usb_device'");
+			return -ENOMEM;
+		}
+	}
+
 /* check the capabilities and set appropriate variables */
+	dvb_usb_device_power_ctrl(d, 1);
 
-/* speed - when running at FULL speed we need a HW PID filter */
-	if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
-		err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
-		return -ENODEV;
-	}
-
-	if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) ||
-		(d->props.caps & DVB_USB_NEED_PID_FILTERING)) {
-		info("will use the device's hardware PID filter (table count: %d).",d->props.pid_filter_count);
-		d->pid_filtering = 1;
-		d->max_feed_count = d->props.pid_filter_count;
-	} else {
-		info("will pass the complete MPEG2 transport stream to the software demuxer.");
-		d->pid_filtering = 0;
-		d->max_feed_count = 255;
-	}
-
-	if (d->props.power_ctrl)
-		d->props.power_ctrl(d,1);
-
-	if ((ret = dvb_usb_urb_init(d)) ||
-		(ret = dvb_usb_dvb_init(d)) ||
-		(ret = dvb_usb_i2c_init(d)) ||
-		(ret = dvb_usb_fe_init(d))) {
+	if ((ret = dvb_usb_i2c_init(d)) ||
+		(ret = dvb_usb_adapter_init(d))) {
 		dvb_usb_exit(d);
 		return ret;
 	}
@@ -80,14 +151,13 @@
 	if ((ret = dvb_usb_remote_init(d)))
 		err("could not initialize remote control.");
 
-	if (d->props.power_ctrl)
-		d->props.power_ctrl(d,0);
+	dvb_usb_device_power_ctrl(d, 0);
 
 	return 0;
 }
 
 /* determine the name and the state of the just found USB device */
-static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold)
+static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_device_properties *props, int *cold)
 {
 	int i,j;
 	struct dvb_usb_device_description *desc = NULL;
@@ -125,11 +195,25 @@
 	return desc;
 }
 
+int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	if (onoff)
+		d->powered++;
+	else
+		d->powered--;
+
+	if (d->powered == 0 || (onoff && d->powered == 1)) { // when switching from 1 to 0 or from 0 to 1
+		deb_info("power control: %d\n", onoff);
+		if (d->props.power_ctrl)
+			return d->props.power_ctrl(d, onoff);
+	}
+	return 0;
+}
+
 /*
  * USB
  */
-
-int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
+int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_device_properties
 		*props, struct module *owner,struct dvb_usb_device **du)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
@@ -149,7 +233,7 @@
 	if (cold) {
 		info("found a '%s' in cold state, will try to load a firmware",desc->name);
 		ret = dvb_usb_download_firmware(udev,props);
-		if (!props->no_reconnect)
+		if (!props->no_reconnect || ret != 0)
 			return ret;
 	}
 
@@ -161,19 +245,10 @@
 	}
 
 	d->udev = udev;
-	memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
+	memcpy(&d->props,props,sizeof(struct dvb_usb_device_properties));
 	d->desc = desc;
 	d->owner = owner;
 
-	if (d->props.size_of_priv > 0) {
-			d->priv = kzalloc(d->props.size_of_priv,GFP_KERNEL);
-		if (d->priv == NULL) {
-			err("no memory for priv in 'struct dvb_usb_device'");
-			kfree(d);
-			return -ENOMEM;
-		}
-	}
-
 	usb_set_intfdata(intf, d);
 
 	if (du != NULL)
@@ -204,7 +279,7 @@
 }
 EXPORT_SYMBOL(dvb_usb_device_exit);
 
-MODULE_VERSION("0.3");
+MODULE_VERSION("1.0");
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
 MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 380b2a4..0a3a0b6 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -1,6 +1,6 @@
 /* dvb-usb-remote.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for initializing the the input-device and for handling remote-control-queries.
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index 88b2837..5cef12a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -1,9 +1,9 @@
 /* dvb-usb-urb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
- * This file contains functions for initializing and handling the
+ * This file keeps functions for initializing and handling the
  * USB and URB stuff.
  */
 #include "dvb-usb-common.h"
@@ -64,260 +64,32 @@
 }
 EXPORT_SYMBOL(dvb_usb_generic_write);
 
-
-/* URB stuff for streaming */
-static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length)
 {
-	struct dvb_usb_device *d = urb->context;
-	int ptype = usb_pipetype(urb->pipe);
-	int i;
-	u8 *b;
-
-	deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
-			ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
-			urb->status,urb->actual_length,urb->transfer_buffer_length,
-			urb->number_of_packets,urb->error_count);
-
-	switch (urb->status) {
-		case 0:         /* success */
-			break;
-		case -ECONNRESET:   /* kill */
-		case -ENOENT:
-		case -ESHUTDOWN:
-			return;
-		default:        /* error */
-			deb_ts("urb completition error %d.", urb->status);
-			break;
-	}
-
-	if (d->feedcount > 0) {
-		if (d->state & DVB_USB_STATE_DVB) {
-			switch (ptype) {
-				case PIPE_ISOCHRONOUS:
-					b = (u8 *) urb->transfer_buffer;
-					for (i = 0; i < urb->number_of_packets; i++) {
-						if (urb->iso_frame_desc[i].status != 0)
-							deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
-						else if (urb->iso_frame_desc[i].actual_length > 0) {
-								dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
-										urb->iso_frame_desc[i].actual_length);
-							}
-						urb->iso_frame_desc[i].status = 0;
-						urb->iso_frame_desc[i].actual_length = 0;
-					}
-					debug_dump(b,20,deb_ts);
-					break;
-				case PIPE_BULK:
-					if (urb->actual_length > 0)
-						dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
-					break;
-				default:
-					err("unkown endpoint type in completition handler.");
-					return;
-			}
-		}
-	}
-
-	usb_submit_urb(urb,GFP_ATOMIC);
+	struct dvb_usb_adapter *adap = stream->user_priv;
+	if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
+		dvb_dmx_swfilter(&adap->demux, buffer, length);
 }
 
-int dvb_usb_urb_kill(struct dvb_usb_device *d)
+static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length)
 {
-	int i;
-	for (i = 0; i < d->urbs_submitted; i++) {
-		deb_ts("killing URB no. %d.\n",i);
-
-		/* stop the URB */
-		usb_kill_urb(d->urb_list[i]);
-	}
-	d->urbs_submitted = 0;
-	return 0;
+	struct dvb_usb_adapter *adap = stream->user_priv;
+	if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
+		dvb_dmx_swfilter_204(&adap->demux, buffer, length);
 }
 
-int dvb_usb_urb_submit(struct dvb_usb_device *d)
+int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
 {
-	int i,ret;
-	for (i = 0; i < d->urbs_initialized; i++) {
-		deb_ts("submitting URB no. %d\n",i);
-		if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
-			err("could not submit URB no. %d - get them all back",i);
-			dvb_usb_urb_kill(d);
-			return ret;
-		}
-		d->urbs_submitted++;
-	}
-	return 0;
+	adap->stream.udev      = adap->dev->udev;
+	if (adap->props.caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
+		adap->stream.complete = dvb_usb_data_complete_204;
+	else
+	adap->stream.complete  = dvb_usb_data_complete;
+	adap->stream.user_priv = adap;
+	return usb_urb_init(&adap->stream, &adap->props.stream);
 }
 
-static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
+int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
 {
-	if (d->state & DVB_USB_STATE_URB_BUF) {
-		while (d->buf_num) {
-			d->buf_num--;
-			deb_mem("freeing buffer %d\n",d->buf_num);
-			usb_buffer_free(d->udev, d->buf_size,
-					d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
-		}
-		kfree(d->buf_list);
-		kfree(d->dma_addr);
-	}
-
-	d->state &= ~DVB_USB_STATE_URB_BUF;
-
-	return 0;
-}
-
-static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
-{
-	d->buf_num = 0;
-	d->buf_size = size;
-
-	deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
-
-	if ((d->buf_list = kcalloc(num, sizeof(u8 *), GFP_ATOMIC)) == NULL)
-		return -ENOMEM;
-
-	if ((d->dma_addr = kcalloc(num, sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
-		kfree(d->buf_list);
-		return -ENOMEM;
-	}
-
-	d->state |= DVB_USB_STATE_URB_BUF;
-
-	for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
-		deb_mem("allocating buffer %d\n",d->buf_num);
-		if (( d->buf_list[d->buf_num] =
-					usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
-					&d->dma_addr[d->buf_num]) ) == NULL) {
-			deb_mem("not enough memory for urb-buffer allocation.\n");
-			dvb_usb_free_stream_buffers(d);
-			return -ENOMEM;
-		}
-		deb_mem("buffer %d: %p (dma: %llu)\n",
-			d->buf_num, d->buf_list[d->buf_num],
-			(unsigned long long)d->dma_addr[d->buf_num]);
-		memset(d->buf_list[d->buf_num],0,size);
-	}
-	deb_mem("allocation successful\n");
-
-	return 0;
-}
-
-static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
-{
-	int i;
-
-	if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
-					d->props.urb.u.bulk.buffersize)) < 0)
-		return i;
-
-	/* allocate the URBs */
-	for (i = 0; i < d->props.urb.count; i++) {
-		if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
-			return -ENOMEM;
-
-		usb_fill_bulk_urb( d->urb_list[i], d->udev,
-				usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
-				d->buf_list[i],
-				d->props.urb.u.bulk.buffersize,
-				dvb_usb_urb_complete, d);
-
-		d->urb_list[i]->transfer_flags = 0;
-		d->urbs_initialized++;
-	}
-	return 0;
-}
-
-static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
-{
-	int i,j;
-
-	if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
-					d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
-		return i;
-
-	/* allocate the URBs */
-	for (i = 0; i < d->props.urb.count; i++) {
-		struct urb *urb;
-		int frame_offset = 0;
-		if ((d->urb_list[i] =
-					usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
-			return -ENOMEM;
-
-		urb = d->urb_list[i];
-
-		urb->dev = d->udev;
-		urb->context = d;
-		urb->complete = dvb_usb_urb_complete;
-		urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
-		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-		urb->interval = d->props.urb.u.isoc.interval;
-		urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
-		urb->transfer_buffer_length = d->buf_size;
-		urb->transfer_buffer = d->buf_list[i];
-		urb->transfer_dma = d->dma_addr[i];
-
-		for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
-			urb->iso_frame_desc[j].offset = frame_offset;
-			urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
-			frame_offset += d->props.urb.u.isoc.framesize;
-		}
-
-		d->urbs_initialized++;
-	}
-	return 0;
-
-}
-
-int dvb_usb_urb_init(struct dvb_usb_device *d)
-{
-	/*
-	 * when reloading the driver w/o replugging the device
-	 * sometimes a timeout occures, this helps
-	 */
-	if (d->props.generic_bulk_ctrl_endpoint != 0) {
-		usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
-		usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
-	}
-	usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
-
-	/* allocate the array for the data transfer URBs */
-	d->urb_list = kzalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
-	if (d->urb_list == NULL)
-		return -ENOMEM;
-	d->state |= DVB_USB_STATE_URB_LIST;
-
-	switch (d->props.urb.type) {
-		case DVB_USB_BULK:
-			return dvb_usb_bulk_urb_init(d);
-		case DVB_USB_ISOC:
-			return dvb_usb_isoc_urb_init(d);
-		default:
-			err("unkown URB-type for data transfer.");
-			return -EINVAL;
-	}
-}
-
-int dvb_usb_urb_exit(struct dvb_usb_device *d)
-{
-	int i;
-
-	dvb_usb_urb_kill(d);
-
-	if (d->state & DVB_USB_STATE_URB_LIST) {
-		for (i = 0; i < d->urbs_initialized; i++) {
-			if (d->urb_list[i] != NULL) {
-				deb_mem("freeing URB no. %d.\n",i);
-				/* free the URBs */
-				usb_free_urb(d->urb_list[i]);
-			}
-		}
-		d->urbs_initialized = 0;
-		/* free the urb array */
-		kfree(d->urb_list);
-		d->state &= ~DVB_USB_STATE_URB_LIST;
-	}
-
-	dvb_usb_free_stream_buffers(d);
-	return 0;
+	return usb_urb_exit(&adap->stream);
 }
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 97f8ea9..376c45a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -1,9 +1,11 @@
 /* dvb-usb.h is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * the headerfile, all dvb-usb-drivers have to include.
+ *
+ * TODO: clean-up the structures for unused fields and update the comments
  */
 #ifndef __DVB_USB_H__
 #define __DVB_USB_H__
@@ -84,36 +86,84 @@
 };
 
 struct dvb_usb_device;
+struct dvb_usb_adapter;
+struct usb_data_stream;
 
 /**
- * struct dvb_usb_properties - properties of a dvb-usb-device
+ * Properties of USB streaming - TODO this structure should be somewhere else
+ * describes the kind of USB transfer used for data-streaming.
+ *  (BULK or ISOC)
+ */
+struct usb_data_stream_properties {
+#define USB_BULK  1
+#define USB_ISOC  2
+	int type;
+	int count;
+	int endpoint;
+
+	union {
+		struct {
+			int buffersize; /* per URB */
+		} bulk;
+		struct {
+			int framesperurb;
+			int framesize;
+			int interval;
+		} isoc;
+	} u;
+};
+
+/**
+ * struct dvb_usb_adapter_properties - properties of a dvb-usb-adapter.
+ *    A DVB-USB-Adapter is basically a dvb_adapter which is present on a USB-device.
  * @caps: capabilities of the DVB USB device.
  * @pid_filter_count: number of PID filter position in the optional hardware
  *  PID-filter.
- *
+ * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
+ *  device (not URB submitting/killing).
+ * @pid_filter_ctrl: called to en/disable the PID filter, if any.
+ * @pid_filter: called to set/unset a PID for filtering.
+ * @frontend_attach: called to attach the possible frontends (fill fe-field
+ *  of struct dvb_usb_device).
+ * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
+ *  pll_desc and pll_init_buf of struct dvb_usb_device).
+ * @stream: configuration of the USB streaming
+ */
+struct dvb_usb_adapter_properties {
+#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
+#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
+#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS         0x08
+	int caps;
+	int pid_filter_count;
+
+	int (*streaming_ctrl)  (struct dvb_usb_adapter *, int);
+	int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
+	int (*pid_filter)      (struct dvb_usb_adapter *, int, u16, int);
+
+	int (*frontend_attach) (struct dvb_usb_adapter *);
+	int (*tuner_attach)    (struct dvb_usb_adapter *);
+
+	struct usb_data_stream_properties stream;
+
+	int size_of_priv;
+};
+
+/**
+ * struct dvb_usb_device_properties - properties of a dvb-usb-device
  * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
  *  download.
  * @firmware: name of the firmware file.
  * @download_firmware: called to download the firmware when the usb_ctrl is
  *  DEVICE_SPECIFIC.
  * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
-    so do the warm initialization right after it
-
+ *  so do the warm initialization right after it
+ *
  * @size_of_priv: how many bytes shall be allocated for the private field
  *  of struct dvb_usb_device.
  *
  * @power_ctrl: called to enable/disable power of the device.
- * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
- *  device (not URB submitting/killing).
- * @pid_filter_ctrl: called to en/disable the PID filter, if any.
- * @pid_filter: called to set/unset a PID for filtering.
- *
  * @read_mac_address: called to read the MAC address of the device.
- *
- * @frontend_attach: called to attach the possible frontends (fill fe-field
- *  of struct dvb_usb_device).
- * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
- *  pll_desc and pll_init_buf of struct dvb_usb_device).
  * @identify_state: called to determine the state (cold or warm), when it
  *  is not distinguishable by the USB IDs.
  *
@@ -130,50 +180,40 @@
  *  is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
  *  helper functions.
  *
- * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
- *  (BULK or ISOC)
- *
  * @num_device_descs: number of struct dvb_usb_device_description in @devices
  * @devices: array of struct dvb_usb_device_description compatibles with these
  *  properties.
  */
-struct dvb_usb_properties {
+#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
+struct dvb_usb_device_properties {
 
-#define DVB_USB_HAS_PID_FILTER               0x01
-#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02
-#define DVB_USB_NEED_PID_FILTERING           0x04
-#define DVB_USB_IS_AN_I2C_ADAPTER            0x08
+#define DVB_USB_IS_AN_I2C_ADAPTER            0x01
 	int caps;
-	int pid_filter_count;
 
 #define DEVICE_SPECIFIC 0
 #define CYPRESS_AN2135  1
 #define CYPRESS_AN2235  2
 #define CYPRESS_FX2     3
-	int usb_ctrl;
+	int        usb_ctrl;
+	int        (*download_firmware) (struct usb_device *, const struct firmware *);
 	const char firmware[FIRMWARE_NAME_MAX];
-	int (*download_firmware) (struct usb_device *, const struct firmware *);
-	int no_reconnect;
+	int        no_reconnect;
 
 	int size_of_priv;
 
-	int (*power_ctrl) (struct dvb_usb_device *, int);
-	int (*streaming_ctrl) (struct dvb_usb_device *, int);
-	int (*pid_filter_ctrl) (struct dvb_usb_device *, int);
-	int (*pid_filter) (struct dvb_usb_device *, int, u16, int);
+	int num_adapters;
+	struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
 
+	int (*power_ctrl)       (struct dvb_usb_device *, int);
 	int (*read_mac_address) (struct dvb_usb_device *, u8 []);
-	int (*frontend_attach) (struct dvb_usb_device *);
-	int (*tuner_attach) (struct dvb_usb_device *);
-
-	int (*identify_state) (struct usb_device *, struct dvb_usb_properties *,
+	int (*identify_state)   (struct usb_device *, struct dvb_usb_device_properties *,
 			struct dvb_usb_device_description **, int *);
 
 /* remote control properties */
 #define REMOTE_NO_KEY_PRESSED      0x00
 #define REMOTE_KEY_PRESSED         0x01
 #define REMOTE_KEY_REPEAT          0x02
-	struct dvb_usb_rc_key *rc_key_map;
+	struct dvb_usb_rc_key  *rc_key_map;
 	int rc_key_map_size;
 	int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
 	int rc_interval;
@@ -182,40 +222,12 @@
 
 	int generic_bulk_ctrl_endpoint;
 
-	struct {
-#define DVB_USB_BULK  1
-#define DVB_USB_ISOC  2
-		int type;
-		int count;
-		int endpoint;
-
-		union {
-			struct {
-				int buffersize; /* per URB */
-			} bulk;
-			struct {
-				int framesperurb;
-				int framesize;
-				int interval;
-			} isoc;
-		} u;
-	} urb;
-
 	int num_device_descs;
 	struct dvb_usb_device_description devices[9];
 };
 
-
 /**
- * struct dvb_usb_device - object of a DVB USB device
- * @props: copy of the struct dvb_usb_properties this device belongs to.
- * @desc: pointer to the device's struct dvb_usb_device_description.
- * @state: initialization and runtime state of the device.
- *
- * @udev: pointer to the device's struct usb_device.
- * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
- *  streaming.
- *
+ * struct usb_data_stream - generic object of an USB stream
  * @buf_num: number of buffer allocated.
  * @buf_size: size of each buffer in buf_list.
  * @buf_list: array containing all allocate buffers for streaming.
@@ -223,18 +235,40 @@
  *
  * @urbs_initialized: number of URBs initialized.
  * @urbs_submitted: number of URBs submitted.
+ */
+#define MAX_NO_URBS_FOR_DATA_STREAM 10
+struct usb_data_stream {
+	struct usb_device                 *udev;
+	struct usb_data_stream_properties  props;
+
+#define USB_STATE_INIT    0x00
+#define USB_STATE_URB_BUF 0x01
+	int state;
+
+	void (*complete) (struct usb_data_stream *, u8 *, size_t);
+
+	struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
+	int            buf_num;
+	unsigned long  buf_size;
+	u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
+	dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
+
+	int urbs_initialized;
+	int urbs_submitted;
+
+	void *user_priv;
+};
+
+/**
+ * struct dvb_usb_adapter - a DVB adapter on a USB device
+ * @id: index of this adapter (starting with 0).
  *
  * @feedcount: number of reqested feeds (used for streaming-activation)
  * @pid_filtering: is hardware pid_filtering used or not.
  *
- * @usb_mutex: semaphore of USB control messages (reading needs two messages)
- * @i2c_mutex: semaphore for i2c-transfers
- *
- * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
  * @pll_addr: I2C address of the tuner for programming
  * @pll_init: array containing the initialization buffer
  * @pll_desc: pointer to the appropriate struct dvb_pll_desc
- *
  * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
  *
  * @dvb_adap: device's dvb_adapter.
@@ -244,8 +278,62 @@
  * @dvb_frontend: device's frontend.
  * @max_feed_count: how many feeds can be handled simultaneously by this
  *  device
+ *
+ * @fe_init:  rerouted frontend-init (wakeup) function.
  * @fe_sleep: rerouted frontend-sleep function.
- * @fe_init: rerouted frontend-init (wakeup) function.
+ *
+ * @stream: the usb data stream.
+ */
+struct dvb_usb_adapter {
+	struct dvb_usb_device *dev;
+	struct dvb_usb_adapter_properties props;
+
+#define DVB_USB_ADAP_STATE_INIT 0x000
+#define DVB_USB_ADAP_STATE_DVB  0x001
+	int state;
+
+	u8  id;
+
+	int feedcount;
+	int pid_filtering;
+
+	/* tuner programming information */
+	u8 pll_addr;
+	u8 pll_init[4];
+	struct dvb_pll_desc *pll_desc;
+	int (*tuner_pass_ctrl) (struct dvb_frontend *, int, u8);
+
+	/* dvb */
+	struct dvb_adapter   dvb_adap;
+	struct dmxdev        dmxdev;
+	struct dvb_demux     demux;
+	struct dvb_net       dvb_net;
+	struct dvb_frontend *fe;
+	int                  max_feed_count;
+
+	int (*fe_init)  (struct dvb_frontend *);
+	int (*fe_sleep) (struct dvb_frontend *);
+
+	struct usb_data_stream stream;
+
+	void *priv;
+};
+
+/**
+ * struct dvb_usb_device - object of a DVB USB device
+ * @props: copy of the struct dvb_usb_properties this device belongs to.
+ * @desc: pointer to the device's struct dvb_usb_device_description.
+ * @state: initialization and runtime state of the device.
+ *
+ * @powered: indicated whether the device is power or not.
+ *  Powered is in/decremented for each call to modify the state.
+ * @udev: pointer to the device's struct usb_device.
+ *
+ * @usb_mutex: semaphore of USB control messages (reading needs two messages)
+ * @i2c_mutex: semaphore for i2c-transfers
+ *
+ * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
+ *
  * @rc_input_dev: input device for the remote control.
  * @rc_query_work: struct work_struct frequent rc queries
  * @last_event: last triggered event
@@ -255,32 +343,18 @@
  *  in size_of_priv of dvb_usb_properties).
  */
 struct dvb_usb_device {
-	struct dvb_usb_properties props;
+	struct dvb_usb_device_properties props;
 	struct dvb_usb_device_description *desc;
 
+	struct usb_device *udev;
+
 #define DVB_USB_STATE_INIT        0x000
-#define DVB_USB_STATE_URB_LIST    0x001
-#define DVB_USB_STATE_URB_BUF     0x002
-#define DVB_USB_STATE_DVB         0x004
-#define DVB_USB_STATE_I2C         0x008
-#define DVB_USB_STATE_REMOTE      0x010
-#define DVB_USB_STATE_URB_SUBMIT  0x020
+#define DVB_USB_STATE_I2C         0x001
+#define DVB_USB_STATE_DVB         0x002
+#define DVB_USB_STATE_REMOTE      0x004
 	int state;
 
-	/* usb */
-	struct usb_device *udev;
-	struct urb **urb_list;
-
-	int buf_num;
-	unsigned long buf_size;
-	u8 **buf_list;
-	dma_addr_t *dma_addr;
-
-	int urbs_initialized;
-	int urbs_submitted;
-
-	int feedcount;
-	int pid_filtering;
+	int powered;
 
 	/* locking */
 	struct mutex usb_mutex;
@@ -289,22 +363,8 @@
 	struct mutex i2c_mutex;
 	struct i2c_adapter i2c_adap;
 
-	/* tuner programming information */
-	u8 pll_addr;
-	u8 pll_init[4];
-	struct dvb_pll_desc *pll_desc;
-	int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8);
-
-	/* dvb */
-	struct dvb_adapter dvb_adap;
-	struct dmxdev dmxdev;
-	struct dvb_demux demux;
-	struct dvb_net dvb_net;
-	struct dvb_frontend* fe;
-	int max_feed_count;
-
-	int (*fe_sleep) (struct dvb_frontend *);
-	int (*fe_init)  (struct dvb_frontend *);
+	int                    num_adapters_initialized;
+	struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
 
 	/* remote control */
 	struct input_dev *rc_input_dev;
@@ -318,7 +378,7 @@
 	void *priv;
 };
 
-extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *, struct dvb_usb_device **);
+extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_device_properties *, struct module *, struct dvb_usb_device **);
 extern void dvb_usb_device_exit(struct usb_interface *);
 
 /* the generic read/write method for device control */
@@ -342,5 +402,7 @@
 	u8 chk;
 };
 extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
+extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos);
+
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
index 9a98f3f..7375eb2 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -161,19 +161,18 @@
 }
 
 
-static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-	return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0);
+	return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
 }
 
-static int gp8psk_frontend_attach(struct dvb_usb_device *d)
+static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	d->fe = gp8psk_fe_attach(d);
-
+	adap->fe = gp8psk_fe_attach(adap->dev);
 	return 0;
 }
 
-static struct dvb_usb_properties gp8psk_properties;
+static struct dvb_usb_device_properties gp8psk_properties;
 
 static int gp8psk_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -188,20 +187,18 @@
 };
 MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
 
-static struct dvb_usb_properties gp8psk_properties = {
-	.caps = 0,
-
+static struct dvb_usb_device_properties gp8psk_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-gp8psk-01.fw",
 
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.streaming_ctrl   = gp8psk_streaming_ctrl,
-	.power_ctrl       = gp8psk_power_ctrl,
 	.frontend_attach  = gp8psk_frontend_attach,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 7,
 		.endpoint = 0x82,
 		.u = {
@@ -210,6 +207,11 @@
 			}
 		}
 	},
+		}
+	},
+	.power_ctrl       = gp8psk_power_ctrl,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
 
 	.num_device_descs = 1,
 	.devices = {
@@ -217,7 +219,7 @@
 		  .cold_ids = { &gp8psk_usb_table[0], NULL },
 		  .warm_ids = { &gp8psk_usb_table[1], NULL },
 		},
-		{ 0 },
+		{ NULL },
 	}
 };
 
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 79f0a02..a9219bf 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -135,7 +135,7 @@
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties nova_t_properties;
+static struct dvb_usb_device_properties nova_t_properties;
 
 static int nova_t_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -151,21 +151,41 @@
 };
 MODULE_DEVICE_TABLE(usb, nova_t_table);
 
-static struct dvb_usb_properties nova_t_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-	.pid_filter_count = 32,
+static struct dvb_usb_device_properties nova_t_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-nova-t-usb2-02.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
+	.num_adapters     = 1,
+	.adapter          = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+			.pid_filter_count = 32,
 
 	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
 	.pid_filter       = dibusb_pid_filter,
 	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-	.power_ctrl       = dibusb2_0_power_ctrl,
 	.frontend_attach  = dibusb_dib3000mc_frontend_attach,
 	.tuner_attach     = dibusb_dib3000mc_tuner_attach,
+
+	/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+			.size_of_priv     = sizeof(struct dibusb_state),
+		}
+	},
+
+	.power_ctrl       = dibusb2_0_power_ctrl,
 	.read_mac_address = nova_t_read_mac_address,
 
 	.rc_interval      = 100,
@@ -176,17 +196,6 @@
 	.i2c_algo         = &dibusb_i2c_algo,
 
 	.generic_bulk_ctrl_endpoint = 0x01,
-	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
-		.endpoint = 0x06,
-		.u = {
-			.bulk = {
-				.buffersize = 4096,
-			}
-		}
-	},
 
 	.num_device_descs = 1,
 	.devices = {
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 418a0b7..f9941ea 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -50,7 +50,7 @@
 	return 0;
 }
 
-static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
+static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	struct mt352_config umt_config;
 
@@ -58,21 +58,21 @@
 	umt_config.demod_init = umt_mt352_demod_init;
 	umt_config.demod_address = 0xf;
 
-	d->fe = dvb_attach(mt352_attach, &umt_config, &d->i2c_adap);
+	adap->fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap);
 
 	return 0;
 }
 
-static int umt_tuner_attach (struct dvb_usb_device *d)
+static int umt_tuner_attach (struct dvb_usb_adapter *adap)
 {
-	d->pll_addr = 0x61;
-	d->pll_desc = &dvb_pll_tua6034;
-	d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+	adap->pll_addr = 0x61;
+	adap->pll_desc = &dvb_pll_tua6034;
+	adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
 	return 0;
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties umt_properties;
+static struct dvb_usb_device_properties umt_properties;
 
 static int umt_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -90,25 +90,22 @@
 };
 MODULE_DEVICE_TABLE (usb, umt_table);
 
-static struct dvb_usb_properties umt_properties = {
+static struct dvb_usb_device_properties umt_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-umt-010-02.fw",
 
-	.size_of_priv     = sizeof(struct dibusb_state),
-
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
-	.power_ctrl       = dibusb_power_ctrl,
 	.frontend_attach  = umt_mt352_frontend_attach,
 	.tuner_attach     = umt_tuner_attach,
 
-	.i2c_algo         = &dibusb_i2c_algo,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 20,
 		.endpoint = 0x06,
 		.u = {
@@ -118,6 +115,15 @@
 		}
 	},
 
+			.size_of_priv     = sizeof(struct dibusb_state),
+		}
+	},
+	.power_ctrl       = dibusb_power_ctrl,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
 	.num_device_descs = 1,
 	.devices = {
 		{	"Hanftek UMT-010 DVB-T USB2.0",
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
new file mode 100644
index 0000000..8728cf3
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/usb-urb.c
@@ -0,0 +1,242 @@
+/* usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file keeps functions for initializing and handling the
+ * BULK and ISOC USB data transfers in a generic way.
+ * Can be used for DVB-only and also, that's the plan, for
+ * Hybrid USB devices (analog and DVB).
+ */
+#include "dvb-usb-common.h"
+
+/* URB stuff for streaming */
+static void usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+{
+	struct usb_data_stream *stream = urb->context;
+	int ptype = usb_pipetype(urb->pipe);
+	int i;
+	u8 *b;
+
+	deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
+		ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
+		urb->status,urb->actual_length,urb->transfer_buffer_length,
+		urb->number_of_packets,urb->error_count);
+
+	switch (urb->status) {
+		case 0:         /* success */
+		case -ETIMEDOUT:    /* NAK */
+			break;
+		case -ECONNRESET:   /* kill */
+		case -ENOENT:
+		case -ESHUTDOWN:
+			return;
+		default:        /* error */
+			deb_ts("urb completition error %d.\n", urb->status);
+			break;
+	}
+
+	b = (u8 *) urb->transfer_buffer;
+	switch (ptype) {
+		case PIPE_ISOCHRONOUS:
+			for (i = 0; i < urb->number_of_packets; i++) {
+
+				if (urb->iso_frame_desc[i].status != 0)
+					deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
+				else if (urb->iso_frame_desc[i].actual_length > 0)
+					stream->complete(stream, b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length);
+
+				urb->iso_frame_desc[i].status = 0;
+				urb->iso_frame_desc[i].actual_length = 0;
+			}
+			debug_dump(b,20,deb_uxfer);
+			break;
+		case PIPE_BULK:
+			if (urb->actual_length > 0)
+				stream->complete(stream, b, urb->actual_length);
+			break;
+		default:
+			err("unkown endpoint type in completition handler.");
+			return;
+	}
+	usb_submit_urb(urb,GFP_ATOMIC);
+}
+
+int usb_urb_kill(struct usb_data_stream *stream)
+{
+	int i;
+	for (i = 0; i < stream->urbs_submitted; i++) {
+		deb_ts("killing URB no. %d.\n",i);
+
+		/* stop the URB */
+		usb_kill_urb(stream->urb_list[i]);
+	}
+	stream->urbs_submitted = 0;
+	return 0;
+}
+
+int usb_urb_submit(struct usb_data_stream *stream)
+{
+	int i,ret;
+	for (i = 0; i < stream->urbs_initialized; i++) {
+		deb_ts("submitting URB no. %d\n",i);
+		if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) {
+			err("could not submit URB no. %d - get them all back",i);
+			usb_urb_kill(stream);
+			return ret;
+		}
+		stream->urbs_submitted++;
+	}
+	return 0;
+}
+
+static int usb_free_stream_buffers(struct usb_data_stream *stream)
+{
+	if (stream->state & USB_STATE_URB_BUF) {
+		while (stream->buf_num) {
+			stream->buf_num--;
+			deb_mem("freeing buffer %d\n",stream->buf_num);
+			usb_buffer_free(stream->udev, stream->buf_size,
+					stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]);
+		}
+	}
+
+	stream->state &= ~USB_STATE_URB_BUF;
+
+	return 0;
+}
+
+static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size)
+{
+	stream->buf_num = 0;
+	stream->buf_size = size;
+
+	deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
+
+	for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
+		deb_mem("allocating buffer %d\n",stream->buf_num);
+		if (( stream->buf_list[stream->buf_num] =
+					usb_buffer_alloc(stream->udev, size, SLAB_ATOMIC,
+					&stream->dma_addr[stream->buf_num]) ) == NULL) {
+			deb_mem("not enough memory for urb-buffer allocation.\n");
+			usb_free_stream_buffers(stream);
+			return -ENOMEM;
+		}
+		deb_mem("buffer %d: %p (dma: %u)\n",
+			stream->buf_num, stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]);
+		memset(stream->buf_list[stream->buf_num],0,size);
+		stream->state |= USB_STATE_URB_BUF;
+	}
+	deb_mem("allocation successful\n");
+
+	return 0;
+}
+
+static int usb_bulk_urb_init(struct usb_data_stream *stream)
+{
+	int i;
+
+	if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
+					stream->props.u.bulk.buffersize)) < 0)
+		return i;
+
+	/* allocate the URBs */
+	for (i = 0; i < stream->props.count; i++) {
+		if ((stream->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
+			return -ENOMEM;
+
+		usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
+				usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
+				stream->buf_list[i],
+				stream->props.u.bulk.buffersize,
+				usb_urb_complete, stream);
+
+		stream->urb_list[i]->transfer_flags = 0;
+		stream->urbs_initialized++;
+	}
+	return 0;
+}
+
+static int usb_isoc_urb_init(struct usb_data_stream *stream)
+{
+	int i,j;
+
+	if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
+					stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0)
+		return i;
+
+	/* allocate the URBs */
+	for (i = 0; i < stream->props.count; i++) {
+		struct urb *urb;
+		int frame_offset = 0;
+		if ((stream->urb_list[i] =
+					usb_alloc_urb(stream->props.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
+			return -ENOMEM;
+
+		urb = stream->urb_list[i];
+
+		urb->dev = stream->udev;
+		urb->context = stream;
+		urb->complete = usb_urb_complete;
+		urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint);
+		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+		urb->interval = stream->props.u.isoc.interval;
+		urb->number_of_packets = stream->props.u.isoc.framesperurb;
+		urb->transfer_buffer_length = stream->buf_size;
+		urb->transfer_buffer = stream->buf_list[i];
+		urb->transfer_dma = stream->dma_addr[i];
+
+		for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
+			urb->iso_frame_desc[j].offset = frame_offset;
+			urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize;
+			frame_offset += stream->props.u.isoc.framesize;
+		}
+
+		stream->urbs_initialized++;
+	}
+	return 0;
+}
+
+int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props)
+{
+	if (stream == NULL || props == NULL)
+		return -EINVAL;
+
+	memcpy(&stream->props, props, sizeof(*props));
+
+	usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint));
+
+	if (stream->complete == NULL) {
+		err("there is no data callback - this doesn't make sense.");
+		return -EINVAL;
+	}
+
+	switch (stream->props.type) {
+		case USB_BULK:
+			return usb_bulk_urb_init(stream);
+		case USB_ISOC:
+			return usb_isoc_urb_init(stream);
+		default:
+			err("unkown URB-type for data transfer.");
+			return -EINVAL;
+	}
+}
+
+int usb_urb_exit(struct usb_data_stream *stream)
+{
+	int i;
+
+	usb_urb_kill(stream);
+
+	for (i = 0; i < stream->urbs_initialized; i++) {
+		if (stream->urb_list[i] != NULL) {
+			deb_mem("freeing URB no. %d.\n",i);
+			/* free the URBs */
+			usb_free_urb(stream->urb_list[i]);
+		}
+	}
+	stream->urbs_initialized = 0;
+
+	usb_free_stream_buffers(stream);
+	return 0;
+}
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index d4da494..3ecb2e0 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -24,6 +24,8 @@
 	struct dvb_frontend fe;
 	struct dvb_usb_device *d;
 
+	struct dvb_frontend_ops ops;
+
 	fe_sec_voltage_t voltage;
 	fe_sec_tone_mode_t tone_mode;
 
@@ -72,9 +74,6 @@
 	else
 		*status = 0;
 
-	deb_fe("real state: %x\n",*status);
-	*status = 0x1f;
-
 	if (*status & FE_HAS_LOCK)
 		st->status_check_interval = 1000;
 	else
@@ -171,8 +170,6 @@
 	st->status_check_interval = 250;
 	st->next_status_check = jiffies;
 
-	vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
-	msleep(30);
 	vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
 
 	if (ibuf[2] == 0 && ibuf[3] == 0)
@@ -183,6 +180,20 @@
 	return 0;
 }
 
+static int vp702x_fe_init(struct dvb_frontend *fe)
+{
+	struct vp702x_fe_state *st = fe->demodulator_priv;
+	deb_fe("%s\n",__FUNCTION__);
+	vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
+	return 0;
+}
+
+static int vp702x_fe_sleep(struct dvb_frontend *fe)
+{
+	deb_fe("%s\n",__FUNCTION__);
+	return 0;
+}
+
 static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
 				  struct dvb_frontend_parameters *fep)
 {
@@ -193,8 +204,8 @@
 static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
 				    struct dvb_diseqc_master_cmd *m)
 {
-	struct vp702x_fe_state *st = fe->demodulator_priv;
-	u8 cmd[8],ibuf[10];
+	//struct vp702x_fe_state *st = fe->demodulator_priv;
+	u8 cmd[8];//,ibuf[10];
 	memset(cmd,0,8);
 
 	deb_fe("%s\n",__FUNCTION__);
@@ -207,12 +218,12 @@
 	memcpy(&cmd[3], m->msg, m->msg_len);
 	cmd[7] = vp702x_chksum(cmd,0,7);
 
-	vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+//	vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
 
-	if (ibuf[2] == 0 && ibuf[3] == 0)
-		deb_fe("diseqc cmd failed.\n");
-	else
-		deb_fe("diseqc cmd succeeded.\n");
+//	if (ibuf[2] == 0 && ibuf[3] == 0)
+//		deb_fe("diseqc cmd failed.\n");
+//	else
+//		deb_fe("diseqc cmd succeeded.\n");
 
 	return 0;
 }
@@ -318,8 +329,8 @@
 	},
 	.release = vp702x_fe_release,
 
-	.init = NULL,
-	.sleep = NULL,
+	.init  = vp702x_fe_init,
+	.sleep = vp702x_fe_sleep,
 
 	.set_frontend = vp702x_fe_set_frontend,
 	.get_frontend = vp702x_fe_get_frontend,
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index b2f098a..02bd61a 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -22,50 +22,54 @@
 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
 
 struct vp702x_state {
-	u8 pid_table[17]; /* [16] controls the pid_table state */
+	int pid_filter_count;
+	int pid_filter_can_bypass;
+	u8  pid_filter_state;
+};
+
+struct vp702x_device_state {
+	u8 power_state;
 };
 
 /* check for mutex FIXME */
 int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
 {
-	int ret = 0,try = 0;
+	int ret = -1;
 
-	while (ret >= 0 && ret != blen && try < 3) {
 		ret = usb_control_msg(d->udev,
 			usb_rcvctrlpipe(d->udev,0),
 			req,
 			USB_TYPE_VENDOR | USB_DIR_IN,
 			value,index,b,blen,
 			2000);
-		deb_info("reading number %d (ret: %d)\n",try,ret);
-		try++;
-	}
 
-	if (ret < 0 || ret != blen) {
-		warn("usb in operation failed.");
+	if (ret < 0) {
+		warn("usb in operation failed. (%d)", ret);
 		ret = -EIO;
 	} else
 		ret = 0;
 
-	deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+
+	deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
 	debug_dump(b,blen,deb_xfer);
 
 	return ret;
 }
 
-static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 			     u16 index, u8 *b, int blen)
 {
-	deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+	int ret;
+	deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
 	debug_dump(b,blen,deb_xfer);
 
-	if (usb_control_msg(d->udev,
+	if ((ret = usb_control_msg(d->udev,
 			usb_sndctrlpipe(d->udev,0),
 			req,
 			USB_TYPE_VENDOR | USB_DIR_OUT,
 			value,index,b,blen,
-			2000) != blen) {
-		warn("usb out operation failed.");
+			2000)) != blen) {
+		warn("usb out operation failed. (%d)",ret);
 		return -EIO;
 	} else
 		return 0;
@@ -78,12 +82,10 @@
 	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
 		return ret;
 
-	if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
-		goto unlock;
+	ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen);
 	msleep(msec);
 	ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
 
-unlock:
 	mutex_unlock(&d->usb_mutex);
 
 	return ret;
@@ -108,29 +110,65 @@
 	return ret;
 }
 
-static int vp702x_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
 {
-	struct vp702x_state *st = d->priv;
-	u8 buf[9];
-
-	if (onoff) {
-		st->pid_table[16]   |=   1 << index;
-		st->pid_table[index*2]   = (pid >> 8) & 0xff;
-		st->pid_table[index*2+1] =  pid       & 0xff;
-	} else {
-		st->pid_table[16]   &= ~(1 << index);
-		st->pid_table[index*2] = st->pid_table[index*2+1] = 0;
-	}
-
-	return vp702x_usb_inout_cmd(d,SET_PID_FILTER,st->pid_table,17,buf,9,10);
+	u8 buf[16] = { 0 };
+	return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16);
 }
 
-static int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
+static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
 {
-	vp702x_usb_in_op(d,RESET_TUNER,0,0,NULL,0);
+	u8 buf[16] = { 0 };
+	return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16);
+}
 
-	vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
-	return vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
+static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
+{
+	struct vp702x_state *st = adap->priv;
+	u8 buf[16] = { 0 };
+
+	if (onoff)
+		st->pid_filter_state |=  (1 << id);
+	else {
+		st->pid_filter_state &= ~(1 << id);
+		pid = 0xffff;
+	}
+
+	id = 0x10 + id*2;
+
+	vp702x_set_pld_state(adap, st->pid_filter_state);
+	vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
+	vp702x_usb_in_op(adap->dev, 0xe0, (((pid     ) & 0xff) << 8) | (id+1), 0, buf, 16);
+	return 0;
+}
+
+
+static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
+{
+	struct vp702x_state *st = adap->priv;
+	int i;
+	u8 b[10] = { 0 };
+
+	st->pid_filter_count = 8;
+	st->pid_filter_can_bypass = 1;
+	st->pid_filter_state = 0x00;
+
+	vp702x_set_pld_mode(adap, 1); // bypass
+
+	for (i = 0; i < st->pid_filter_count; i++)
+		vp702x_set_pid(adap, 0xffff, i, 1);
+
+	vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
+	vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
+	vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
+
+	//vp702x_set_pld_mode(d, 0); // filter
+	return 0;
+}
+
+static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	return 0;
 }
 
 /* keys for the enclosed remote control */
@@ -166,74 +204,83 @@
 	return 0;
 }
 
+int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	struct vp702x_device_state *st = d->priv;
+
+	if (st->power_state == 0 && onoff)
+		vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
+	else if (st->power_state == 1 && onoff == 0)
+		vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
+
+	st->power_state = onoff;
+
+	return 0;
+}
+
 static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
 {
-	u8 macb[9];
-	if (vp702x_usb_inout_cmd(d, GET_MAC_ADDRESS, NULL, 0, macb, 9, 10))
-		return -EIO;
-	memcpy(mac,&macb[3],6);
+	u8 i;
+	for (i = 6; i < 12; i++)
+		vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &mac[i - 6], 1);
 	return 0;
 }
 
-static int vp702x_frontend_attach(struct dvb_usb_device *d)
+static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	u8 buf[9] = { 0 };
+	u8 buf[10] = { 0 };
 
-	if (vp702x_usb_inout_cmd(d, GET_SYSTEM_STRING, NULL, 0, buf, 9, 10))
+	vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
+
+	if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0, buf, 10, 10))
 		return -EIO;
 
-	buf[8] = '\0';
+	buf[9] = '\0';
 	info("system string: %s",&buf[1]);
 
-	d->fe = vp702x_fe_attach(d);
+	vp702x_init_pid_filter(adap);
+
+	adap->fe = vp702x_fe_attach(adap->dev);
+	vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
+
 	return 0;
 }
 
-static struct dvb_usb_properties vp702x_properties;
+static struct dvb_usb_device_properties vp702x_properties;
 
 static int vp702x_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	struct usb_device *udev = interface_to_usbdev(intf);
-
-	usb_clear_halt(udev,usb_sndctrlpipe(udev,0));
-	usb_clear_halt(udev,usb_rcvctrlpipe(udev,0));
-
 	return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL);
 }
 
 static struct usb_device_id vp702x_usb_table [] = {
 	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
-	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_WARM) },
-	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
-	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
+//	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
+//	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
 	    { 0 },
 };
 MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
 
-static struct dvb_usb_properties vp702x_properties = {
-	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-	.pid_filter_count = 8, /* !!! */
-
+static struct dvb_usb_device_properties vp702x_properties = {
 	.usb_ctrl = CYPRESS_FX2,
-	.firmware = "dvb-usb-vp702x-01.fw",
+	.firmware            = "dvb-usb-vp702x-02.fw",
+	.no_reconnect        = 1,
 
-	.pid_filter       = vp702x_pid_filter,
-	.power_ctrl       = vp702x_power_ctrl,
+	.size_of_priv     = sizeof(struct vp702x_device_state),
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps             = DVB_USB_ADAP_RECEIVES_204_BYTE_TS,
+
+			.streaming_ctrl   = vp702x_streaming_ctrl,
 	.frontend_attach  = vp702x_frontend_attach,
-	.read_mac_address = vp702x_read_mac_addr,
-
-	.rc_key_map       = vp702x_rc_keys,
-	.rc_key_map_size  = ARRAY_SIZE(vp702x_rc_keys),
-	.rc_interval      = 400,
-	.rc_query         = vp702x_rc_query,
-
-	.size_of_priv     = sizeof(struct vp702x_state),
 
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
-		.count = 7,
+			.stream = {
+				.type = USB_BULK,
+				.count = 10,
 		.endpoint = 0x02,
 		.u = {
 			.bulk = {
@@ -241,24 +288,33 @@
 			}
 		}
 	},
+			.size_of_priv     = sizeof(struct vp702x_state),
+		}
+		},
+	.read_mac_address = vp702x_read_mac_addr,
 
-	.num_device_descs = 2,
+	.rc_key_map       = vp702x_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(vp702x_rc_keys),
+	.rc_interval      = 400,
+	.rc_query         = vp702x_rc_query,
+
+	.num_device_descs = 1,
 	.devices = {
 		{ .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
 		  .cold_ids = { &vp702x_usb_table[0], NULL },
-		  .warm_ids = { &vp702x_usb_table[1], NULL },
+		  .warm_ids = { NULL },
 		},
-		{ .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
+/*		{ .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
 		  .cold_ids = { &vp702x_usb_table[2], NULL },
 		  .warm_ids = { &vp702x_usb_table[3], NULL },
 		},
-		{ 0 },
+*/		{ NULL },
 	}
 };
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp702x_usb_driver = {
-	.name		= "dvb-usb-vp702x",
+	.name		= "dvb_usb_vp702x",
 	.probe 		= vp702x_usb_probe,
 	.disconnect = dvb_usb_device_exit,
 	.id_table 	= vp702x_usb_table,
@@ -287,5 +343,5 @@
 
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
 MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
-MODULE_VERSION("1.0-alpha");
+MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
index c2f97f9..25a9dee 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.h
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -102,5 +102,7 @@
 
 extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
 extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff);
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 8ea3834..b4cf002 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -169,31 +169,31 @@
 	return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
 }
 
-static int vp7045_frontend_attach(struct dvb_usb_device *d)
+static int vp7045_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	u8 buf[255] = { 0 };
 
-	vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0);
+	vp7045_usb_op(adap->dev,VENDOR_STRING_READ,NULL,0,buf,20,0);
 	buf[10] = '\0';
 	deb_info("firmware says: %s ",buf);
 
-	vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0);
+	vp7045_usb_op(adap->dev,PRODUCT_STRING_READ,NULL,0,buf,20,0);
 	buf[10] = '\0';
 	deb_info("%s ",buf);
 
-	vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0);
+	vp7045_usb_op(adap->dev,FW_VERSION_READ,NULL,0,buf,20,0);
 	buf[10] = '\0';
 	deb_info("v%s\n",buf);
 
 /*	Dump the EEPROM */
 /*	vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
 
-	d->fe = vp7045_fe_attach(d);
+	adap->fe = vp7045_fe_attach(adap->dev);
 
 	return 0;
 }
 
-static struct dvb_usb_properties vp7045_properties;
+static struct dvb_usb_device_properties vp7045_properties;
 
 static int vp7045_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
@@ -210,24 +210,17 @@
 };
 MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
 
-static struct dvb_usb_properties vp7045_properties = {
-	.caps = 0,
-
+static struct dvb_usb_device_properties vp7045_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-vp7045-01.fw",
 
-	.power_ctrl       = vp7045_power_ctrl,
+	.num_adapters = 1,
+	.adapter = {
+		{
 	.frontend_attach  = vp7045_frontend_attach,
-	.read_mac_address = vp7045_read_mac_addr,
-
-	.rc_interval      = 400,
-	.rc_key_map       = vp7045_rc_keys,
-	.rc_key_map_size  = ARRAY_SIZE(vp7045_rc_keys),
-	.rc_query         = vp7045_rc_query,
-
 	/* parameter for the MPEG2-data transfer */
-	.urb = {
-		.type = DVB_USB_BULK,
+			.stream = {
+				.type = USB_BULK,
 		.count = 7,
 		.endpoint = 0x02,
 		.u = {
@@ -236,6 +229,15 @@
 			}
 		}
 	},
+		}
+	},
+	.power_ctrl       = vp7045_power_ctrl,
+	.read_mac_address = vp7045_read_mac_addr,
+
+	.rc_interval      = 400,
+	.rc_key_map       = vp7045_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(vp7045_rc_keys),
+	.rc_query         = vp7045_rc_query,
 
 	.num_device_descs = 2,
 	.devices = {
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 62d69a6..a356d28 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -553,8 +553,8 @@
 	ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
 	adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
 
-	if (adiv == 0)
-		ndiv++;
+	if (adiv == 0 && ndiv > 0)
+		ndiv--;
 
 	/* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
 	state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index cc28417..ccc813b 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -37,6 +37,8 @@
 
 	struct dibx000_i2c_master i2c_master;
 
+	u32 timf;
+
 	fe_bandwidth_t current_bandwidth;
 
 	u16 dev_id;
@@ -92,50 +94,31 @@
 
 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
 {
-/*
-	u32 timf_msb, timf_lsb, i;
-	int tim_sgn ;
-	LUInt comp1, comp2, comp ;
-//	u32 tim_offset ;
-	comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
-	timf_msb = (comp >> 16) & 0x00FF;
-	timf_lsb =  comp        & 0xFFFF;
+	u32 timf;
 
-	// Update the timing offset ;
+	if (state->timf == 0) {
+		timf = 1384402; // default value for 8MHz
+		if (update_offset)
+			msleep(200); // first time we do an update
+	} else
+		timf = state->timf;
+
+	timf *= (BW_INDEX_TO_KHZ(bw) / 1000);
+
 	if (update_offset) {
-		if (state->timing_offset_comp_done == 0) {
-			usleep(200000);
-			state->timing_offset_comp_done = 1;
-		}
-		tim_offset = dib3000mc_read_word(state, 416);
-		if ((tim_offset & 0x2000) == 0x2000)
-			tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
+		s16 tim_offs = dib3000mc_read_word(state, 416);
+
+		if (tim_offs &  0x2000)
+			tim_offs -= 0x4000;
 
 		if (nfft == 0)
-			tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
-		state->timing_offset += tim_offset;
+			tim_offs *= 4;
+
+		timf += tim_offs;
+		state->timf = timf / (BW_INDEX_TO_KHZ(bw) / 1000);
 	}
-	tim_offset = state->timing_offset;
 
-	if (tim_offset < 0) {
-		tim_sgn = 1;
-		tim_offset = -tim_offset;
-	} else
-		tim_sgn = 0;
-
-	comp1 = tim_offset * timf_lsb;
-	comp2 = tim_offset * timf_msb;
-	comp  = ((comp1 >> 16) + comp2) >> 7;
-
-	if (tim_sgn == 0)
-		comp = timf_msb * (1<<16) + timf_lsb + comp;
-	else
-		comp = timf_msb * (1<<16) + timf_lsb - comp;
-
-	timf_msb = (comp>>16)&0xFF ;
-	timf_lsb = comp&0xFFFF;
-*/
-	u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
+	dprintk("timf: %d\n", timf);
 
 	dib3000mc_write_word(state, 23, timf >> 16);
 	dib3000mc_write_word(state, 24, timf & 0xffff);
@@ -143,15 +126,18 @@
 	return 0;
 }
 
-static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
+static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
 {
+	u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
     if (state->cfg->pwm3_inversion) {
-		dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
-		dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
+		reg_51 =  (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
+		reg_52 |= (1 << 2);
 	} else {
-		dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
-		dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
+		reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
+		reg_52 |= (1 << 8);
 	}
+	dib3000mc_write_word(state, 51, reg_51);
+	dib3000mc_write_word(state, 52, reg_52);
 
     if (state->cfg->use_pwm3)
 		dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
@@ -326,10 +312,10 @@
 		dib3000mc_write_word(state, 175,  0x0000);
 		dib3000mc_write_word(state, 1032, 0x012C);
 	}
-	dib3000mc_write_word(state, 1033, 0);
+	dib3000mc_write_word(state, 1033, 0x0000);
 
 	// P_clk_cfg
-	dib3000mc_write_word(state, 1037, 12592);
+	dib3000mc_write_word(state, 1037, 0x3130);
 
 	// other configurations
 
@@ -350,7 +336,7 @@
 	dib3000mc_write_word(state, 50, 0x8000);
 
 	// agc setup misc
-	dib3000mc_setup_pwm3_state(state);
+	dib3000mc_setup_pwm_state(state);
 
 	// P_agc_counter_lock
 	dib3000mc_write_word(state, 53, 0x87);
@@ -426,10 +412,9 @@
 {
 	struct dib3000mc_state *state = demod->demodulator_priv;
 
-	dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
 	dib3000mc_write_word(state, 1031, 0xFFFF);
 	dib3000mc_write_word(state, 1032, 0xFFFF);
-	dib3000mc_write_word(state, 1033, 0xFFF4);   // ****  Bin2
+	dib3000mc_write_word(state, 1033, 0xFFF0);
 
     return 0;
 }
@@ -539,6 +524,7 @@
 
 	reg = dib3000mc_read_word(state, 0);
 	dib3000mc_write_word(state, 0, reg | (1 << 8));
+	dib3000mc_read_word(state, 511);
 	dib3000mc_write_word(state, 0, reg);
 
 	return 0;
@@ -578,62 +564,12 @@
 		dib3000mc_write_word(state, 33, 6);
 	}
 
-	// if (lock)
-	//	dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
+	if (dib3000mc_read_word(state, 509) & 0x80)
+		dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
 
 	return 0;
 }
 
-static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
-{
-	struct dib3000mc_state *state = demod->demodulator_priv;
-	return dib3000mc_set_output_mode(state, mode);
-}
-
-static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
-{
-	struct dib3000mc_state *st;
-	int k,ret=0;
-	u8 new_addr;
-
-	static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
-
-	for (k = no_of_demods-1; k >= 0; k--) {
-		st = demod[k]->demodulator_priv;
-
-		/* designated i2c address */
-		new_addr          = DIB3000MC_I2C_ADDRESS[k];
-
-		st->i2c_addr = new_addr;
-		if (dib3000mc_identify(st) != 0) {
-			st->i2c_addr = default_addr;
-			if (dib3000mc_identify(st) != 0) {
-				dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
-				return -EINVAL;
-			}
-		}
-
-		/* turn on div_out */
-		dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
-
-		// set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
-		ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
-		st->i2c_addr = new_addr;
-	}
-
-	for (k = 0; k < no_of_demods; k++) {
-		st = demod[k]->demodulator_priv;
-
-		ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
-
-		/* turn off data output */
-		dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
-		dib3000mc_write_word(st, 769, (1 << 7) );
-
-	}
-	return 0;
-}
-
 struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
 {
 	struct dib3000mc_state *st = demod->demodulator_priv;
@@ -826,61 +762,79 @@
 }
 EXPORT_SYMBOL(dib3000mc_set_config);
 
-static struct dvb_frontend_ops dib3000mc_ops;
-
-int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8	default_addr,				u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
 {
-	struct dib3000mc_state *st;
-	int k, num=0;
+	struct dib3000mc_state st = { .i2c_adap = i2c };
+	int k;
+	u8 new_addr;
 
-	if (no_of_demods < 1)
-		return -EINVAL;
+	static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
+
+	for (k = no_of_demods-1; k >= 0; k--) {
+		st.cfg = &cfg[k];
+
+		/* designated i2c address */
+		new_addr          = DIB3000MC_I2C_ADDRESS[k];
+		st.i2c_addr = new_addr;
+		if (dib3000mc_identify(&st) != 0) {
+			st.i2c_addr = default_addr;
+			if (dib3000mc_identify(&st) != 0) {
+				dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
+				return -ENODEV;
+			}
+		}
+
+		dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK);
+
+		// set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
+		dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1);
+		st.i2c_addr = new_addr;
+	}
 
 	for (k = 0; k < no_of_demods; k++) {
-		st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
-		if (st == NULL)
-			goto error;
+		st.cfg = &cfg[k];
+		st.i2c_addr = DIB3000MC_I2C_ADDRESS[k];
 
-		num++;
+		dib3000mc_write_word(&st, 1024, st.i2c_addr << 3);
 
-		st->cfg = &cfg[k];
-	//	st->gpio_val = cfg[k].gpio_val;
-	//	st->gpio_dir = cfg[k].gpio_dir;
-		st->i2c_adap = i2c_adap;
-
-		demod[k]           = &st->demod;
-		demod[k]->demodulator_priv     = st;
-		memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
-
-//		INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
-//		demod[k]->register_access = &st->register_access;
+		/* turn off data output */
+		dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z);
 	}
-
-	if (do_i2c_enum) {
-		if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
-			goto error;
-	} else {
-		st = demod[0]->demodulator_priv;
-		st->i2c_addr = default_addr;
-		if (dib3000mc_identify(st) != 0)
-			goto error;
-	}
-
-	for (k = 0; k < num; k++) {
-		st = demod[k]->demodulator_priv;
-		dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
-	}
-
 	return 0;
+}
+EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
+
+static struct dvb_frontend_ops dib3000mc_ops;
+
+struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
+{
+	struct dvb_frontend *demod;
+	struct dib3000mc_state *st;
+	st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
+	if (st == NULL)
+		return NULL;
+
+	st->cfg = cfg;
+	st->i2c_adap = i2c_adap;
+	st->i2c_addr = i2c_addr;
+
+	demod                   = &st->demod;
+	demod->demodulator_priv = st;
+	memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
+
+	if (dib3000mc_identify(st) != 0)
+		goto error;
+
+	dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
+
+	dib3000mc_write_word(st, 1037, 0x3130);
+
+	return demod;
 
 error:
-	for (k = 0; k < num; k++) {
-		kfree(demod[k]->demodulator_priv);
-		demod[k] = NULL;
-	}
-	return -EINVAL;
+	kfree(st);
+	return NULL;
 }
-
 EXPORT_SYMBOL(dib3000mc_attach);
 
 static struct dvb_frontend_ops dib3000mc_ops = {
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
index fd0b2e7..b198cd5 100644
--- a/drivers/media/dvb/frontends/dib3000mc.h
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -37,17 +37,17 @@
 #define DEFAULT_DIB3000P_I2C_ADDRESS  24
 
 #if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE)
-extern int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr,
-    u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[]);
+extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg);
 #else
-static inline struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
-					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
+static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
 	return NULL;
 }
 #endif // CONFIG_DVB_DIB3000MC
 
+extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]);
+
 extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
 
 extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
diff --git a/drivers/media/dvb/frontends/mt2060.c b/drivers/media/dvb/frontends/mt2060.c
index 508ec1b..450fad8 100644
--- a/drivers/media/dvb/frontends/mt2060.c
+++ b/drivers/media/dvb/frontends/mt2060.c
@@ -247,6 +247,9 @@
 	if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
 		return;
 
+	/* initialize the clock output */
+	mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
+
 	do {
 		b |= (1 << 6); // FM1SS;
 		mt2060_writereg(priv, REG_LO2C1,b);
@@ -294,13 +297,13 @@
 static int mt2060_init(struct dvb_frontend *fe)
 {
 	struct mt2060_priv *priv = fe->tuner_priv;
-	return mt2060_writereg(priv, REG_VGAG,0x33);
+	return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x33);
 }
 
 static int mt2060_sleep(struct dvb_frontend *fe)
 {
 	struct mt2060_priv *priv = fe->tuner_priv;
-	return mt2060_writereg(priv, REG_VGAG,0x30);
+	return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
 }
 
 static int mt2060_release(struct dvb_frontend *fe)
@@ -329,14 +332,14 @@
 };
 
 /* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
-int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
 {
 	struct mt2060_priv *priv = NULL;
 	u8 id = 0;
 
 	priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
 	if (priv == NULL)
-		return -ENOMEM;
+		return NULL;
 
 	priv->cfg      = cfg;
 	priv->i2c      = i2c;
@@ -344,12 +347,12 @@
 
 	if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
 		kfree(priv);
-		return -ENODEV;
+		return NULL;
 	}
 
 	if (id != PART_REV) {
 		kfree(priv);
-		return -ENODEV;
+		return NULL;
 	}
 	printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
 	memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
@@ -358,7 +361,7 @@
 
 	mt2060_calibrate(priv);
 
-	return 0;
+	return fe;
 }
 EXPORT_SYMBOL(mt2060_attach);
 
diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/dvb/frontends/mt2060.h
index c58b03e..34a37c2 100644
--- a/drivers/media/dvb/frontends/mt2060.h
+++ b/drivers/media/dvb/frontends/mt2060.h
@@ -27,9 +27,9 @@
 
 struct mt2060_config {
 	u8 i2c_address;
-	/* Shall we add settings for the discrete outputs ? */
+	u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
 };
 
-extern int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
+extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
 
 #endif
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 7015517..6d96b17 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -195,8 +195,7 @@
 	---help---
 	  Choose Y here if you want to see RDS/RBDS information like
 	  RadioText, Programme Service name, Clock Time and date, Programme
-	  TYpe and Traffic Announcement/Programme identification.  You also
-	  need to say Y to "miroSOUND PCM20 radio" and devfs!
+	  Type and Traffic Announcement/Programme identification.
 
 	  It's not possible to read the raw RDS packets from the device, so
 	  the driver cant provide an V4L interface for this.  But the
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index d1183c9..afb734d 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -36,7 +36,7 @@
 menu "Encoders/decoders and other helper chips"
 	depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
 
-comment "Audio Decoders"
+comment "Audio decoders"
 
 config VIDEO_TVAUDIO
 	tristate "Simple audio decoder chips"
@@ -51,7 +51,7 @@
 	  module will be called tvaudio.
 
 config VIDEO_TDA7432
-	tristate "Philips TDA7432 audio processor chip"
+	tristate "Philips TDA7432 audio processor"
 	depends on VIDEO_V4L1 && I2C
 	---help---
 	  Support for tda7432 audio decoder chip found on some bt8xx boards.
@@ -60,7 +60,7 @@
 	  module will be called tda7432.
 
 config VIDEO_TDA9840
-	tristate "Philips TDA9840 audio processor chip"
+	tristate "Philips TDA9840 audio processor"
 	depends on VIDEO_DEV && I2C
 	---help---
 	  Support for tda9840 audio decoder chip found on some Zoran boards.
@@ -69,7 +69,7 @@
 	  module will be called tda9840.
 
 config VIDEO_TDA9875
-	tristate "Philips TDA9875 audio processor chip"
+	tristate "Philips TDA9875 audio processor"
 	depends on VIDEO_V4L1 && I2C
 	---help---
 	  Support for tda9875 audio decoder chip found on some bt8xx boards.
@@ -78,7 +78,7 @@
 	  module will be called tda9875.
 
 config VIDEO_TEA6415C
-	tristate "Philips TEA6415C audio processor chip"
+	tristate "Philips TEA6415C audio processor"
 	depends on VIDEO_DEV && I2C
 	---help---
 	  Support for tea6415c audio decoder chip found on some bt8xx boards.
@@ -87,7 +87,7 @@
 	  module will be called tea6415c.
 
 config VIDEO_TEA6420
-	tristate "Philips TEA6420 audio processor chip"
+	tristate "Philips TEA6420 audio processor"
 	depends on VIDEO_DEV && I2C
 	---help---
 	  Support for tea6420 audio decoder chip found on some bt8xx boards.
@@ -143,64 +143,10 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called wm8739.
 
-comment "MPEG video encoders"
-
-config VIDEO_CX2341X
-	tristate "Conexant CX2341x MPEG encoders"
-	depends on VIDEO_V4L2 && EXPERIMENTAL
-	---help---
-	  Support for the Conexant CX23416 MPEG encoders
-	  and CX23415 MPEG encoder/decoders.
-
-	  This module currently supports the encoding functions only.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called cx2341x.
-
-source "drivers/media/video/cx25840/Kconfig"
-
-comment "Video encoders"
-
-config VIDEO_SAA7127
-	tristate "Philips SAA7127/9 digital video encoders"
-	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
-	---help---
-	  Support for the Philips SAA7127/9 digital video encoders.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called saa7127.
-
-config VIDEO_SAA7185
-	tristate "Philips SAA7185 video encoder"
-	depends on VIDEO_V4L1 && I2C
-	---help---
-	  Support for the Philips SAA7185 video encoder.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called saa7185.
-
-config VIDEO_ADV7170
-	tristate "Analog Devices ADV7170 video encoder driver"
-	depends on VIDEO_V4L1 && I2C
-	---help---
-	  Support for the Analog Devices ADV7170 video encoder driver
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called adv7170.
-
-config VIDEO_ADV7175
-	tristate "Analog Devices ADV7175 video encoder driver"
-	depends on VIDEO_V4L1 && I2C
-	---help---
-	  Support for the Analog Devices ADV7175 video encoder driver
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called adv7175.
-
 comment "Video decoders"
 
 config VIDEO_BT819
-	tristate "BT819A VideoStream Decoder"
+	tristate "BT819A VideoStream decoder"
 	depends on VIDEO_V4L1 && I2C
 	---help---
 	  Support for BT819A video decoder.
@@ -209,7 +155,7 @@
 	  module will be called bt819.
 
 config VIDEO_BT856
-	tristate "BT856 VideoStream Decoder"
+	tristate "BT856 VideoStream decoder"
 	depends on VIDEO_V4L1 && I2C
 	---help---
 	  Support for BT856 video decoder.
@@ -218,7 +164,7 @@
 	  module will be called bt856.
 
 config VIDEO_BT866
-	tristate "BT866 VideoStream Decoder"
+	tristate "BT866 VideoStream decoder"
 	depends on VIDEO_V4L1 && I2C
 	---help---
 	  Support for BT866 video decoder.
@@ -295,7 +241,7 @@
 	  module will be called tvp5150.
 
 config VIDEO_VPX3220
-	tristate "vpx3220a, vpx3216b & vpx3214c video decoder driver"
+	tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
 	depends on VIDEO_V4L1 && I2C
 	---help---
 	  Support for VPX322x video decoders.
@@ -303,6 +249,62 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called vpx3220.
 
+comment "Video and audio decoders"
+
+source "drivers/media/video/cx25840/Kconfig"
+
+comment "MPEG video encoders"
+
+config VIDEO_CX2341X
+	tristate "Conexant CX2341x MPEG encoders"
+	depends on VIDEO_V4L2 && EXPERIMENTAL
+	---help---
+	  Support for the Conexant CX23416 MPEG encoders
+	  and CX23415 MPEG encoder/decoders.
+
+	  This module currently supports the encoding functions only.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cx2341x.
+
+comment "Video encoders"
+
+config VIDEO_SAA7127
+	tristate "Philips SAA7127/9 digital video encoders"
+	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+	---help---
+	  Support for the Philips SAA7127/9 digital video encoders.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa7127.
+
+config VIDEO_SAA7185
+	tristate "Philips SAA7185 video encoder"
+	depends on VIDEO_V4L1 && I2C
+	---help---
+	  Support for the Philips SAA7185 video encoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa7185.
+
+config VIDEO_ADV7170
+	tristate "Analog Devices ADV7170 video encoder"
+	depends on VIDEO_V4L1 && I2C
+	---help---
+	  Support for the Analog Devices ADV7170 video encoder driver
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called adv7170.
+
+config VIDEO_ADV7175
+	tristate "Analog Devices ADV7175 video encoder"
+	depends on VIDEO_V4L1 && I2C
+	---help---
+	  Support for the Analog Devices ADV7175 video encoder driver
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called adv7175.
+
 comment "Video improvement chips"
 
 config VIDEO_UPD64031A
@@ -351,7 +353,7 @@
 	help
 	  Support for  Radio Data System (RDS) decoder. This allows seeing
 	  radio station identification transmitted using this standard.
-	  Currentlly, it works only with bt8x8 chips.
+	  Currently, it works only with bt8x8 chips.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa6588.
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index d23a42b..a84903e 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -2000,7 +2000,7 @@
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
-		.muxsel         = { 3, 0, 1, 2 },
+		.muxsel         = { 3, 1 },
 		.pll            = PLL_28,
 		.no_gpioirq     = 1,
 		.has_dvb        = 1,
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 51d68f3..0f9d969 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -69,6 +69,6 @@
 	depends on VIDEO_CX88_DVB && DVB_MT352
 	---help---
 	  This adds DVB-T support for cards based on the
-	  Connexant 2388x chip and the MT352 demodulator,
+	  Conexant 2388x chip and the MT352 demodulator,
 	  which also require support for the VP-3054
 	  Secondary I2C bus, such at DNTV Live! DVB-T Pro.
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index a7921f9d..4673832 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -896,7 +896,7 @@
 		snprintf(name, sizeof(name), "%s/2", core->name);
 		printk("%s/2: ============  START LOG STATUS  ============\n",
 		       core->name);
-		cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, 0);
+		cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL);
 		cx2341x_log_status(&dev->params, name);
 		printk("%s/2: =============  END LOG STATUS  =============\n",
 		       core->name);
@@ -1086,7 +1086,7 @@
 		return -EINVAL;
 
 	err = -ENODEV;
-	if (!cx88_boards[core->board].blackbird)
+	if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))
 		goto fail_core;
 
 	err = -ENOMEM;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 6214eb8..af71d42 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -294,7 +294,7 @@
 			.type   = CX88_RADIO,
 			.gpio0  = 0x0000bd62,
 		},
-		.blackbird = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_IODATA_GVVCP3PCI] = {
 		.name		= "IODATA GV-VCP3/PCI",
@@ -358,7 +358,7 @@
 			.type   = CX88_RADIO,
 			.gpio0  = 0x0000fde2,
 		},
-		.blackbird = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_MSI_TVANYWHERE] = {
 		.name           = "MSI TV-@nywhere",
@@ -401,7 +401,7 @@
 			.gpio0  = 0x0700,
 			.gpio2  = 0x0101,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
 		.name           = "DViCO FusionHDTV DVB-T1",
@@ -418,7 +418,7 @@
 			.vmux   = 2,
 			.gpio0  = 0x000027df,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_KWORLD_LTV883] = {
 		.name           = "KWorld LTV883RF",
@@ -488,7 +488,7 @@
 			.vmux   = 2,
 			.gpio0	= 0x0f00,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_HAUPPAUGE_DVB_T1] = {
 		.name           = "Hauppauge Nova-T DVB-T",
@@ -500,7 +500,7 @@
 			.type   = CX88_VMUX_DVB,
 			.vmux   = 0,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_CONEXANT_DVB_T1] = {
 		.name           = "Conexant DVB-T reference design",
@@ -512,7 +512,7 @@
 			.type   = CX88_VMUX_DVB,
 			.vmux   = 0,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_PROVIDEO_PV259] = {
 		.name		= "Provideo PV259",
@@ -524,7 +524,7 @@
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
 		}},
-		.blackbird = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
 		.name           = "DViCO FusionHDTV DVB-T Plus",
@@ -541,7 +541,7 @@
 			.vmux   = 2,
 			.gpio0  = 0x000027df,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_DNTV_LIVE_DVB_T] = {
 		.name		= "digitalnow DNTV Live! DVB-T",
@@ -560,7 +560,7 @@
 			.gpio0  = 0x00000700,
 			.gpio2  = 0x00000101,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_PCHDTV_HD3000] = {
 		.name           = "pcHDTV HD3000 HDTV",
@@ -599,7 +599,7 @@
 			.gpio2  = 0x00000000,
 			.gpio3  = 0x00000000,
 		},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_HAUPPAUGE_ROSLYN] = {
 		// entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
@@ -633,7 +633,7 @@
 			 .gpio0  = 0xed96,
 			 .gpio2  = 0x00ff,
 		 },
-		.blackbird = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_DIGITALLOGIC_MEC] = {
 		.name           = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
@@ -659,7 +659,7 @@
 			.type   = CX88_RADIO,
 			.gpio0  = 0x00009d00,
 		},
-		.blackbird = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_IODATA_GVBCTV7E] = {
 		.name           = "IODATA GV/BCTV7E",
@@ -727,7 +727,7 @@
 			.vmux   = 2,
 			.gpio0  = 0x97e9,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_ADSTECH_DVB_T_PCI] = {
 		.name           = "ADS Tech Instant TV DVB-T PCI",
@@ -746,7 +746,7 @@
 			.gpio0  = 0x0700,
 			.gpio2  = 0x0101,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
 		.name           = "TerraTec Cinergy 1400 DVB-T",
@@ -755,7 +755,7 @@
 			.type   = CX88_VMUX_DVB,
 			.vmux   = 0,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = {
 		.name           = "DViCO FusionHDTV 5 Gold",
@@ -777,7 +777,7 @@
 			.vmux   = 2,
 			.gpio0  = 0x87f9,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
 		.name           = "AverMedia UltraTV Media Center PCI 550",
@@ -786,7 +786,7 @@
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.blackbird      = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 		.input          = {{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 0,
@@ -854,7 +854,7 @@
 			.gpio2  = 0x00000001,
 			.gpio3  = 0x00000000,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_WINFAST_DTV1000] = {
 		.name           = "WinFast DTV1000-T",
@@ -866,7 +866,7 @@
 			.type   = CX88_VMUX_DVB,
 			.vmux   = 0,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_AVERTV_303] = {
 		.name           = "AVerTV 303 (M126)",
@@ -914,7 +914,7 @@
 			.type	= CX88_VMUX_SVIDEO,
 			.vmux	= 2,
 		}},
-		.dvb		= 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = {
 		.name		= "Hauppauge Nova-SE2 DVB-S",
@@ -926,7 +926,7 @@
 			.type	= CX88_VMUX_DVB,
 			.vmux	= 0,
 		}},
-		.dvb		= 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_KWORLD_DVBS_100] = {
 		.name		= "KWorld DVB-S 100",
@@ -944,7 +944,7 @@
 			.type	= CX88_VMUX_SVIDEO,
 			.vmux	= 2,
 		}},
-		.dvb		= 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_HAUPPAUGE_HVR1100] = {
 		.name		= "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
@@ -964,7 +964,7 @@
 			.vmux	= 2,
 		}},
 		/* fixme: Add radio support */
-		.dvb		= 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
 		.name		= "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
@@ -981,7 +981,7 @@
 			.vmux	= 1,
 		}},
 		/* fixme: Add radio support */
-		.dvb		= 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
 		.name           = "digitalnow DNTV Live! DVB-T Pro",
@@ -1008,7 +1008,7 @@
 			 .type  = CX88_RADIO,
 			 .gpio0 = 0xf80808,
 		},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_KWORLD_DVB_T_CX22702] = {
 		/* Kworld V-stream Xpert DVB-T with Thomson tuner */
@@ -1030,7 +1030,7 @@
 			.gpio0  = 0x0700,
 			.gpio2  = 0x0101,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = {
 		.name           = "DViCO FusionHDTV DVB-T Dual Digital",
@@ -1047,7 +1047,7 @@
 			.vmux   = 2,
 			.gpio0  = 0x000067df,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
 		/* FIXME: Audio not working for s-video / composite inputs. */
@@ -1075,7 +1075,7 @@
 			.gpio0  = 0x3de6,
 			.gpio2  = 0x00ff,
 		},
-		.blackbird      = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = {
 		.name           = "DViCO FusionHDTV DVB-T Hybrid",
@@ -1096,7 +1096,7 @@
 			.vmux   = 2,
 			.gpio0  = 0x0000a75b,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_PCHDTV_HD5500] = {
 		.name           = "pcHDTV HD5500 HDTV",
@@ -1118,7 +1118,7 @@
 			.vmux   = 2,
 			.gpio0  = 0x87f9,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_KWORLD_MCE200_DELUXE] = {
 		/* FIXME: tested TV input only, disabled composite,
@@ -1134,7 +1134,7 @@
 			.vmux   = 0,
 			.gpio0  = 0x0000BDE6
 		}},
-		.blackbird = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = {
 		/* FIXME: SVideo, Composite and FM inputs are untested */
@@ -1150,7 +1150,7 @@
 			.vmux   = 0,
 			.gpio0  = 0x5da6,
 		}},
-		.blackbird = 1,
+		.mpeg           = CX88_MPEG_BLACKBIRD,
 	},
 	[CX88_BOARD_NPGTECH_REALTV_TOP10FM] = {
 		.name           = "NPG Tech Real TV FM Top 10",
@@ -1192,7 +1192,7 @@
 			.gpio2  = 0x00017304,
 			.gpio3  = 0x02000000,
 		}},
-		.dvb            = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_GENIATECH_DVBS] = {
 		.name          = "Geniatech DVB-S",
@@ -1207,7 +1207,7 @@
 			.type  = CX88_VMUX_COMPOSITE1,
 			.vmux  = 1,
 		}},
-		.dvb      = 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_HAUPPAUGE_HVR3000] = {
 		/* FIXME: Add dvb & radio support */
@@ -1287,6 +1287,7 @@
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
+		.audio_chip     = AUDIO_CHIP_WM8775,
 		.input		= {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -1301,7 +1302,7 @@
 			.gpio0	= 0xe780,
 		}},
 		/* fixme: Add radio support */
-		.dvb		= 1,
+		.mpeg           = CX88_MPEG_DVB,
 	},
 };
 const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -1581,6 +1582,14 @@
 		.subvendor = 0x107d,
 		.subdevice = 0x6632,
 		.card      = CX88_BOARD_LEADTEK_PVR2000,
+	},{
+		.subvendor = 0x12ab,
+		.subdevice = 0x2300, /* Club3D Zap TV2100 */
+		.card      = CX88_BOARD_KWORLD_DVB_T_CX22702,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9000,
+		.card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
 	},
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index f379ede..4b655f2 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -658,13 +658,6 @@
 	return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
 }
 
-static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
-{
-	return (norm->id & V4L2_STD_625_50)
-		? HLNotchFilter135PAL
-		: HLNotchFilter135NTSC;
-}
-
 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
 {
 	/* Should always be Line Draw Time / (4*FSC) */
@@ -937,7 +930,7 @@
 	// htotal
 	tmp64 = norm_htotal(norm) * (u64)vdec_clock;
 	do_div(tmp64, fsc8);
-	htotal = (u32)tmp64 | (norm_notchfilter(norm) << 11);
+	htotal = (u32)tmp64 | (HLNotchFilter4xFsc << 11);
 	dprintk(1,"set_tvnorm: MO_HTOTAL        0x%08x [old=0x%08x,htotal=%d]\n",
 		htotal, cx_read(MO_HTOTAL), (u32)tmp64);
 	cx_write(MO_HTOTAL, htotal);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index c87041d..bd0c879 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -802,7 +802,7 @@
 		return -EINVAL;
 
 	err = -ENODEV;
-	if (!cx88_boards[core->board].dvb)
+	if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
 		goto fail_core;
 
 	err = -ENOMEM;
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 27b5dbb..88af23a 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -145,7 +145,7 @@
 	if (0 != core->i2c_rc)
 		return;
 
-	if (core->dvbdev) {
+	if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
 		if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
 			core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
 
@@ -220,7 +220,7 @@
 
 	if (core->tuner_type != TUNER_ABSENT)
 		core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
-	if (cx88_boards[core->board].dvb)
+	if (cx88_boards[core->board].mpeg & CX88_MPEG_DVB)
 		core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
 
 	core->i2c_adap.dev.parent = &pci->dev;
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 138a4f6..d6d9807 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -65,8 +65,17 @@
 
 	/* FIXME: this needs a review.
 	 * also: move to cx88-blackbird + cx88-dvb source files? */
+	if (cx88_boards[core->board].mpeg == (CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) ) {
+		/* Report a warning until the mini driver patch is applied,
+		 * else the following conditions will set the dma registers incorrectly.
+		 * This will be removed in the next major patch and changes to the conditions
+		 * will be made.
+		 */
+		printk(KERN_INFO "%s() board->(CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) is invalid\n", __FUNCTION__);
+		return -EINVAL;
+	}
 
-	if (cx88_boards[core->board].dvb) {
+	if (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) {
 		/* negedge driven & software reset */
 		cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
 		udelay(100);
@@ -92,7 +101,7 @@
 		udelay(100);
 	}
 
-	if (cx88_boards[core->board].blackbird) {
+	if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) {
 		cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
 
 		cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 741e7c5e..58ba9f7 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -142,7 +142,7 @@
 	cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
 	cx88_start_audio_dma(core);
 
-	if (cx88_boards[core->board].blackbird) {
+	if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) {
 		/* sets sound input from external adc */
 		switch (core->board) {
 		case CX88_BOARD_HAUPPAUGE_ROSLYN:
@@ -164,7 +164,7 @@
 		cx_write(AUD_I2SCNTL, 0);
 		/* cx_write(AUD_APB_IN_RATE_ADJ, 0); */
 	}
-	if ((always_analog) || (!cx88_boards[core->board].blackbird)) {
+	if ((always_analog) || (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))) {
 		ctl |= EN_DAC_ENABLE;
 		cx_write(AUD_CTL, ctl);
 	}
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index fbc79e9..cb0c0ee 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1928,6 +1928,9 @@
 	if (TUNER_ABSENT != core->tuner_type)
 		request_module("tuner");
 
+	if (cx88_boards[ core->board ].audio_chip == AUDIO_CHIP_WM8775)
+		request_module("wm8775");
+
 	/* register v4l devices */
 	dev->video_dev = cx88_vdev_init(core,dev->pci,
 					&cx8800_video_template,"video");
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 89f12e2..3bc91aa 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -30,6 +30,7 @@
 #include <media/tveeprom.h>
 #include <media/video-buf.h>
 #include <media/cx2341x.h>
+#include <media/audiochip.h>
 #include <media/video-buf-dvb.h>
 
 #include "btcx-risc.h"
@@ -39,12 +40,6 @@
 #include <linux/mutex.h>
 #define CX88_VERSION_CODE KERNEL_VERSION(0,0,6)
 
-#ifndef TRUE
-# define TRUE (1==1)
-#endif
-#ifndef FALSE
-# define FALSE (1==0)
-#endif
 #define UNSET (-1U)
 
 #define CX88_MAXBOARDS 8
@@ -73,6 +68,12 @@
 	FM_DEEMPH_75
 };
 
+enum cx88_board_type {
+	CX88_BOARD_NONE = 0,
+	CX88_MPEG_DVB,
+	CX88_MPEG_BLACKBIRD
+};
+
 /* ----------------------------------------------------------- */
 /* tv norms                                                    */
 
@@ -230,8 +231,8 @@
 	int                     tda9887_conf;
 	struct cx88_input       input[MAX_CX88_INPUT];
 	struct cx88_input       radio;
-	unsigned int            blackbird:1;
-	unsigned int            dvb:1;
+	enum cx88_board_type    mpeg;
+	enum audiochip          audio_chip;
 };
 
 struct cx88_subid {
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index fba30a4..1457b16 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -64,23 +64,32 @@
 static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
 	unsigned char buf[3];
-	int start, toggle, dev, code;
+	int start, range, toggle, dev, code;
 
 	/* poll IR chip */
 	if (3 != i2c_master_recv(&ir->c,buf,3))
 		return -EIO;
 
 	/* split rc5 data block ... */
-	start  = (buf[0] >> 6) &    3;
+	start  = (buf[0] >> 7) &    1;
+	range  = (buf[0] >> 6) &    1;
 	toggle = (buf[0] >> 5) &    1;
 	dev    =  buf[0]       & 0x1f;
 	code   = (buf[1] >> 2) & 0x3f;
 
-	if (3 != start)
+	/* rc5 has two start bits
+	 * the first bit must be one
+	 * the second bit defines the command range (1 = 0-63, 0 = 64 - 127)
+	 */
+	if (!start)
 		/* no key pressed */
 		return 0;
-	dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
-		start, toggle, dev, code);
+
+	if (!range)
+		code += 64;
+
+	dprintk(1,"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
+		start, range, toggle, dev, code);
 
 	/* return key */
 	*ir_key = code;
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 56246b8..cf43df3 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -904,6 +904,8 @@
 	state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1;
 	/* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
 	state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2;
+	/* The msp343xG supports BTSC only and cannot do Automatic Standard Detection. */
+	state->force_btsc = msp_family == 3 && msp_revision == 'G' && msp_prod_hi == 3;
 
 	state->opmode = opmode;
 	if (state->opmode == OPMODE_AUTO) {
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
index 545e4ac..7531efa 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -64,6 +64,7 @@
 	u8 has_sound_processing;
 	u8 has_virtual_dolby_surround;
 	u8 has_dolby_pro_logic;
+	u8 force_btsc;
 
 	int radio;
 	int opmode;
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index ed02ff8..4c7f85b 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -960,9 +960,10 @@
 
 		/* setup the chip*/
 		msp34xxg_reset(client);
-		state->std = state->radio ? 0x40 : msp_standard;
-		/* start autodetect */
+		state->std = state->radio ? 0x40 :
+			(state->force_btsc && msp_standard == 1) ? 32 : msp_standard;
 		msp_write_dem(client, 0x20, state->std);
+		/* start autodetect */
 		if (state->std != 1)
 			goto unmute;
 
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index a52171e..5645c93 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -18,8 +18,8 @@
 	select VIDEO_SAA711X
 	select VIDEO_MSP3400
 	---help---
-	  This option enables support for WinTV-PVR USB2 devices whose 
-	  model number is of the form "29xxx" (leading prefix of "29" 
+	  This option enables support for WinTV-PVR USB2 devices whose
+	  model number is of the form "29xxx" (leading prefix of "29"
 	  followed by 3 digits).
 	  To see if you may need this option, examine the white
 	  sticker on the underside of your device.
@@ -37,14 +37,9 @@
 	  form "24xxx" (leading prefix of "24" followed by 3 digits).
 	  To see if you may need this option, examine the white
 	  sticker on the underside of your device.  Enabling this
-	  option will not harm support for older devices, however it
-	  is a separate option because of the experimental nature of
-	  this new feature.
+	  option will not harm support for older devices.
 
-	  If you are in doubt, say N.
-
-	  Note: This feature is _very_ experimental.  You have been
-	  warned.
+	  If you are in doubt, say Y.
 
 config VIDEO_PVRUSB2_SYSFS
 	bool "pvrusb2 sysfs support (EXPERIMENTAL)"
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 8860436..3d8cd0d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/videodev2.h>
+#include <media/v4l2-common.h>
 #include <asm/semaphore.h>
 #include "pvrusb2.h"
 #include "pvrusb2-std.h"
@@ -3131,6 +3132,42 @@
 }
 
 
+int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
+			     u32 chip_id,unsigned long reg_id,
+			     int setFl,u32 *val_ptr)
+{
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	struct list_head *item;
+	struct pvr2_i2c_client *cp;
+	struct v4l2_register req;
+	int stat = 0;
+	int okFl = 0;
+
+	req.i2c_id = chip_id;
+	req.reg = reg_id;
+	if (setFl) req.val = *val_ptr;
+	mutex_lock(&hdw->i2c_list_lock); do {
+		list_for_each(item,&hdw->i2c_clients) {
+			cp = list_entry(item,struct pvr2_i2c_client,list);
+			if (cp->client->driver->id != chip_id) continue;
+			stat = pvr2_i2c_client_cmd(
+				cp,(setFl ? VIDIOC_INT_S_REGISTER :
+				    VIDIOC_INT_G_REGISTER),&req);
+			if (!setFl) *val_ptr = req.val;
+			okFl = !0;
+			break;
+		}
+	} while (0); mutex_unlock(&hdw->i2c_list_lock);
+	if (okFl) {
+		return stat;
+	}
+	return -EINVAL;
+#else
+	return -ENOSYS;
+#endif
+}
+
+
 /*
   Stuff for Emacs to see, in order to encourage consistent editing style:
   *** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index fd931b5..29979bb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -211,6 +211,14 @@
 /* Store the v4l minor device number */
 void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int);
 
+/* Direct read/write access to chip's registers:
+   chip_id - unique id of chip (e.g. I2C_DRIVERD_xxxx)
+   reg_id  - register number to access
+   setFl   - true to set the register, false to read it
+   val_ptr - storage location for source / result. */
+int pvr2_hdw_register_access(struct pvr2_hdw *,
+			     u32 chip_id,unsigned long reg_id,
+			     int setFl,u32 *val_ptr);
 
 /* The following entry points are all lower level things you normally don't
    want to worry about. */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index ed3e810..0512166 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include "pvrusb2-i2c-core.h"
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-debug.h"
@@ -89,7 +90,8 @@
 
 const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
 {
-	if (idx >= sizeof(ops)/sizeof(ops[0])) return 0;
+	if (idx >= ARRAY_SIZE(ops))
+		return NULL;
 	return ops[idx];
 }
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 3608c2f..97e974d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -29,27 +29,17 @@
 #include "pvrusb2-v4l2.h"
 #include "pvrusb2-ioread.h"
 #include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
 #include <media/v4l2-common.h>
 
 struct pvr2_v4l2_dev;
 struct pvr2_v4l2_fh;
 struct pvr2_v4l2;
 
-/* V4L no longer provide the ability to set / get a private context pointer
-   (i.e. video_get_drvdata / video_set_drvdata), which means we have to
-   concoct our own context locating mechanism.  Supposedly this is intended
-   to simplify driver implementation.  It's not clear to me how that can
-   possibly be true.  Our solution here is to maintain a lookup table of
-   our context instances, indexed by the minor device number of the V4L
-   device.  See pvr2_v4l2_open() for some implications of this approach. */
-static struct pvr2_v4l2_dev *devices[256];
-static DEFINE_MUTEX(device_lock);
-
 struct pvr2_v4l2_dev {
+	struct video_device devbase; /* MUST be first! */
 	struct pvr2_v4l2 *v4lp;
-	struct video_device *vdev;
 	struct pvr2_context_stream *stream;
-	int ctxt_idx;
 	enum pvr2_config config;
 };
 
@@ -74,7 +64,7 @@
 	struct v4l2_prio_state prio;
 
 	/* streams */
-	struct pvr2_v4l2_dev video_dev;
+	struct pvr2_v4l2_dev *vdev;
 };
 
 static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
@@ -671,6 +661,20 @@
 		ret = 0;
 		break;
 	}
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	case VIDIOC_INT_G_REGISTER:
+	case VIDIOC_INT_S_REGISTER:
+	{
+		u32 val;
+		struct v4l2_register *req = (struct v4l2_register *)arg;
+		if (cmd == VIDIOC_INT_S_REGISTER) val = req->val;
+		ret = pvr2_hdw_register_access(
+			hdw,req->i2c_id,req->reg,
+			cmd == VIDIOC_INT_S_REGISTER,&val);
+		if (cmd == VIDIOC_INT_G_REGISTER) req->val = val;
+		break;
+	}
+#endif
 
 	default :
 		ret = v4l_compat_translate_ioctl(inode,file,cmd,
@@ -704,21 +708,22 @@
 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
 {
 	printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n",
-	       dip->vdev->minor,pvr2_config_get_name(dip->config));
-	if (dip->ctxt_idx >= 0) {
-		mutex_lock(&device_lock);
-		devices[dip->ctxt_idx] = NULL;
-		dip->ctxt_idx = -1;
-		mutex_unlock(&device_lock);
-	}
-	video_unregister_device(dip->vdev);
+	       dip->devbase.minor,pvr2_config_get_name(dip->config));
+
+	/* Paranoia */
+	dip->v4lp = 0;
+	dip->stream = 0;
+
+	/* Actual deallocation happens later when all internal references
+	   are gone. */
+	video_unregister_device(&dip->devbase);
 }
 
 
 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 {
 	pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1);
-	pvr2_v4l2_dev_destroy(&vp->video_dev);
+	pvr2_v4l2_dev_destroy(vp->vdev);
 
 	pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
 	pvr2_channel_done(&vp->channel);
@@ -726,6 +731,14 @@
 }
 
 
+static void pvr2_video_device_release(struct video_device *vdev)
+{
+	struct pvr2_v4l2_dev *dev;
+	dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
+	kfree(dev);
+}
+
+
 static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
 {
 	struct pvr2_v4l2 *vp;
@@ -797,40 +810,12 @@
 
 static int pvr2_v4l2_open(struct inode *inode, struct file *file)
 {
-	struct pvr2_v4l2_dev *dip = NULL; /* Our own context pointer */
+	struct pvr2_v4l2_dev *dip; /* Our own context pointer */
 	struct pvr2_v4l2_fh *fhp;
 	struct pvr2_v4l2 *vp;
 	struct pvr2_hdw *hdw;
 
-	mutex_lock(&device_lock);
-	/* MCI 7-Jun-2006 Even though we're just doing what amounts to an
-	   atomic read of the device mapping array here, we still need the
-	   mutex.  The problem is that there is a tiny race possible when
-	   we register the device.  We can't update the device mapping
-	   array until after the device has been registered, owing to the
-	   fact that we can't know the minor device number until after the
-	   registration succeeds.  And if another thread tries to open the
-	   device in the window of time after registration but before the
-	   map is updated, then it will get back an erroneous null pointer
-	   and the open will result in a spurious failure.  The only way to
-	   prevent that is to (a) be inside the mutex here before we access
-	   the array, and (b) cover the entire registration process later
-	   on with this same mutex.  Thus if we get inside the mutex here,
-	   then we can be assured that the registration process actually
-	   completed correctly.  This is an unhappy complication from the
-	   use of global data in a driver that lives in a preemptible
-	   environment.  It sure would be nice if the video device itself
-	   had a means for storing and retrieving a local context pointer.
-	   Oh wait.  It did.  But now it's gone.  Silly me. */
-	{
-		unsigned int midx = iminor(file->f_dentry->d_inode);
-		if (midx < sizeof(devices)/sizeof(devices[0])) {
-			dip = devices[midx];
-		}
-	}
-	mutex_unlock(&device_lock);
-
-	if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
+	dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
 
 	vp = dip->v4lp;
 	hdw = vp->channel.hdw;
@@ -1060,38 +1045,24 @@
 		return;
 	}
 
-	dip->vdev = video_device_alloc();
-	if (!dip->vdev) {
-		err("Alloc of pvrusb2 v4l video device failed");
-		return;
-	}
-
-	memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
-	dip->vdev->release = video_device_release;
-	mutex_lock(&device_lock);
+	memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
+	dip->devbase.release = pvr2_video_device_release;
 
 	mindevnum = -1;
 	unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
 	if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
 		mindevnum = video_nr[unit_number];
 	}
-	if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) &&
-	    (video_register_device(dip->vdev, v4l_type, -1) < 0)) {
+	if ((video_register_device(&dip->devbase, v4l_type, mindevnum) < 0) &&
+	    (video_register_device(&dip->devbase, v4l_type, -1) < 0)) {
 		err("Failed to register pvrusb2 v4l video device");
 	} else {
 		printk(KERN_INFO "pvrusb2: registered device video%d [%s]\n",
-		       dip->vdev->minor,pvr2_config_get_name(dip->config));
+		       dip->devbase.minor,pvr2_config_get_name(dip->config));
 	}
 
-	if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
-	    (devices[dip->vdev->minor] == NULL)) {
-		dip->ctxt_idx = dip->vdev->minor;
-		devices[dip->ctxt_idx] = dip;
-	}
-	mutex_unlock(&device_lock);
-
 	pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
-					dip->vdev->minor);
+					dip->devbase.minor);
 }
 
 
@@ -1102,15 +1073,19 @@
 	vp = kmalloc(sizeof(*vp),GFP_KERNEL);
 	if (!vp) return vp;
 	memset(vp,0,sizeof(*vp));
-	vp->video_dev.ctxt_idx = -1;
+	vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL);
+	if (!vp->vdev) {
+		kfree(vp);
+		return 0;
+	}
+	memset(vp->vdev,0,sizeof(*vp->vdev));
 	pvr2_channel_init(&vp->channel,mnp);
 	pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
 
 	vp->channel.check_func = pvr2_v4l2_internal_check;
 
 	/* register streams */
-	pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg);
-
+	pvr2_v4l2_dev_init(vp->vdev,vp,pvr2_config_mpeg);
 
 	return vp;
 }
diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/video/pwc/philips.txt
index 11f751a..f5e8484 100644
--- a/drivers/media/video/pwc/philips.txt
+++ b/drivers/media/video/pwc/philips.txt
@@ -175,8 +175,8 @@
    - If a device node is already occupied, registration will fail and
      the webcam is not available.
    - You can have up to 64 video devices; be sure to make enough device
-     nodes in /dev if you want to spread the numbers (this does not apply
-     to devfs). After /dev/video9 comes /dev/video10 (not /dev/videoA).
+     nodes in /dev if you want to spread the numbers.
+     After /dev/video9 comes /dev/video10 (not /dev/videoA).
    - If a camera does not match any dev_hint, it will simply get assigned
      the first available device node, just as it used to be.
 
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index aa1db50..fe3c83c 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -2965,6 +2965,35 @@
 			.amux = LINE1,
 		},
 	},
+	[SAA7134_BOARD_AVERMEDIA_A16AR] = {
+		/* Petr Baudis <pasky@ucw.cz> */
+		.name           = "AVerMedia TV Hybrid A16AR",
+		.audio_clock    = 0x187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290, /* untested */
+		.radio_type     = TUNER_TEA5767, /* untested */
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE1,
+		},
+	},
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3562,6 +3591,12 @@
 		.subdevice    = 0x2003,
 		.driver_data  = SAA7134_BOARD_PROTEUS_2309,
 	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x1461,
+		.subdevice    = 0x2c00,
+		.driver_data  = SAA7134_BOARD_AVERMEDIA_A16AR,
+	},{
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3703,6 +3738,7 @@
 		saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
 		saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00);
 		break;
+	case SAA7134_BOARD_AVERMEDIA_A16AR:
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS:
 		/* power-up tuner chip */
 		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0xffffffff, 0xffffffff);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index b688154..fb741fa 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1055,6 +1055,7 @@
 		}
 		break;
 	case SAA7134_BOARD_AVERMEDIA_777:
+	case SAA7134_BOARD_AVERMEDIA_A16AR:
 		printk("%s: avertv 777 dvb setup\n",dev->name);
 		dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
 					       &dev->i2c_adap);
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index f7ea857..ff59911 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -185,6 +185,7 @@
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
+	case SAA7134_BOARD_AVERMEDIA_A16AR:
 		ir_codes     = ir_codes_avermedia;
 		mask_keycode = 0x0007C8;
 		mask_keydown = 0x000010;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 7db7b97..701a909 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -226,6 +226,7 @@
 #define SAA7134_BOARD_MEDION_MD8800_QUADRO 96
 #define SAA7134_BOARD_FLYDVBS_LR300 97
 #define SAA7134_BOARD_PROTEUS_2309 98
+#define SAA7134_BOARD_AVERMEDIA_A16AR   99
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index acc5ea9..f429f49 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -365,7 +365,12 @@
 		if (NULL == fbuf)
 			return -EINVAL;
 		/* FIXME: need sanity checks for vb->boff */
-		bus   = (dma_addr_t)fbuf->base + vb->boff;
+		/*
+		 * Using a double cast to avoid compiler warnings when
+		 * building for PAE. Compiler doesn't like direct casting
+		 * of a 32 bit ptr to 64 bit integer.
+		 */
+		bus   = (dma_addr_t)(unsigned long)fbuf->base + vb->boff;
 		pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
 		err = videobuf_dma_init_overlay(&vb->dma,PCI_DMA_FROMDEVICE,
 						bus, pages);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7fc692a..3df0e7a 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -18,7 +18,7 @@
 	  service processor board as a regular serial port. To make use of
 	  this feature serial driver support (CONFIG_SERIAL_8250) must be
 	  enabled.
-	  
+
 	  WARNING: This software may not be supported or function
 	  correctly on your IBM server. Please consult the IBM ServerProven
 	  website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for
@@ -28,5 +28,33 @@
 
 	  If unsure, say N.
 
-endmenu
+config TIFM_CORE
+	tristate "TI Flash Media interface support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  If you want support for Texas Instruments(R) Flash Media adapters
+	  you should select this option and then also choose an appropriate
+	  host adapter, such as 'TI Flash Media PCI74xx/PCI76xx host adapter
+	  support', if you have a TI PCI74xx compatible card reader, for
+	  example.
+	  You will also have to select some flash card format drivers. MMC/SD
+	  cards are supported via 'MMC/SD Card support: TI Flash Media MMC/SD
+	  Interface support (MMC_TIFM_SD)'.
 
+          To compile this driver as a module, choose M here: the module will
+	  be called tifm_core.
+
+config TIFM_7XX1
+	tristate "TI Flash Media PCI74xx/PCI76xx host adapter support (EXPERIMENTAL)"
+	depends on PCI && TIFM_CORE && EXPERIMENTAL
+	default TIFM_CORE
+	help
+	  This option enables support for Texas Instruments(R) PCI74xx and
+	  PCI76xx families of Flash Media adapters, found in many laptops.
+	  To make actual use of the device, you will have to select some
+	  flash card format drivers, as outlined in the TIFM_CORE Help.
+
+          To compile this driver as a module, choose M here: the module will
+	  be called tifm_7xx1.
+
+endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 19c2b85..d65ece7 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -3,5 +3,8 @@
 #
 obj- := misc.o	# Dummy rule to force built-in.o to be made
 
-obj-$(CONFIG_IBM_ASM)	+= ibmasm/
+obj-$(CONFIG_IBM_ASM)		+= ibmasm/
 obj-$(CONFIG_HDPU_FEATURES)	+= hdpuftrs/
+obj-$(CONFIG_LKDTM)		+= lkdtm.o
+obj-$(CONFIG_TIFM_CORE)       	+= tifm_core.o
+obj-$(CONFIG_TIFM_7XX1)       	+= tifm_7xx1.o
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
new file mode 100644
index 0000000..e689ee9
--- /dev/null
+++ b/drivers/misc/lkdtm.c
@@ -0,0 +1,342 @@
+/*
+ * Kprobe module for testing crash dumps
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Ankita Garg <ankita@in.ibm.com>
+ *
+ * This module induces system failures at predefined crashpoints to
+ * evaluate the reliability of crash dumps obtained using different dumping
+ * solutions.
+ *
+ * It is adapted from the Linux Kernel Dump Test Tool by
+ * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
+ *
+ * Usage :  insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
+ *							[cpoint_count={>0}]
+ *
+ * recur_count : Recursion level for the stack overflow test. Default is 10.
+ *
+ * cpoint_name : Crash point where the kernel is to be crashed. It can be
+ *		 one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
+ *		 FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
+ *		 IDE_CORE_CP
+ *
+ * cpoint_type : Indicates the action to be taken on hitting the crash point.
+ *		 It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW
+ *
+ * cpoint_count : Indicates the number of times the crash point is to be hit
+ *		  to trigger an action. The default is 10.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <scsi/scsi_cmnd.h>
+
+#ifdef CONFIG_IDE
+#include <linux/ide.h>
+#endif
+
+#define NUM_CPOINTS 8
+#define NUM_CPOINT_TYPES 5
+#define DEFAULT_COUNT 10
+#define REC_NUM_DEFAULT 10
+
+enum cname {
+	INVALID,
+	INT_HARDWARE_ENTRY,
+	INT_HW_IRQ_EN,
+	INT_TASKLET_ENTRY,
+	FS_DEVRW,
+	MEM_SWAPOUT,
+	TIMERADD,
+	SCSI_DISPATCH_CMD,
+	IDE_CORE_CP
+};
+
+enum ctype {
+	NONE,
+	PANIC,
+	BUG,
+	EXCEPTION,
+	LOOP,
+	OVERFLOW
+};
+
+static char* cp_name[] = {
+	"INT_HARDWARE_ENTRY",
+	"INT_HW_IRQ_EN",
+	"INT_TASKLET_ENTRY",
+	"FS_DEVRW",
+	"MEM_SWAPOUT",
+	"TIMERADD",
+	"SCSI_DISPATCH_CMD",
+	"IDE_CORE_CP"
+};
+
+static char* cp_type[] = {
+	"PANIC",
+	"BUG",
+	"EXCEPTION",
+	"LOOP",
+	"OVERFLOW"
+};
+
+static struct jprobe lkdtm;
+
+static int lkdtm_parse_commandline(void);
+static void lkdtm_handler(void);
+
+static char* cpoint_name = INVALID;
+static char* cpoint_type = NONE;
+static int cpoint_count = DEFAULT_COUNT;
+static int recur_count = REC_NUM_DEFAULT;
+
+static enum cname cpoint = INVALID;
+static enum ctype cptype = NONE;
+static int count = DEFAULT_COUNT;
+
+module_param(recur_count, int, 0644);
+MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\
+				 default is 10");
+module_param(cpoint_name, charp, 0644);
+MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed");
+module_param(cpoint_type, charp, 06444);
+MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\
+				hitting the crash point");
+module_param(cpoint_count, int, 06444);
+MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \
+				crash point is to be hit to trigger action");
+
+unsigned int jp_do_irq(unsigned int irq, struct pt_regs *regs)
+{
+	lkdtm_handler();
+	jprobe_return();
+	return 0;
+}
+
+irqreturn_t jp_handle_irq_event(unsigned int irq, struct pt_regs *regs,
+			struct irqaction *action)
+{
+	lkdtm_handler();
+	jprobe_return();
+	return 0;
+}
+
+void jp_tasklet_action(struct softirq_action *a)
+{
+	lkdtm_handler();
+	jprobe_return();
+}
+
+void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
+{
+	lkdtm_handler();
+	jprobe_return();
+}
+
+struct scan_control;
+
+unsigned long jp_shrink_page_list(struct list_head *page_list,
+                                        struct scan_control *sc)
+{
+	lkdtm_handler();
+	jprobe_return();
+	return 0;
+}
+
+int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
+				const enum hrtimer_mode mode)
+{
+	lkdtm_handler();
+	jprobe_return();
+	return 0;
+}
+
+int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
+{
+	lkdtm_handler();
+	jprobe_return();
+	return 0;
+}
+
+#ifdef CONFIG_IDE
+int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
+			struct block_device *bdev, unsigned int cmd,
+			unsigned long arg)
+{
+	lkdtm_handler();
+	jprobe_return();
+	return 0;
+}
+#endif
+
+static int lkdtm_parse_commandline(void)
+{
+	int i;
+
+	if (cpoint_name == INVALID || cpoint_type == NONE ||
+					cpoint_count < 1 || recur_count < 1)
+		return -EINVAL;
+
+	for (i = 0; i < NUM_CPOINTS; ++i) {
+		if (!strcmp(cpoint_name, cp_name[i])) {
+			cpoint = i + 1;
+			break;
+		}
+	}
+
+	for (i = 0; i < NUM_CPOINT_TYPES; ++i) {
+		if (!strcmp(cpoint_type, cp_type[i])) {
+			cptype = i + 1;
+			break;
+		}
+	}
+
+	if (cpoint == INVALID || cptype == NONE)
+                return -EINVAL;
+
+	count = cpoint_count;
+
+	return 0;
+}
+
+static int recursive_loop(int a)
+{
+	char buf[1024];
+
+	memset(buf,0xFF,1024);
+	recur_count--;
+	if (!recur_count)
+		return 0;
+	else
+        	return recursive_loop(a);
+}
+
+void lkdtm_handler(void)
+{
+	printk(KERN_INFO "lkdtm : Crash point %s of type %s hit\n",
+					 cpoint_name, cpoint_type);
+	--count;
+
+	if (count == 0) {
+		switch (cptype) {
+		case NONE:
+			break;
+		case PANIC:
+			printk(KERN_INFO "lkdtm : PANIC\n");
+			panic("dumptest");
+			break;
+		case BUG:
+			printk(KERN_INFO "lkdtm : BUG\n");
+			BUG();
+			break;
+		case EXCEPTION:
+			printk(KERN_INFO "lkdtm : EXCEPTION\n");
+			*((int *) 0) = 0;
+			break;
+		case LOOP:
+			printk(KERN_INFO "lkdtm : LOOP\n");
+			for (;;);
+			break;
+		case OVERFLOW:
+			printk(KERN_INFO "lkdtm : OVERFLOW\n");
+			(void) recursive_loop(0);
+			break;
+		default:
+			break;
+		}
+		count = cpoint_count;
+	}
+}
+
+int lkdtm_module_init(void)
+{
+	int ret;
+
+	if (lkdtm_parse_commandline() == -EINVAL) {
+		printk(KERN_INFO "lkdtm : Invalid command\n");
+		return -EINVAL;
+	}
+
+	switch (cpoint) {
+	case INT_HARDWARE_ENTRY:
+		lkdtm.kp.symbol_name = "__do_IRQ";
+		lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
+		break;
+	case INT_HW_IRQ_EN:
+		lkdtm.kp.symbol_name = "handle_IRQ_event";
+		lkdtm.entry = (kprobe_opcode_t*) jp_handle_irq_event;
+		break;
+	case INT_TASKLET_ENTRY:
+		lkdtm.kp.symbol_name = "tasklet_action";
+		lkdtm.entry = (kprobe_opcode_t*) jp_tasklet_action;
+		break;
+	case FS_DEVRW:
+		lkdtm.kp.symbol_name = "ll_rw_block";
+		lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block;
+		break;
+	case MEM_SWAPOUT:
+		lkdtm.kp.symbol_name = "shrink_page_list";
+		lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list;
+		break;
+	case TIMERADD:
+		lkdtm.kp.symbol_name = "hrtimer_start";
+		lkdtm.entry = (kprobe_opcode_t*) jp_hrtimer_start;
+		break;
+	case SCSI_DISPATCH_CMD:
+		lkdtm.kp.symbol_name = "scsi_dispatch_cmd";
+		lkdtm.entry = (kprobe_opcode_t*) jp_scsi_dispatch_cmd;
+		break;
+	case IDE_CORE_CP:
+#ifdef CONFIG_IDE
+		lkdtm.kp.symbol_name = "generic_ide_ioctl";
+		lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
+#else
+		printk(KERN_INFO "lkdtm : Crash point not available\n");
+#endif
+		break;
+	default:
+		printk(KERN_INFO "lkdtm : Invalid Crash Point\n");
+		break;
+	}
+
+	if ((ret = register_jprobe(&lkdtm)) < 0) {
+                printk(KERN_INFO "lkdtm : Couldn't register jprobe\n");
+                return ret;
+	}
+
+	printk(KERN_INFO "lkdtm : Crash point %s of type %s registered\n",
+						cpoint_name, cpoint_type);
+	return 0;
+}
+
+void lkdtm_module_exit(void)
+{
+        unregister_jprobe(&lkdtm);
+        printk(KERN_INFO "lkdtm : Crash point unregistered\n");
+}
+
+module_init(lkdtm_module_init);
+module_exit(lkdtm_module_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
new file mode 100644
index 0000000..a7ed304
--- /dev/null
+++ b/drivers/misc/tifm_7xx1.c
@@ -0,0 +1,437 @@
+/*
+ *  tifm_7xx1.c - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/tifm.h>
+#include <linux/dma-mapping.h>
+
+#define DRIVER_NAME "tifm_7xx1"
+#define DRIVER_VERSION "0.6"
+
+static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock)
+{
+	int cnt;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fm->lock, flags);
+	if (!fm->inhibit_new_cards) {
+		for (cnt = 0; cnt < fm->max_sockets; cnt++) {
+			if (fm->sockets[cnt] == sock) {
+				fm->remove_mask |= (1 << cnt);
+				queue_work(fm->wq, &fm->media_remover);
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&fm->lock, flags);
+}
+
+static void tifm_7xx1_remove_media(void *adapter)
+{
+	struct tifm_adapter *fm = adapter;
+	unsigned long flags;
+	int cnt;
+	struct tifm_dev *sock;
+
+	if (!class_device_get(&fm->cdev))
+		return;
+	spin_lock_irqsave(&fm->lock, flags);
+	for (cnt = 0; cnt < fm->max_sockets; cnt++) {
+		if (fm->sockets[cnt] && (fm->remove_mask & (1 << cnt))) {
+			printk(KERN_INFO DRIVER_NAME
+			       ": demand removing card from socket %d\n", cnt);
+			sock = fm->sockets[cnt];
+			fm->sockets[cnt] = 0;
+			fm->remove_mask &= ~(1 << cnt);
+
+			writel(0x0e00, sock->addr + SOCK_CONTROL);
+
+			writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+				fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+			writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+				fm->addr + FM_SET_INTERRUPT_ENABLE);
+
+			spin_unlock_irqrestore(&fm->lock, flags);
+			device_unregister(&sock->dev);
+			spin_lock_irqsave(&fm->lock, flags);
+		}
+	}
+	spin_unlock_irqrestore(&fm->lock, flags);
+	class_device_put(&fm->cdev);
+}
+
+static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct tifm_adapter *fm = dev_id;
+	unsigned int irq_status;
+	unsigned int sock_irq_status, cnt;
+
+	spin_lock(&fm->lock);
+	irq_status = readl(fm->addr + FM_INTERRUPT_STATUS);
+	if (irq_status == 0 || irq_status == (~0)) {
+		spin_unlock(&fm->lock);
+		return IRQ_NONE;
+	}
+
+	if (irq_status & TIFM_IRQ_ENABLE) {
+		writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+
+		for (cnt = 0; cnt <  fm->max_sockets; cnt++) {
+			sock_irq_status = (irq_status >> cnt) &
+					(TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK);
+
+			if (fm->sockets[cnt]) {
+				if (sock_irq_status &&
+						fm->sockets[cnt]->signal_irq)
+					sock_irq_status = fm->sockets[cnt]->
+						signal_irq(fm->sockets[cnt],
+							sock_irq_status);
+
+				if (irq_status & (1 << cnt))
+					fm->remove_mask |= 1 << cnt;
+			} else {
+				if (irq_status & (1 << cnt))
+					fm->insert_mask |= 1 << cnt;
+			}
+		}
+	}
+	writel(irq_status, fm->addr + FM_INTERRUPT_STATUS);
+
+	if (!fm->inhibit_new_cards) {
+		if (!fm->remove_mask && !fm->insert_mask) {
+			writel(TIFM_IRQ_ENABLE,
+				fm->addr + FM_SET_INTERRUPT_ENABLE);
+		} else {
+			queue_work(fm->wq, &fm->media_remover);
+			queue_work(fm->wq, &fm->media_inserter);
+		}
+	}
+
+	spin_unlock(&fm->lock);
+	return IRQ_HANDLED;
+}
+
+static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2)
+{
+	unsigned int s_state;
+	int cnt;
+
+	writel(0x0e00, sock_addr + SOCK_CONTROL);
+
+	for (cnt = 0; cnt < 100; cnt++) {
+		if (!(TIFM_SOCK_STATE_POWERED &
+				readl(sock_addr + SOCK_PRESENT_STATE)))
+			break;
+		msleep(10);
+	}
+
+	s_state = readl(sock_addr + SOCK_PRESENT_STATE);
+	if (!(TIFM_SOCK_STATE_OCCUPIED & s_state))
+		return FM_NULL;
+
+	if (is_x2) {
+		writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL);
+	} else {
+		// SmartMedia cards need extra 40 msec
+		if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) == 1)
+			msleep(40);
+		writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED,
+		       sock_addr + SOCK_CONTROL);
+		msleep(10);
+		writel((s_state & 0x7) | 0x0c00 | TIFM_CTRL_LED,
+			sock_addr + SOCK_CONTROL);
+	}
+
+	for (cnt = 0; cnt < 100; cnt++) {
+		if ((TIFM_SOCK_STATE_POWERED &
+				readl(sock_addr + SOCK_PRESENT_STATE)))
+			break;
+		msleep(10);
+	}
+
+	if (!is_x2)
+		writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED),
+		       sock_addr + SOCK_CONTROL);
+
+	return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
+}
+
+inline static char *tifm_7xx1_sock_addr(char *base_addr, unsigned int sock_num)
+{
+	return base_addr + ((sock_num + 1) << 10);
+}
+
+static void tifm_7xx1_insert_media(void *adapter)
+{
+	struct tifm_adapter *fm = adapter;
+	unsigned long flags;
+	tifm_media_id media_id;
+	char *card_name = "xx";
+	int cnt, ok_to_register;
+	unsigned int insert_mask;
+	struct tifm_dev *new_sock = 0;
+
+	if (!class_device_get(&fm->cdev))
+		return;
+	spin_lock_irqsave(&fm->lock, flags);
+	insert_mask = fm->insert_mask;
+	fm->insert_mask = 0;
+	if (fm->inhibit_new_cards) {
+		spin_unlock_irqrestore(&fm->lock, flags);
+		class_device_put(&fm->cdev);
+		return;
+	}
+	spin_unlock_irqrestore(&fm->lock, flags);
+
+	for (cnt = 0; cnt < fm->max_sockets; cnt++) {
+		if (!(insert_mask & (1 << cnt)))
+			continue;
+
+		media_id = tifm_7xx1_toggle_sock_power(tifm_7xx1_sock_addr(fm->addr, cnt),
+						       fm->max_sockets == 2);
+		if (media_id) {
+			ok_to_register = 0;
+			new_sock = tifm_alloc_device(fm, cnt);
+			if (new_sock) {
+				new_sock->addr = tifm_7xx1_sock_addr(fm->addr,
+									cnt);
+				new_sock->media_id = media_id;
+				switch (media_id) {
+				case 1:
+					card_name = "xd";
+					break;
+				case 2:
+					card_name = "ms";
+					break;
+				case 3:
+					card_name = "sd";
+					break;
+				default:
+					break;
+				}
+				snprintf(new_sock->dev.bus_id, BUS_ID_SIZE,
+					"tifm_%s%u:%u", card_name, fm->id, cnt);
+				printk(KERN_INFO DRIVER_NAME
+					": %s card detected in socket %d\n",
+					card_name, cnt);
+				spin_lock_irqsave(&fm->lock, flags);
+				if (!fm->sockets[cnt]) {
+					fm->sockets[cnt] = new_sock;
+					ok_to_register = 1;
+				}
+				spin_unlock_irqrestore(&fm->lock, flags);
+				if (!ok_to_register ||
+					    device_register(&new_sock->dev)) {
+					spin_lock_irqsave(&fm->lock, flags);
+					fm->sockets[cnt] = 0;
+					spin_unlock_irqrestore(&fm->lock,
+								flags);
+					tifm_free_device(&new_sock->dev);
+				}
+			}
+		}
+		writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+		       fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+		writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+		       fm->addr + FM_SET_INTERRUPT_ENABLE);
+	}
+
+	writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
+	class_device_put(&fm->cdev);
+}
+
+static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	struct tifm_adapter *fm = pci_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&fm->lock, flags);
+	fm->inhibit_new_cards = 1;
+	fm->remove_mask = 0xf;
+	fm->insert_mask = 0;
+	writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+	spin_unlock_irqrestore(&fm->lock, flags);
+	flush_workqueue(fm->wq);
+
+	tifm_7xx1_remove_media(fm);
+
+	pci_set_power_state(dev, PCI_D3hot);
+        pci_disable_device(dev);
+        pci_save_state(dev);
+	return 0;
+}
+
+static int tifm_7xx1_resume(struct pci_dev *dev)
+{
+	struct tifm_adapter *fm = pci_get_drvdata(dev);
+	unsigned long flags;
+
+	pci_restore_state(dev);
+        pci_enable_device(dev);
+        pci_set_power_state(dev, PCI_D0);
+        pci_set_master(dev);
+
+	spin_lock_irqsave(&fm->lock, flags);
+	fm->inhibit_new_cards = 0;
+	writel(TIFM_IRQ_SETALL, fm->addr + FM_INTERRUPT_STATUS);
+	writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+	writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK,
+		fm->addr + FM_SET_INTERRUPT_ENABLE);
+	fm->insert_mask = 0xf;
+	spin_unlock_irqrestore(&fm->lock, flags);
+	return 0;
+}
+
+static int tifm_7xx1_probe(struct pci_dev *dev,
+			const struct pci_device_id *dev_id)
+{
+	struct tifm_adapter *fm;
+	int pci_dev_busy = 0;
+	int rc;
+
+	rc = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+	if (rc)
+		return rc;
+
+	rc = pci_enable_device(dev);
+	if (rc)
+		return rc;
+
+	pci_set_master(dev);
+
+	rc = pci_request_regions(dev, DRIVER_NAME);
+	if (rc) {
+		pci_dev_busy = 1;
+		goto err_out;
+	}
+
+	pci_intx(dev, 1);
+
+	fm = tifm_alloc_adapter();
+	if (!fm) {
+		rc = -ENOMEM;
+		goto err_out_int;
+	}
+
+	fm->dev = &dev->dev;
+	fm->max_sockets = (dev->device == 0x803B) ? 2 : 4;
+	fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->max_sockets,
+				GFP_KERNEL);
+	if (!fm->sockets)
+		goto err_out_free;
+
+	INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media, fm);
+	INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media, fm);
+	fm->eject = tifm_7xx1_eject;
+	pci_set_drvdata(dev, fm);
+
+	fm->addr = ioremap(pci_resource_start(dev, 0),
+				pci_resource_len(dev, 0));
+	if (!fm->addr)
+		goto err_out_free;
+
+	rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm);
+	if (rc)
+		goto err_out_unmap;
+
+	rc = tifm_add_adapter(fm);
+	if (rc)
+		goto err_out_irq;
+
+	writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+	writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK,
+		fm->addr + FM_SET_INTERRUPT_ENABLE);
+
+	fm->insert_mask = 0xf;
+
+	return 0;
+
+err_out_irq:
+	free_irq(dev->irq, fm);
+err_out_unmap:
+	iounmap(fm->addr);
+err_out_free:
+	pci_set_drvdata(dev, NULL);
+	tifm_free_adapter(fm);
+err_out_int:
+	pci_intx(dev, 0);
+	pci_release_regions(dev);
+err_out:
+	if (!pci_dev_busy)
+		pci_disable_device(dev);
+	return rc;
+}
+
+static void tifm_7xx1_remove(struct pci_dev *dev)
+{
+	struct tifm_adapter *fm = pci_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&fm->lock, flags);
+	fm->inhibit_new_cards = 1;
+	fm->remove_mask = 0xf;
+	fm->insert_mask = 0;
+	writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+	spin_unlock_irqrestore(&fm->lock, flags);
+
+	flush_workqueue(fm->wq);
+
+	tifm_7xx1_remove_media(fm);
+
+	writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+	free_irq(dev->irq, fm);
+
+	tifm_remove_adapter(fm);
+
+	pci_set_drvdata(dev, 0);
+
+	iounmap(fm->addr);
+	pci_intx(dev, 0);
+	pci_release_regions(dev);
+
+	pci_disable_device(dev);
+	tifm_free_adapter(fm);
+}
+
+static struct pci_device_id tifm_7xx1_pci_tbl [] = {
+	{ PCI_VENDOR_ID_TI, 0x8033, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  0 }, /* xx21 - the one I have */
+        { PCI_VENDOR_ID_TI, 0x803B, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  0 }, /* xx12 - should be also supported */
+	{ }
+};
+
+static struct pci_driver tifm_7xx1_driver = {
+	.name = DRIVER_NAME,
+	.id_table = tifm_7xx1_pci_tbl,
+	.probe = tifm_7xx1_probe,
+	.remove = tifm_7xx1_remove,
+	.suspend = tifm_7xx1_suspend,
+	.resume = tifm_7xx1_resume,
+};
+
+static int __init tifm_7xx1_init(void)
+{
+	return pci_register_driver(&tifm_7xx1_driver);
+}
+
+static void __exit tifm_7xx1_exit(void)
+{
+	pci_unregister_driver(&tifm_7xx1_driver);
+}
+
+MODULE_AUTHOR("Alex Dubov");
+MODULE_DESCRIPTION("TI FlashMedia host driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, tifm_7xx1_pci_tbl);
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tifm_7xx1_init);
+module_exit(tifm_7xx1_exit);
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
new file mode 100644
index 0000000..cca5f85
--- /dev/null
+++ b/drivers/misc/tifm_core.c
@@ -0,0 +1,272 @@
+/*
+ *  tifm_core.c - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/tifm.h>
+#include <linux/init.h>
+#include <linux/idr.h>
+
+#define DRIVER_NAME "tifm_core"
+#define DRIVER_VERSION "0.6"
+
+static DEFINE_IDR(tifm_adapter_idr);
+static DEFINE_SPINLOCK(tifm_adapter_lock);
+
+static tifm_media_id *tifm_device_match(tifm_media_id *ids,
+			struct tifm_dev *dev)
+{
+	while (*ids) {
+		if (dev->media_id == *ids)
+			return ids;
+		ids++;
+	}
+	return NULL;
+}
+
+static int tifm_match(struct device *dev, struct device_driver *drv)
+{
+	struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
+	struct tifm_driver *fm_drv;
+
+	fm_drv = container_of(drv, struct tifm_driver, driver);
+	if (!fm_drv->id_table)
+		return -EINVAL;
+	if (tifm_device_match(fm_drv->id_table, fm_dev))
+		return 1;
+	return -ENODEV;
+}
+
+static int tifm_uevent(struct device *dev, char **envp, int num_envp,
+		       char *buffer, int buffer_size)
+{
+	struct tifm_dev *fm_dev;
+	int i = 0;
+	int length = 0;
+	const char *card_type_name[] = {"INV", "SM", "MS", "SD"};
+
+	if (!dev || !(fm_dev = container_of(dev, struct tifm_dev, dev)))
+		return -ENODEV;
+	if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+			"TIFM_CARD_TYPE=%s", card_type_name[fm_dev->media_id]))
+		return -ENOMEM;
+
+	return 0;
+}
+
+static struct bus_type tifm_bus_type = {
+	.name    = "tifm",
+	.match   = tifm_match,
+	.uevent  = tifm_uevent,
+};
+
+static void tifm_free(struct class_device *cdev)
+{
+	struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev);
+
+	kfree(fm->sockets);
+	if (fm->wq)
+		destroy_workqueue(fm->wq);
+	kfree(fm);
+}
+
+static struct class tifm_adapter_class = {
+	.name    = "tifm_adapter",
+	.release = tifm_free
+};
+
+struct tifm_adapter *tifm_alloc_adapter(void)
+{
+	struct tifm_adapter *fm;
+
+	fm = kzalloc(sizeof(struct tifm_adapter), GFP_KERNEL);
+	if (fm) {
+		fm->cdev.class = &tifm_adapter_class;
+		spin_lock_init(&fm->lock);
+		class_device_initialize(&fm->cdev);
+	}
+	return fm;
+}
+EXPORT_SYMBOL(tifm_alloc_adapter);
+
+void tifm_free_adapter(struct tifm_adapter *fm)
+{
+	class_device_put(&fm->cdev);
+}
+EXPORT_SYMBOL(tifm_free_adapter);
+
+int tifm_add_adapter(struct tifm_adapter *fm)
+{
+	int rc;
+
+	if (!idr_pre_get(&tifm_adapter_idr, GFP_KERNEL))
+		return -ENOMEM;
+
+	spin_lock(&tifm_adapter_lock);
+	rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id);
+	spin_unlock(&tifm_adapter_lock);
+	if (!rc) {
+		snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id);
+		strncpy(fm->wq_name, fm->cdev.class_id, KOBJ_NAME_LEN);
+
+		fm->wq = create_singlethread_workqueue(fm->wq_name);
+		if (fm->wq)
+			return class_device_add(&fm->cdev);
+
+		spin_lock(&tifm_adapter_lock);
+		idr_remove(&tifm_adapter_idr, fm->id);
+		spin_unlock(&tifm_adapter_lock);
+		rc = -ENOMEM;
+	}
+	return rc;
+}
+EXPORT_SYMBOL(tifm_add_adapter);
+
+void tifm_remove_adapter(struct tifm_adapter *fm)
+{
+	class_device_del(&fm->cdev);
+
+	spin_lock(&tifm_adapter_lock);
+	idr_remove(&tifm_adapter_idr, fm->id);
+	spin_unlock(&tifm_adapter_lock);
+}
+EXPORT_SYMBOL(tifm_remove_adapter);
+
+void tifm_free_device(struct device *dev)
+{
+	struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
+	if (fm_dev->wq)
+		destroy_workqueue(fm_dev->wq);
+	kfree(fm_dev);
+}
+EXPORT_SYMBOL(tifm_free_device);
+
+struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id)
+{
+	struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
+
+	if (dev) {
+		spin_lock_init(&dev->lock);
+		snprintf(dev->wq_name, KOBJ_NAME_LEN, "tifm%u:%u", fm->id, id);
+		dev->wq = create_singlethread_workqueue(dev->wq_name);
+		if (!dev->wq) {
+			kfree(dev);
+			return 0;
+		}
+		dev->dev.parent = fm->dev;
+		dev->dev.bus = &tifm_bus_type;
+		dev->dev.release = tifm_free_device;
+	}
+	return dev;
+}
+EXPORT_SYMBOL(tifm_alloc_device);
+
+void tifm_eject(struct tifm_dev *sock)
+{
+	struct tifm_adapter *fm = dev_get_drvdata(sock->dev.parent);
+	fm->eject(fm, sock);
+}
+EXPORT_SYMBOL(tifm_eject);
+
+int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+		int direction)
+{
+	return pci_map_sg(to_pci_dev(sock->dev.parent), sg, nents, direction);
+}
+EXPORT_SYMBOL(tifm_map_sg);
+
+void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+		   int direction)
+{
+	pci_unmap_sg(to_pci_dev(sock->dev.parent), sg, nents, direction);
+}
+EXPORT_SYMBOL(tifm_unmap_sg);
+
+static int tifm_device_probe(struct device *dev)
+{
+	struct tifm_driver *drv;
+	struct tifm_dev *fm_dev;
+	int rc = 0;
+	const tifm_media_id *id;
+
+	drv = container_of(dev->driver, struct tifm_driver, driver);
+	fm_dev = container_of(dev, struct tifm_dev, dev);
+	get_device(dev);
+	if (!fm_dev->drv && drv->probe && drv->id_table) {
+		rc = -ENODEV;
+		id = tifm_device_match(drv->id_table, fm_dev);
+		if (id)
+			rc = drv->probe(fm_dev);
+		if (rc >= 0) {
+			rc = 0;
+			fm_dev->drv = drv;
+		}
+	}
+	if (rc)
+		put_device(dev);
+	return rc;
+}
+
+static int tifm_device_remove(struct device *dev)
+{
+	struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
+	struct tifm_driver *drv = fm_dev->drv;
+
+	if (drv) {
+		if (drv->remove) drv->remove(fm_dev);
+		fm_dev->drv = 0;
+	}
+
+	put_device(dev);
+	return 0;
+}
+
+int tifm_register_driver(struct tifm_driver *drv)
+{
+	drv->driver.bus = &tifm_bus_type;
+	drv->driver.probe = tifm_device_probe;
+	drv->driver.remove = tifm_device_remove;
+
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(tifm_register_driver);
+
+void tifm_unregister_driver(struct tifm_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(tifm_unregister_driver);
+
+static int __init tifm_init(void)
+{
+	int rc = bus_register(&tifm_bus_type);
+
+	if (!rc) {
+		rc = class_register(&tifm_adapter_class);
+		if (rc)
+			bus_unregister(&tifm_bus_type);
+	}
+
+	return rc;
+}
+
+static void __exit tifm_exit(void)
+{
+	class_unregister(&tifm_adapter_class);
+	bus_unregister(&tifm_bus_type);
+}
+
+subsys_initcall(tifm_init);
+module_exit(tifm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alex Dubov");
+MODULE_DESCRIPTION("TI FlashMedia core driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index f540bd8..ea41852 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -109,4 +109,20 @@
 
 	  If unsure, say N.
 
+config MMC_TIFM_SD
+	tristate "TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)"
+	depends on MMC && EXPERIMENTAL
+	select TIFM_CORE
+	help
+	  Say Y here if you want to be able to access MMC/SD cards with
+	  the Texas Instruments(R) Flash Media card reader, found in many
+	  laptops.
+	  This option 'selects' (turns on, enables) 'TIFM_CORE', but you
+	  probably also need appropriate card reader host adapter, such as
+	  'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support
+	  (TIFM_7XX1)'.
+
+          To compile this driver as a module, choose M here: the
+	  module will be called tifm_sd.
+
 endmenu
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index b1f6e03..acfd4de 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -23,6 +23,7 @@
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
 obj-$(CONFIG_MMC_AT91RM9200)	+= at91_mci.o
+obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
 
 mmc_core-y := mmc.o mmc_sysfs.o
 mmc_core-$(CONFIG_BLOCK) += mmc_queue.o
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5b9caa7..ee8863c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1166,9 +1166,9 @@
 void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 {
 	if (delay)
-		schedule_delayed_work(&host->detect, delay);
+		mmc_schedule_delayed_work(&host->detect, delay);
 	else
-		schedule_work(&host->detect);
+		mmc_schedule_work(&host->detect);
 }
 
 EXPORT_SYMBOL(mmc_detect_change);
@@ -1311,7 +1311,7 @@
  */
 void mmc_free_host(struct mmc_host *host)
 {
-	flush_scheduled_work();
+	mmc_flush_scheduled_work();
 	mmc_free_host_sysfs(host);
 }
 
diff --git a/drivers/mmc/mmc.h b/drivers/mmc/mmc.h
index 97bae00..cd5e0ab 100644
--- a/drivers/mmc/mmc.h
+++ b/drivers/mmc/mmc.h
@@ -18,4 +18,8 @@
 int mmc_add_host_sysfs(struct mmc_host *host);
 void mmc_remove_host_sysfs(struct mmc_host *host);
 void mmc_free_host_sysfs(struct mmc_host *host);
+
+int mmc_schedule_work(struct work_struct *work);
+int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay);
+void mmc_flush_scheduled_work(void);
 #endif
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index db0e8ad..c1293f1 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -158,13 +158,13 @@
 {
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
+	struct mmc_blk_request brq;
 	int ret;
 
 	if (mmc_card_claim_host(card))
 		goto cmd_err;
 
 	do {
-		struct mmc_blk_request brq;
 		struct mmc_command cmd;
 		u32 readcmd, writecmd;
 
@@ -278,17 +278,27 @@
  cmd_err:
 	mmc_card_release_host(card);
 
+	ret = 1;
+
 	/*
-	 * This is a little draconian, but until we get proper
-	 * error handling sorted out here, its the best we can
-	 * do - especially as some hosts have no idea how much
-	 * data was transferred before the error occurred.
+	 * For writes and where the host claims to support proper
+	 * error reporting, we first ok the successful blocks.
+	 *
+	 * For reads we just fail the entire chunk as that should
+	 * be safe in all cases.
 	 */
+	if (rq_data_dir(req) != READ &&
+	    (card->host->caps & MMC_CAP_MULTIWRITE)) {
+		spin_lock_irq(&md->lock);
+		ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered);
+		spin_unlock_irq(&md->lock);
+	}
+
 	spin_lock_irq(&md->lock);
-	do {
+	while (ret) {
 		ret = end_that_request_chunk(req, 0,
 				req->current_nr_sectors << 9);
-	} while (ret);
+	}
 
 	add_disk_randomness(req->rq_disk);
 	blkdev_dequeue_request(req);
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index a2a35fd..10cc973 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/idr.h>
+#include <linux/workqueue.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -317,10 +318,41 @@
 	class_device_put(&host->class_dev);
 }
 
+static struct workqueue_struct *workqueue;
+
+/*
+ * Internal function. Schedule work in the MMC work queue.
+ */
+int mmc_schedule_work(struct work_struct *work)
+{
+	return queue_work(workqueue, work);
+}
+
+/*
+ * Internal function. Schedule delayed work in the MMC work queue.
+ */
+int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay)
+{
+	return queue_delayed_work(workqueue, work, delay);
+}
+
+/*
+ * Internal function. Flush all scheduled work from the MMC work queue.
+ */
+void mmc_flush_scheduled_work(void)
+{
+	flush_workqueue(workqueue);
+}
 
 static int __init mmc_init(void)
 {
-	int ret = bus_register(&mmc_bus_type);
+	int ret;
+
+	workqueue = create_singlethread_workqueue("kmmcd");
+	if (!workqueue)
+		return -ENOMEM;
+
+	ret = bus_register(&mmc_bus_type);
 	if (ret == 0) {
 		ret = class_register(&mmc_host_class);
 		if (ret)
@@ -333,6 +365,7 @@
 {
 	class_unregister(&mmc_host_class);
 	bus_unregister(&mmc_bus_type);
+	destroy_workqueue(workqueue);
 }
 
 module_init(mmc_init);
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 4dab5ec..20711ac 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -35,6 +35,8 @@
 
 #define SDHCI_QUIRK_CLOCK_BEFORE_RESET			(1<<0)
 #define SDHCI_QUIRK_FORCE_DMA				(1<<1)
+/* Controller doesn't like some resets when there is no card inserted. */
+#define SDHCI_QUIRK_NO_CARD_NO_RESET			(1<<2)
 
 static const struct pci_device_id pci_ids[] __devinitdata = {
 	{
@@ -51,7 +53,8 @@
 		.device		= PCI_DEVICE_ID_RICOH_R5C822,
 		.subvendor	= PCI_ANY_ID,
 		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SDHCI_QUIRK_FORCE_DMA,
+		.driver_data	= SDHCI_QUIRK_FORCE_DMA |
+				  SDHCI_QUIRK_NO_CARD_NO_RESET,
 	},
 
 	{
@@ -125,6 +128,12 @@
 {
 	unsigned long timeout;
 
+	if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
+		if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+			SDHCI_CARD_PRESENT))
+			return;
+	}
+
 	writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
 
 	if (mask & SDHCI_RESET_ALL)
@@ -717,6 +726,7 @@
 	} else
 		sdhci_send_command(host, mrq->cmd);
 
+	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -753,6 +763,7 @@
 		ctrl &= ~SDHCI_CTRL_4BITBUS;
 	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
 
+	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -860,6 +871,7 @@
 
 	sdhci_deactivate_led(host);
 
+	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	mmc_request_done(host->mmc, mrq);
@@ -893,6 +905,7 @@
 		}
 	}
 
+	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -1030,6 +1043,7 @@
 
 	result = IRQ_HANDLED;
 
+	mmiowb();
 out:
 	spin_unlock(&host->lock);
 
@@ -1095,6 +1109,7 @@
 		if (chip->hosts[i]->flags & SDHCI_USE_DMA)
 			pci_set_master(pdev);
 		sdhci_init(chip->hosts[i]);
+		mmiowb();
 		ret = mmc_resume_host(chip->hosts[i]->mmc);
 		if (ret)
 			return ret;
@@ -1168,6 +1183,9 @@
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
 
+	host->chip = chip;
+	chip->hosts[slot] = host;
+
 	host->bar = first_bar + slot;
 
 	host->addr = pci_resource_start(pdev, host->bar);
@@ -1324,8 +1342,7 @@
 	sdhci_dumpregs(host);
 #endif
 
-	host->chip = chip;
-	chip->hosts[slot] = host;
+	mmiowb();
 
 	mmc_add_host(mmc);
 
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
new file mode 100644
index 0000000..6d23dc0
--- /dev/null
+++ b/drivers/mmc/tifm_sd.c
@@ -0,0 +1,933 @@
+/*
+ *  tifm_sd.c - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+
+#include <linux/tifm.h>
+#include <linux/mmc/protocol.h>
+#include <linux/mmc/host.h>
+#include <linux/highmem.h>
+
+#define DRIVER_NAME "tifm_sd"
+#define DRIVER_VERSION "0.6"
+
+static int no_dma = 0;
+static int fixed_timeout = 0;
+module_param(no_dma, bool, 0644);
+module_param(fixed_timeout, bool, 0644);
+
+/* Constants here are mostly from OMAP5912 datasheet */
+#define TIFM_MMCSD_RESET      0x0002
+#define TIFM_MMCSD_CLKMASK    0x03ff
+#define TIFM_MMCSD_POWER      0x0800
+#define TIFM_MMCSD_4BBUS      0x8000
+#define TIFM_MMCSD_RXDE       0x8000   /* rx dma enable */
+#define TIFM_MMCSD_TXDE       0x0080   /* tx dma enable */
+#define TIFM_MMCSD_BUFINT     0x0c00   /* set bits: AE, AF */
+#define TIFM_MMCSD_DPE        0x0020   /* data timeout counted in kilocycles */
+#define TIFM_MMCSD_INAB       0x0080   /* abort / initialize command */
+#define TIFM_MMCSD_READ       0x8000
+
+#define TIFM_MMCSD_DATAMASK   0x001d   /* set bits: EOFB, BRS, CB, EOC */
+#define TIFM_MMCSD_ERRMASK    0x41e0   /* set bits: CERR, CCRC, CTO, DCRC, DTO */
+#define TIFM_MMCSD_EOC        0x0001   /* end of command phase  */
+#define TIFM_MMCSD_CB         0x0004   /* card enter busy state */
+#define TIFM_MMCSD_BRS        0x0008   /* block received/sent   */
+#define TIFM_MMCSD_EOFB       0x0010   /* card exit busy state  */
+#define TIFM_MMCSD_DTO        0x0020   /* data time-out         */
+#define TIFM_MMCSD_DCRC       0x0040   /* data crc error        */
+#define TIFM_MMCSD_CTO        0x0080   /* command time-out      */
+#define TIFM_MMCSD_CCRC       0x0100   /* command crc error     */
+#define TIFM_MMCSD_AF         0x0400   /* fifo almost full      */
+#define TIFM_MMCSD_AE         0x0800   /* fifo almost empty     */
+#define TIFM_MMCSD_CERR       0x4000   /* card status error     */
+
+#define TIFM_MMCSD_FIFO_SIZE  0x0020
+
+#define TIFM_MMCSD_RSP_R0     0x0000
+#define TIFM_MMCSD_RSP_R1     0x0100
+#define TIFM_MMCSD_RSP_R2     0x0200
+#define TIFM_MMCSD_RSP_R3     0x0300
+#define TIFM_MMCSD_RSP_R4     0x0400
+#define TIFM_MMCSD_RSP_R5     0x0500
+#define TIFM_MMCSD_RSP_R6     0x0600
+
+#define TIFM_MMCSD_RSP_BUSY   0x0800
+
+#define TIFM_MMCSD_CMD_BC     0x0000
+#define TIFM_MMCSD_CMD_BCR    0x1000
+#define TIFM_MMCSD_CMD_AC     0x2000
+#define TIFM_MMCSD_CMD_ADTC   0x3000
+
+typedef enum {
+	IDLE = 0,
+	CMD,    /* main command ended                   */
+	BRS,    /* block transfer finished              */
+	SCMD,   /* stop command ended                   */
+	CARD,   /* card left busy state                 */
+	FIFO,   /* FIFO operation completed (uncertain) */
+	READY
+} card_state_t;
+
+enum {
+	FIFO_RDY   = 0x0001,     /* hardware dependent value */
+	HOST_REG   = 0x0002,
+	EJECT      = 0x0004,
+	EJECT_DONE = 0x0008,
+	CARD_BUSY  = 0x0010,
+	OPENDRAIN  = 0x0040,     /* hardware dependent value */
+	CARD_EVENT = 0x0100,     /* hardware dependent value */
+	CARD_RO    = 0x0200,     /* hardware dependent value */
+	FIFO_EVENT = 0x10000 };  /* hardware dependent value */
+
+struct tifm_sd {
+	struct tifm_dev     *dev;
+
+	unsigned int        flags;
+	card_state_t        state;
+	unsigned int        clk_freq;
+	unsigned int        clk_div;
+	unsigned long       timeout_jiffies; // software timeout - 2 sec
+
+	struct mmc_request    *req;
+	struct work_struct    cmd_handler;
+	struct work_struct    abort_handler;
+	wait_queue_head_t     can_eject;
+
+	size_t                written_blocks;
+	char                  *buffer;
+	size_t                buffer_size;
+	size_t                buffer_pos;
+
+};
+
+static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host,
+					unsigned int host_status)
+{
+	struct mmc_command *cmd = host->req->cmd;
+	unsigned int t_val = 0, cnt = 0;
+
+	if (host_status & TIFM_MMCSD_BRS) {
+		/* in non-dma rx mode BRS fires when fifo is still not empty */
+		if (host->buffer && (cmd->data->flags & MMC_DATA_READ)) {
+			while (host->buffer_size > host->buffer_pos) {
+				t_val = readl(sock->addr + SOCK_MMCSD_DATA);
+				host->buffer[host->buffer_pos++] = t_val & 0xff;
+				host->buffer[host->buffer_pos++] =
+							(t_val >> 8) & 0xff;
+			}
+		}
+		return 1;
+	} else if (host->buffer) {
+		if ((cmd->data->flags & MMC_DATA_READ) &&
+				(host_status & TIFM_MMCSD_AF)) {
+			for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
+				t_val = readl(sock->addr + SOCK_MMCSD_DATA);
+				if (host->buffer_size > host->buffer_pos) {
+					host->buffer[host->buffer_pos++] =
+							t_val & 0xff;
+					host->buffer[host->buffer_pos++] =
+							(t_val >> 8) & 0xff;
+				}
+			}
+		} else if ((cmd->data->flags & MMC_DATA_WRITE)
+			   && (host_status & TIFM_MMCSD_AE)) {
+			for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
+				if (host->buffer_size > host->buffer_pos) {
+					t_val = host->buffer[host->buffer_pos++] & 0x00ff;
+					t_val |= ((host->buffer[host->buffer_pos++]) << 8)
+						 & 0xff00;
+					writel(t_val,
+						sock->addr + SOCK_MMCSD_DATA);
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+static unsigned int tifm_sd_op_flags(struct mmc_command *cmd)
+{
+	unsigned int rc = 0;
+
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_NONE:
+		rc |= TIFM_MMCSD_RSP_R0;
+		break;
+	case MMC_RSP_R1B:
+		rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through
+	case MMC_RSP_R1:
+		rc |= TIFM_MMCSD_RSP_R1;
+		break;
+	case MMC_RSP_R2:
+		rc |= TIFM_MMCSD_RSP_R2;
+		break;
+	case MMC_RSP_R3:
+		rc |= TIFM_MMCSD_RSP_R3;
+		break;
+	case MMC_RSP_R6:
+		rc |= TIFM_MMCSD_RSP_R6;
+		break;
+	default:
+		BUG();
+	}
+
+	switch (mmc_cmd_type(cmd)) {
+	case MMC_CMD_BC:
+		rc |= TIFM_MMCSD_CMD_BC;
+		break;
+	case MMC_CMD_BCR:
+		rc |= TIFM_MMCSD_CMD_BCR;
+		break;
+	case MMC_CMD_AC:
+		rc |= TIFM_MMCSD_CMD_AC;
+		break;
+	case MMC_CMD_ADTC:
+		rc |= TIFM_MMCSD_CMD_ADTC;
+		break;
+	default:
+		BUG();
+	}
+	return rc;
+}
+
+static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd)
+{
+	struct tifm_dev *sock = host->dev;
+	unsigned int cmd_mask = tifm_sd_op_flags(cmd) |
+				(host->flags & OPENDRAIN);
+
+	if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
+		cmd_mask |= TIFM_MMCSD_READ;
+
+	dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n",
+				cmd->opcode, cmd->arg, cmd_mask);
+
+	writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH);
+	writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW);
+	writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND);
+}
+
+static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock)
+{
+	cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16)
+		       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18);
+	cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16)
+		       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10);
+	cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16)
+		       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08);
+	cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16)
+		       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00);
+}
+
+static void tifm_sd_process_cmd(struct tifm_dev *sock, struct tifm_sd *host,
+				       unsigned int host_status)
+{
+	struct mmc_command *cmd = host->req->cmd;
+
+change_state:
+	switch (host->state) {
+	case IDLE:
+		return;
+	case CMD:
+		if (host_status & TIFM_MMCSD_EOC) {
+			tifm_sd_fetch_resp(cmd, sock);
+			if (cmd->data) {
+				host->state = BRS;
+			} else
+				host->state = READY;
+			goto change_state;
+		}
+		break;
+	case BRS:
+		if (tifm_sd_transfer_data(sock, host, host_status)) {
+			if (!host->req->stop) {
+				if (cmd->data->flags & MMC_DATA_WRITE) {
+					host->state = CARD;
+				} else {
+					host->state =
+						host->buffer ? READY : FIFO;
+				}
+				goto change_state;
+			}
+			tifm_sd_exec(host, host->req->stop);
+			host->state = SCMD;
+		}
+		break;
+	case SCMD:
+		if (host_status & TIFM_MMCSD_EOC) {
+			tifm_sd_fetch_resp(host->req->stop, sock);
+			if (cmd->error) {
+				host->state = READY;
+			} else if (cmd->data->flags & MMC_DATA_WRITE) {
+				host->state = CARD;
+			} else {
+				host->state = host->buffer ? READY : FIFO;
+			}
+			goto change_state;
+		}
+		break;
+	case CARD:
+		if (!(host->flags & CARD_BUSY)
+		    && (host->written_blocks == cmd->data->blocks)) {
+			host->state = host->buffer ? READY : FIFO;
+			goto change_state;
+		}
+		break;
+	case FIFO:
+		if (host->flags & FIFO_RDY) {
+			host->state = READY;
+			host->flags &= ~FIFO_RDY;
+			goto change_state;
+		}
+		break;
+	case READY:
+		queue_work(sock->wq, &host->cmd_handler);
+		return;
+	}
+
+	queue_delayed_work(sock->wq, &host->abort_handler,
+				host->timeout_jiffies);
+}
+
+/* Called from interrupt handler */
+static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
+					unsigned int sock_irq_status)
+{
+	struct tifm_sd *host;
+	unsigned int host_status = 0, fifo_status = 0;
+	int error_code = 0;
+
+	spin_lock(&sock->lock);
+	host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
+	cancel_delayed_work(&host->abort_handler);
+
+	if (sock_irq_status & FIFO_EVENT) {
+		fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
+		writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
+
+		host->flags |= fifo_status & FIFO_RDY;
+	}
+
+	if (sock_irq_status & CARD_EVENT) {
+		host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
+		writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
+
+		if (!(host->flags & HOST_REG))
+			queue_work(sock->wq, &host->cmd_handler);
+		if (!host->req)
+			goto done;
+
+		if (host_status & TIFM_MMCSD_ERRMASK) {
+			if (host_status & TIFM_MMCSD_CERR)
+				error_code = MMC_ERR_FAILED;
+			else if (host_status &
+					(TIFM_MMCSD_CTO | TIFM_MMCSD_DTO))
+				error_code = MMC_ERR_TIMEOUT;
+			else if (host_status &
+					(TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC))
+				error_code = MMC_ERR_BADCRC;
+
+			writel(TIFM_FIFO_INT_SETALL,
+			       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
+			writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
+
+			if (host->req->stop) {
+				if (host->state == SCMD) {
+					host->req->stop->error = error_code;
+				} else if(host->state == BRS) {
+					host->req->cmd->error = error_code;
+					tifm_sd_exec(host, host->req->stop);
+					queue_delayed_work(sock->wq,
+						&host->abort_handler,
+						host->timeout_jiffies);
+					host->state = SCMD;
+					goto done;
+				} else {
+					host->req->cmd->error = error_code;
+				}
+			} else {
+				host->req->cmd->error = error_code;
+			}
+			host->state = READY;
+		}
+
+		if (host_status & TIFM_MMCSD_CB)
+			host->flags |= CARD_BUSY;
+		if ((host_status & TIFM_MMCSD_EOFB) &&
+				(host->flags & CARD_BUSY)) {
+			host->written_blocks++;
+			host->flags &= ~CARD_BUSY;
+		}
+        }
+
+	if (host->req)
+		tifm_sd_process_cmd(sock, host, host_status);
+done:
+	dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n",
+			host_status, fifo_status);
+	spin_unlock(&sock->lock);
+	return sock_irq_status;
+}
+
+static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd)
+{
+	struct tifm_dev *sock = card->dev;
+	unsigned int dest_cnt;
+
+	/* DMA style IO */
+
+	writel(TIFM_FIFO_INT_SETALL,
+		sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
+	writel(long_log2(cmd->data->blksz) - 2,
+			sock->addr + SOCK_FIFO_PAGE_SIZE);
+	writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL);
+	writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
+
+	dest_cnt = (cmd->data->blocks) << 8;
+
+	writel(sg_dma_address(cmd->data->sg), sock->addr + SOCK_DMA_ADDRESS);
+
+	writel(cmd->data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
+	writel(cmd->data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN);
+
+	if (cmd->data->flags & MMC_DATA_WRITE) {
+		writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+		writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN,
+			sock->addr + SOCK_DMA_CONTROL);
+	} else {
+		writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+		writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL);
+	}
+}
+
+static void tifm_sd_set_data_timeout(struct tifm_sd *host,
+					struct mmc_data *data)
+{
+	struct tifm_dev *sock = host->dev;
+	unsigned int data_timeout = data->timeout_clks;
+
+	if (fixed_timeout)
+		return;
+
+	data_timeout += data->timeout_ns /
+			((1000000000 / host->clk_freq) * host->clk_div);
+	data_timeout *= 10; // call it fudge factor for now
+
+	if (data_timeout < 0xffff) {
+		writel((~TIFM_MMCSD_DPE) &
+				readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
+		       sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
+		writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
+	} else {
+		writel(TIFM_MMCSD_DPE |
+				readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
+			sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
+		data_timeout = (data_timeout >> 10) + 1;
+		if(data_timeout > 0xffff)
+			data_timeout = 0;	/* set to unlimited */
+		writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
+	}
+}
+
+static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct tifm_sd *host = mmc_priv(mmc);
+	struct tifm_dev *sock = host->dev;
+	unsigned long flags;
+	int sg_count = 0;
+	struct mmc_data *r_data = mrq->cmd->data;
+
+	spin_lock_irqsave(&sock->lock, flags);
+	if (host->flags & EJECT) {
+		spin_unlock_irqrestore(&sock->lock, flags);
+		goto err_out;
+	}
+
+	if (host->req) {
+		printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n");
+		spin_unlock_irqrestore(&sock->lock, flags);
+		goto err_out;
+	}
+
+	if (r_data) {
+		tifm_sd_set_data_timeout(host, r_data);
+
+		sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len,
+				       mrq->cmd->flags & MMC_DATA_WRITE
+				       ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+		if (sg_count != 1) {
+			printk(KERN_ERR DRIVER_NAME
+				": scatterlist map failed\n");
+			spin_unlock_irqrestore(&sock->lock, flags);
+			goto err_out;
+		}
+
+		host->written_blocks = 0;
+		host->flags &= ~CARD_BUSY;
+		tifm_sd_prepare_data(host, mrq->cmd);
+	}
+
+	host->req = mrq;
+	host->state = CMD;
+	queue_delayed_work(sock->wq, &host->abort_handler,
+				host->timeout_jiffies);
+	writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
+		sock->addr + SOCK_CONTROL);
+	tifm_sd_exec(host, mrq->cmd);
+	spin_unlock_irqrestore(&sock->lock, flags);
+	return;
+
+err_out:
+	if (sg_count > 0)
+		tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
+			      (r_data->flags & MMC_DATA_WRITE)
+			      ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+
+	mrq->cmd->error = MMC_ERR_TIMEOUT;
+	mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_end_cmd(void *data)
+{
+	struct tifm_sd *host = data;
+	struct tifm_dev *sock = host->dev;
+	struct mmc_host *mmc = tifm_get_drvdata(sock);
+	struct mmc_request *mrq;
+	struct mmc_data *r_data = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sock->lock, flags);
+
+	mrq = host->req;
+	host->req = 0;
+	host->state = IDLE;
+
+	if (!mrq) {
+		printk(KERN_ERR DRIVER_NAME ": no request to complete?\n");
+		spin_unlock_irqrestore(&sock->lock, flags);
+		return;
+	}
+
+	r_data = mrq->cmd->data;
+	if (r_data) {
+		if (r_data->flags & MMC_DATA_WRITE) {
+			r_data->bytes_xfered = host->written_blocks *
+						r_data->blksz;
+		} else {
+			r_data->bytes_xfered = r_data->blocks -
+				readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
+			r_data->bytes_xfered *= r_data->blksz;
+			r_data->bytes_xfered += r_data->blksz -
+				readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
+		}
+		tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
+			      (r_data->flags & MMC_DATA_WRITE)
+			      ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+	}
+
+	writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
+			sock->addr + SOCK_CONTROL);
+
+	spin_unlock_irqrestore(&sock->lock, flags);
+	mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct tifm_sd *host = mmc_priv(mmc);
+	struct tifm_dev *sock = host->dev;
+	unsigned long flags;
+	struct mmc_data *r_data = mrq->cmd->data;
+	char *t_buffer = 0;
+
+	if (r_data) {
+		t_buffer = kmap(r_data->sg->page);
+		if (!t_buffer) {
+			printk(KERN_ERR DRIVER_NAME ": kmap failed\n");
+			goto err_out;
+		}
+	}
+
+	spin_lock_irqsave(&sock->lock, flags);
+	if (host->flags & EJECT) {
+		spin_unlock_irqrestore(&sock->lock, flags);
+		goto err_out;
+	}
+
+	if (host->req) {
+		printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n");
+		spin_unlock_irqrestore(&sock->lock, flags);
+		goto err_out;
+	}
+
+	if (r_data) {
+		tifm_sd_set_data_timeout(host, r_data);
+
+		host->buffer = t_buffer + r_data->sg->offset;
+		host->buffer_size = mrq->cmd->data->blocks *
+					mrq->cmd->data->blksz;
+
+		writel(TIFM_MMCSD_BUFINT |
+				readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
+		       sock->addr + SOCK_MMCSD_INT_ENABLE);
+		writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) |
+				(TIFM_MMCSD_FIFO_SIZE - 1),
+		       sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+
+		host->written_blocks = 0;
+		host->flags &= ~CARD_BUSY;
+		host->buffer_pos = 0;
+		writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
+		writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN);
+	}
+
+	host->req = mrq;
+	host->state = CMD;
+	queue_delayed_work(sock->wq, &host->abort_handler,
+				host->timeout_jiffies);
+	writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
+		sock->addr + SOCK_CONTROL);
+	tifm_sd_exec(host, mrq->cmd);
+	spin_unlock_irqrestore(&sock->lock, flags);
+	return;
+
+err_out:
+	if (t_buffer)
+		kunmap(r_data->sg->page);
+
+	mrq->cmd->error = MMC_ERR_TIMEOUT;
+	mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_end_cmd_nodma(void *data)
+{
+	struct tifm_sd *host = (struct tifm_sd*)data;
+	struct tifm_dev *sock = host->dev;
+	struct mmc_host *mmc = tifm_get_drvdata(sock);
+	struct mmc_request *mrq;
+	struct mmc_data *r_data = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sock->lock, flags);
+
+	mrq = host->req;
+	host->req = 0;
+	host->state = IDLE;
+
+	if (!mrq) {
+		printk(KERN_ERR DRIVER_NAME ": no request to complete?\n");
+		spin_unlock_irqrestore(&sock->lock, flags);
+		return;
+	}
+
+	r_data = mrq->cmd->data;
+	if (r_data) {
+		writel((~TIFM_MMCSD_BUFINT) &
+			readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
+			sock->addr + SOCK_MMCSD_INT_ENABLE);
+
+		if (r_data->flags & MMC_DATA_WRITE) {
+			r_data->bytes_xfered = host->written_blocks *
+						r_data->blksz;
+		} else {
+			r_data->bytes_xfered = r_data->blocks -
+				readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
+			r_data->bytes_xfered *= r_data->blksz;
+			r_data->bytes_xfered += r_data->blksz -
+				readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
+		}
+		host->buffer = 0;
+		host->buffer_pos = 0;
+		host->buffer_size = 0;
+	}
+
+	writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
+			sock->addr + SOCK_CONTROL);
+
+	spin_unlock_irqrestore(&sock->lock, flags);
+
+        if (r_data)
+		kunmap(r_data->sg->page);
+
+	mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_abort(void *data)
+{
+	printk(KERN_ERR DRIVER_NAME
+		": card failed to respond for a long period of time");
+	tifm_eject(((struct tifm_sd*)data)->dev);
+}
+
+static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct tifm_sd *host = mmc_priv(mmc);
+	struct tifm_dev *sock = host->dev;
+	unsigned int clk_div1, clk_div2;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sock->lock, flags);
+
+	dev_dbg(&sock->dev, "Setting bus width %d, power %d\n", ios->bus_width,
+		ios->power_mode);
+	if (ios->bus_width == MMC_BUS_WIDTH_4) {
+		writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG),
+		       sock->addr + SOCK_MMCSD_CONFIG);
+	} else {
+		writel((~TIFM_MMCSD_4BBUS) &
+				readl(sock->addr + SOCK_MMCSD_CONFIG),
+			sock->addr + SOCK_MMCSD_CONFIG);
+	}
+
+	if (ios->clock) {
+		clk_div1 = 20000000 / ios->clock;
+		if (!clk_div1)
+			clk_div1 = 1;
+
+		clk_div2 = 24000000 / ios->clock;
+		if (!clk_div2)
+			clk_div2 = 1;
+
+		if ((20000000 / clk_div1) > ios->clock)
+			clk_div1++;
+		if ((24000000 / clk_div2) > ios->clock)
+			clk_div2++;
+		if ((20000000 / clk_div1) > (24000000 / clk_div2)) {
+			host->clk_freq = 20000000;
+			host->clk_div = clk_div1;
+			writel((~TIFM_CTRL_FAST_CLK) &
+					readl(sock->addr + SOCK_CONTROL),
+				sock->addr + SOCK_CONTROL);
+		} else {
+			host->clk_freq = 24000000;
+			host->clk_div = clk_div2;
+			writel(TIFM_CTRL_FAST_CLK |
+					readl(sock->addr + SOCK_CONTROL),
+				sock->addr + SOCK_CONTROL);
+		}
+	} else {
+		host->clk_div = 0;
+	}
+	host->clk_div &= TIFM_MMCSD_CLKMASK;
+	writel(host->clk_div | ((~TIFM_MMCSD_CLKMASK) &
+			readl(sock->addr + SOCK_MMCSD_CONFIG)),
+		sock->addr + SOCK_MMCSD_CONFIG);
+
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+		host->flags |= OPENDRAIN;
+	else
+		host->flags &= ~OPENDRAIN;
+
+	/* chip_select : maybe later */
+	//vdd
+	//power is set before probe / after remove
+	//I believe, power_off when already marked for eject is sufficient to
+	// allow removal.
+	if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) {
+		host->flags |= EJECT_DONE;
+		wake_up_all(&host->can_eject);
+	}
+
+	spin_unlock_irqrestore(&sock->lock, flags);
+}
+
+static int tifm_sd_ro(struct mmc_host *mmc)
+{
+	int rc;
+	struct tifm_sd *host = mmc_priv(mmc);
+	struct tifm_dev *sock = host->dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sock->lock, flags);
+
+	host->flags |= (CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE));
+	rc = (host->flags & CARD_RO) ? 1 : 0;
+
+	spin_unlock_irqrestore(&sock->lock, flags);
+	return rc;
+}
+
+static struct mmc_host_ops tifm_sd_ops = {
+	.request = tifm_sd_request,
+	.set_ios = tifm_sd_ios,
+	.get_ro  = tifm_sd_ro
+};
+
+static void tifm_sd_register_host(void *data)
+{
+	struct tifm_sd *host = (struct tifm_sd*)data;
+	struct tifm_dev *sock = host->dev;
+	struct mmc_host *mmc = tifm_get_drvdata(sock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sock->lock, flags);
+	host->flags |= HOST_REG;
+	PREPARE_WORK(&host->cmd_handler,
+			no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
+			data);
+	spin_unlock_irqrestore(&sock->lock, flags);
+	dev_dbg(&sock->dev, "adding host\n");
+	mmc_add_host(mmc);
+}
+
+static int tifm_sd_probe(struct tifm_dev *sock)
+{
+	struct mmc_host *mmc;
+	struct tifm_sd *host;
+	int rc = -EIO;
+
+	if (!(TIFM_SOCK_STATE_OCCUPIED &
+			readl(sock->addr + SOCK_PRESENT_STATE))) {
+		printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n");
+		return rc;
+	}
+
+	mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev);
+	if (!mmc)
+		return -ENOMEM;
+
+	host = mmc_priv(mmc);
+	host->dev = sock;
+	host->clk_div = 61;
+	init_waitqueue_head(&host->can_eject);
+	INIT_WORK(&host->cmd_handler, tifm_sd_register_host, host);
+	INIT_WORK(&host->abort_handler, tifm_sd_abort, host);
+
+	tifm_set_drvdata(sock, mmc);
+	sock->signal_irq = tifm_sd_signal_irq;
+
+	host->clk_freq = 20000000;
+	host->timeout_jiffies = msecs_to_jiffies(1000);
+
+	tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request;
+	mmc->ops = &tifm_sd_ops;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->caps = MMC_CAP_4_BIT_DATA;
+	mmc->f_min = 20000000 / 60;
+	mmc->f_max = 24000000;
+	mmc->max_hw_segs = 1;
+	mmc->max_phys_segs = 1;
+	mmc->max_sectors = 127;
+	mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length
+
+	writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
+	writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL);
+	writel(host->clk_div | TIFM_MMCSD_POWER,
+			sock->addr + SOCK_MMCSD_CONFIG);
+
+	for (rc = 0; rc < 50; rc++) {
+		/* Wait for reset ack */
+		if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) {
+			rc = 0;
+			break;
+		}
+		msleep(10);
+        }
+
+	if (rc) {
+		printk(KERN_ERR DRIVER_NAME
+			": card not ready - probe failed\n");
+		mmc_free_host(mmc);
+		return -ENODEV;
+	}
+
+	writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
+	writel(host->clk_div | TIFM_MMCSD_POWER,
+			sock->addr + SOCK_MMCSD_CONFIG);
+	writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+	writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK,
+			sock->addr + SOCK_MMCSD_INT_ENABLE);
+
+	writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); // command timeout 64 clocks for now
+	writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND);
+	writel(host->clk_div | TIFM_MMCSD_POWER,
+			sock->addr + SOCK_MMCSD_CONFIG);
+
+	queue_delayed_work(sock->wq, &host->abort_handler,
+			host->timeout_jiffies);
+
+	return 0;
+}
+
+static int tifm_sd_host_is_down(struct tifm_dev *sock)
+{
+	struct mmc_host *mmc = tifm_get_drvdata(sock);
+	struct tifm_sd *host = mmc_priv(mmc);
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&sock->lock, flags);
+	rc = (host->flags & EJECT_DONE);
+	spin_unlock_irqrestore(&sock->lock, flags);
+	return rc;
+}
+
+static void tifm_sd_remove(struct tifm_dev *sock)
+{
+	struct mmc_host *mmc = tifm_get_drvdata(sock);
+	struct tifm_sd *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sock->lock, flags);
+	host->flags |= EJECT;
+	if (host->req)
+		queue_work(sock->wq, &host->cmd_handler);
+	spin_unlock_irqrestore(&sock->lock, flags);
+	wait_event_timeout(host->can_eject, tifm_sd_host_is_down(sock),
+				host->timeout_jiffies);
+
+	if (host->flags & HOST_REG)
+		mmc_remove_host(mmc);
+
+	/* The meaning of the bit majority in this constant is unknown. */
+	writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
+		sock->addr + SOCK_CONTROL);
+	writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
+	writel(TIFM_FIFO_INT_SETALL,
+		sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
+	writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
+
+	tifm_set_drvdata(sock, 0);
+	mmc_free_host(mmc);
+}
+
+static tifm_media_id tifm_sd_id_tbl[] = {
+	FM_SD, 0
+};
+
+static struct tifm_driver tifm_sd_driver = {
+	.driver = {
+		.name  = DRIVER_NAME,
+		.owner = THIS_MODULE
+	},
+	.id_table = tifm_sd_id_tbl,
+	.probe    = tifm_sd_probe,
+	.remove   = tifm_sd_remove
+};
+
+static int __init tifm_sd_init(void)
+{
+	return tifm_register_driver(&tifm_sd_driver);
+}
+
+static void __exit tifm_sd_exit(void)
+{
+	tifm_unregister_driver(&tifm_sd_driver);
+}
+
+MODULE_AUTHOR("Alex Dubov");
+MODULE_DESCRIPTION("TI FlashMedia SD driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl);
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tifm_sd_init);
+module_exit(tifm_sd_exit);
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 6d8f30d..72e6d73 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -270,7 +270,7 @@
 	tristate "JEDEC device support"
 	depends on MTD && MTD_OBSOLETE_CHIPS && BROKEN
 	help
-	  Enable older older JEDEC flash interface devices for self
+	  Enable older JEDEC flash interface devices for self
 	  programming flash.  It is commonly used in older AMD chips.  It is
 	  only called JEDEC because the JEDEC association
 	  <http://www.jedec.org/> distributes the identification codes for the
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index 642d96b..2cc9024 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -96,7 +96,7 @@
 static int __init
 init_arctic_mtd(void)
 {
-	int err = 0;
+	int err;
 
 	printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
 
@@ -112,7 +112,7 @@
 	arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
 
 	if (!arctic_mtd) {
-		iounmap((void *) arctic_mtd_map.virt);
+		iounmap(arctic_mtd_map.virt);
 		return -ENXIO;
 	}
 
@@ -121,7 +121,7 @@
 	err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
 	if (err) {
 		printk("%s: add_mtd_partitions failed\n", NAME);
-		iounmap((void *) arctic_mtd_map.virt);
+		iounmap(arctic_mtd_map.virt);
 	}
 
 	return err;
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 51f962d..e074bb6 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -1,4 +1,4 @@
-/* linux/drivers/mtd/maps/bast_flash.c
+/* linux/drivers/mtd/maps/bast-flash.c
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/drivers/mtd/maps/beech-mtd.c b/drivers/mtd/maps/beech-mtd.c
index a64b1a5..d76d598 100644
--- a/drivers/mtd/maps/beech-mtd.c
+++ b/drivers/mtd/maps/beech-mtd.c
@@ -72,7 +72,7 @@
 static int __init
 init_beech_mtd(void)
 {
-	int err = 0;
+	int err;
 
 	printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
 
@@ -89,7 +89,7 @@
 	beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
 
 	if (!beech_mtd) {
-		iounmap((void *) beech_mtd_map.virt);
+		iounmap(beech_mtd_map.virt);
 		return -ENXIO;
 	}
 
@@ -98,7 +98,7 @@
 	err = add_mtd_partitions(beech_mtd, beech_partitions, 2);
 	if (err) {
 		printk("%s: add_mtd_partitions failed\n", NAME);
-		iounmap((void *) beech_mtd_map.virt);
+		iounmap(beech_mtd_map.virt);
 	}
 
 	return err;
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
index d6bef10..df2c38e 100644
--- a/drivers/mtd/maps/cstm_mips_ixx.c
+++ b/drivers/mtd/maps/cstm_mips_ixx.c
@@ -175,8 +175,8 @@
 			printk(KERN_WARNING "Failed to ioremap\n");
 			for (j = 0; j < i; j++) {
 				if (cstm_mips_ixx_map[j].virt) {
-					iounmap((void *)cstm_mips_ixx_map[j].virt);
-					cstm_mips_ixx_map[j].virt = 0;
+					iounmap(cstm_mips_ixx_map[j].virt);
+					cstm_mips_ixx_map[j].virt = NULL;
 				}
 			}
 			return -EIO;
@@ -214,8 +214,8 @@
 		else {
 			for (i = 0; i < PHYSMAP_NUMBER; i++) {
 				if (cstm_mips_ixx_map[i].virt) {
-					iounmap((void *)cstm_mips_ixx_map[i].virt);
-					cstm_mips_ixx_map[i].virt = 0;
+					iounmap(cstm_mips_ixx_map[i].virt);
+					cstm_mips_ixx_map[i].virt = NULL;
 				}
 			}
 			return -ENXIO;
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
index a43c499..e0558b0 100644
--- a/drivers/mtd/maps/dmv182.c
+++ b/drivers/mtd/maps/dmv182.c
@@ -1,6 +1,6 @@
 
 /*
- * drivers/mtd/maps/svme182.c
+ * drivers/mtd/maps/dmv182.c
  *
  * Flash map driver for the Dy4 SVME182 board
  *
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 198e840..f9e8e5b 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -463,7 +463,7 @@
 
 #ifdef CONFIG_MTD_CFI_INTELEXT
 out_unmap1:
-	iounmap((void *) nettel_intel_map.virt);
+	iounmap(nettel_intel_map.virt);
 #endif
 
 out_unmap2:
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index 2257d2b..4d858b3 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -126,7 +126,7 @@
 
 int __init init_redwood_flash(void)
 {
-	int err = 0;
+	int err;
 
 	printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
 			WINDOW_SIZE, WINDOW_ADDR);
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 6baf5fe..178b53b 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -69,7 +69,7 @@
 		return 1;
 
 	default:
-		printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req));
+		printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
 		return 0;
 	}
 }
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index c99302e..1831340 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -21,7 +21,7 @@
 	  NAND flash device internally checks only bits transitioning
 	  from 1 to 0. There is a rare possibility that even though the
 	  device thinks the write was successful, a bit could have been
-	  flipped accidentaly due to device wear or something else.
+	  flipped accidentally due to device wear or something else.
 
 config MTD_NAND_ECC_SMC
 	bool "NAND ECC Smart Media byte order"
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 12017f3..1daf823 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -199,7 +199,7 @@
 	nand_release(ap7312_mtd);
 
 	/* Release io resource */
-	iounmap((void *)this->IO_ADDR_R);
+	iounmap(this->IO_ADDR_R);
 
 	/* Free the MTD device structure */
 	kfree(ep7312_mtd);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 975b2ef..baece61 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -415,7 +415,7 @@
  * Wait for the ready pin, after a command
  * The timeout is catched later.
  */
-static void nand_wait_ready(struct mtd_info *mtd)
+void nand_wait_ready(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
 	unsigned long timeo = jiffies + 2;
@@ -429,6 +429,7 @@
 	} while (time_before(jiffies, timeo));
 	led_trigger_event(nand_led_trigger, LED_OFF);
 }
+EXPORT_SYMBOL_GPL(nand_wait_ready);
 
 /**
  * nand_command - [DEFAULT] Send command to NAND device
@@ -766,8 +767,8 @@
 	int eccbytes = chip->ecc.bytes;
 	int eccsteps = chip->ecc.steps;
 	uint8_t *p = buf;
-	uint8_t *ecc_calc = chip->buffers.ecccalc;
-	uint8_t *ecc_code = chip->buffers.ecccode;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
 	int *eccpos = chip->ecc.layout->eccpos;
 
 	nand_read_page_raw(mtd, chip, buf);
@@ -808,8 +809,8 @@
 	int eccbytes = chip->ecc.bytes;
 	int eccsteps = chip->ecc.steps;
 	uint8_t *p = buf;
-	uint8_t *ecc_calc = chip->buffers.ecccalc;
-	uint8_t *ecc_code = chip->buffers.ecccode;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
 	int *eccpos = chip->ecc.layout->eccpos;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
@@ -970,7 +971,7 @@
 	page = realpage & chip->pagemask;
 
 	col = (int)(from & (mtd->writesize - 1));
-	chip->oob_poi = chip->buffers.oobrbuf;
+	chip->oob_poi = chip->buffers->oobrbuf;
 
 	buf = ops->datbuf;
 	oob = ops->oobbuf;
@@ -981,7 +982,7 @@
 
 		/* Is the current page in the buffer ? */
 		if (realpage != chip->pagebuf || oob) {
-			bufpoi = aligned ? buf : chip->buffers.databuf;
+			bufpoi = aligned ? buf : chip->buffers->databuf;
 
 			if (likely(sndcmd)) {
 				chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
@@ -989,14 +990,17 @@
 			}
 
 			/* Now read the page into the buffer */
-			ret = chip->ecc.read_page(mtd, chip, bufpoi);
+			if (unlikely(ops->mode == MTD_OOB_RAW))
+				ret = chip->ecc.read_page_raw(mtd, chip, bufpoi);
+			else
+				ret = chip->ecc.read_page(mtd, chip, bufpoi);
 			if (ret < 0)
 				break;
 
 			/* Transfer not aligned data */
 			if (!aligned) {
 				chip->pagebuf = realpage;
-				memcpy(buf, chip->buffers.databuf + col, bytes);
+				memcpy(buf, chip->buffers->databuf + col, bytes);
 			}
 
 			buf += bytes;
@@ -1023,7 +1027,7 @@
 					nand_wait_ready(mtd);
 			}
 		} else {
-			memcpy(buf, chip->buffers.databuf + col, bytes);
+			memcpy(buf, chip->buffers->databuf + col, bytes);
 			buf += bytes;
 		}
 
@@ -1266,7 +1270,7 @@
 	realpage = (int)(from >> chip->page_shift);
 	page = realpage & chip->pagemask;
 
-	chip->oob_poi = chip->buffers.oobrbuf;
+	chip->oob_poi = chip->buffers->oobrbuf;
 
 	while(1) {
 		sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
@@ -1322,8 +1326,6 @@
 static int nand_read_oob(struct mtd_info *mtd, loff_t from,
 			 struct mtd_oob_ops *ops)
 {
-	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
-			 uint8_t *buf) = NULL;
 	struct nand_chip *chip = mtd->priv;
 	int ret = -ENOTSUPP;
 
@@ -1341,12 +1343,7 @@
 	switch(ops->mode) {
 	case MTD_OOB_PLACE:
 	case MTD_OOB_AUTO:
-		break;
-
 	case MTD_OOB_RAW:
-		/* Replace the read_page algorithm temporary */
-		read_page = chip->ecc.read_page;
-		chip->ecc.read_page = nand_read_page_raw;
 		break;
 
 	default:
@@ -1358,8 +1355,6 @@
 	else
 		ret = nand_do_read_ops(mtd, from, ops);
 
-	if (unlikely(ops->mode == MTD_OOB_RAW))
-		chip->ecc.read_page = read_page;
  out:
 	nand_release_device(mtd);
 	return ret;
@@ -1391,7 +1386,7 @@
 	int i, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
 	int eccsteps = chip->ecc.steps;
-	uint8_t *ecc_calc = chip->buffers.ecccalc;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
 	int *eccpos = chip->ecc.layout->eccpos;
 
@@ -1417,7 +1412,7 @@
 	int i, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
 	int eccsteps = chip->ecc.steps;
-	uint8_t *ecc_calc = chip->buffers.ecccalc;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
 	int *eccpos = chip->ecc.layout->eccpos;
 
@@ -1478,7 +1473,7 @@
 }
 
 /**
- * nand_write_page - [INTERNAL] write one page
+ * nand_write_page - [REPLACEABLE] write one page
  * @mtd:	MTD device structure
  * @chip:	NAND chip descriptor
  * @buf:	the data to write
@@ -1486,13 +1481,16 @@
  * @cached:	cached programming
  */
 static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-			   const uint8_t *buf, int page, int cached)
+			   const uint8_t *buf, int page, int cached, int raw)
 {
 	int status;
 
 	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
-	chip->ecc.write_page(mtd, chip, buf);
+	if (unlikely(raw))
+		chip->ecc.write_page_raw(mtd, chip, buf);
+	else
+		chip->ecc.write_page(mtd, chip, buf);
 
 	/*
 	 * Cached progamming disabled for now, Not sure if its worth the
@@ -1627,7 +1625,7 @@
 	    (chip->pagebuf << chip->page_shift) < (to + ops->len))
 		chip->pagebuf = -1;
 
-	chip->oob_poi = chip->buffers.oobwbuf;
+	chip->oob_poi = chip->buffers->oobwbuf;
 
 	while(1) {
 		int cached = writelen > bytes && page != blockmask;
@@ -1635,7 +1633,8 @@
 		if (unlikely(oob))
 			oob = nand_fill_oob(chip, oob, ops);
 
-		ret = nand_write_page(mtd, chip, buf, page, cached);
+		ret = chip->write_page(mtd, chip, buf, page, cached,
+				       (ops->mode == MTD_OOB_RAW));
 		if (ret)
 			break;
 
@@ -1745,7 +1744,7 @@
 	if (page == chip->pagebuf)
 		chip->pagebuf = -1;
 
-	chip->oob_poi = chip->buffers.oobwbuf;
+	chip->oob_poi = chip->buffers->oobwbuf;
 	memset(chip->oob_poi, 0xff, mtd->oobsize);
 	nand_fill_oob(chip, ops->oobbuf, ops);
 	status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
@@ -1768,8 +1767,6 @@
 static int nand_write_oob(struct mtd_info *mtd, loff_t to,
 			  struct mtd_oob_ops *ops)
 {
-	void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-			  const uint8_t *buf) = NULL;
 	struct nand_chip *chip = mtd->priv;
 	int ret = -ENOTSUPP;
 
@@ -1787,12 +1784,7 @@
 	switch(ops->mode) {
 	case MTD_OOB_PLACE:
 	case MTD_OOB_AUTO:
-		break;
-
 	case MTD_OOB_RAW:
-		/* Replace the write_page algorithm temporary */
-		write_page = chip->ecc.write_page;
-		chip->ecc.write_page = nand_write_page_raw;
 		break;
 
 	default:
@@ -1804,8 +1796,6 @@
 	else
 		ret = nand_do_write_ops(mtd, to, ops);
 
-	if (unlikely(ops->mode == MTD_OOB_RAW))
-		chip->ecc.write_page = write_page;
  out:
 	nand_release_device(mtd);
 	return ret;
@@ -2288,40 +2278,22 @@
 	return type;
 }
 
-/* module_text_address() isn't exported, and it's mostly a pointless
-   test if this is a module _anyway_ -- they'd have to try _really_ hard
-   to call us from in-kernel code if the core NAND support is modular. */
-#ifdef MODULE
-#define caller_is_module() (1)
-#else
-#define caller_is_module() \
-	module_text_address((unsigned long)__builtin_return_address(0))
-#endif
-
 /**
- * nand_scan - [NAND Interface] Scan for the NAND device
- * @mtd:	MTD device structure
- * @maxchips:	Number of chips to scan for
+ * nand_scan_ident - [NAND Interface] Scan for the NAND device
+ * @mtd:	     MTD device structure
+ * @maxchips:	     Number of chips to scan for
  *
- * This fills out all the uninitialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values.
- * The mtd->owner field must be set to the module of the caller
+ * This is the first phase of the normal nand_scan() function. It
+ * reads the flash ID and sets up MTD fields accordingly.
  *
+ * The mtd->owner field must be set to the module of the caller.
  */
-int nand_scan(struct mtd_info *mtd, int maxchips)
+int nand_scan_ident(struct mtd_info *mtd, int maxchips)
 {
 	int i, busw, nand_maf_id;
 	struct nand_chip *chip = mtd->priv;
 	struct nand_flash_dev *type;
 
-	/* Many callers got this wrong, so check for it for a while... */
-	if (!mtd->owner && caller_is_module()) {
-		printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
-		BUG();
-	}
-
 	/* Get buswidth to select the correct functions */
 	busw = chip->options & NAND_BUSWIDTH_16;
 	/* Set the default functions */
@@ -2353,8 +2325,31 @@
 	chip->numchips = i;
 	mtd->size = i * chip->chipsize;
 
+	return 0;
+}
+
+
+/**
+ * nand_scan_tail - [NAND Interface] Scan for the NAND device
+ * @mtd:	    MTD device structure
+ * @maxchips:	    Number of chips to scan for
+ *
+ * This is the second phase of the normal nand_scan() function. It
+ * fills out all the uninitialized function pointers with the defaults
+ * and scans for a bad block table if appropriate.
+ */
+int nand_scan_tail(struct mtd_info *mtd)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	if (!(chip->options & NAND_OWN_BUFFERS))
+		chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
+	if (!chip->buffers)
+		return -ENOMEM;
+
 	/* Preset the internal oob write buffer */
-	memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize);
+	memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize);
 
 	/*
 	 * If no default placement scheme is given, select an appropriate one
@@ -2377,10 +2372,18 @@
 		}
 	}
 
+	if (!chip->write_page)
+		chip->write_page = nand_write_page;
+
 	/*
 	 * check ECC mode, default to software if 3byte/512byte hardware ECC is
 	 * selected and we have 256 byte pagesize fallback to software ECC
 	 */
+	if (!chip->ecc.read_page_raw)
+		chip->ecc.read_page_raw = nand_read_page_raw;
+	if (!chip->ecc.write_page_raw)
+		chip->ecc.write_page_raw = nand_write_page_raw;
+
 	switch (chip->ecc.mode) {
 	case NAND_ECC_HW:
 		/* Use standard hwecc read page function ? */
@@ -2438,6 +2441,7 @@
 		chip->ecc.size = mtd->writesize;
 		chip->ecc.bytes = 0;
 		break;
+
 	default:
 		printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
 		       chip->ecc.mode);
@@ -2503,6 +2507,44 @@
 	return chip->scan_bbt(mtd);
 }
 
+/* module_text_address() isn't exported, and it's mostly a pointless
+   test if this is a module _anyway_ -- they'd have to try _really_ hard
+   to call us from in-kernel code if the core NAND support is modular. */
+#ifdef MODULE
+#define caller_is_module() (1)
+#else
+#define caller_is_module() \
+	module_text_address((unsigned long)__builtin_return_address(0))
+#endif
+
+/**
+ * nand_scan - [NAND Interface] Scan for the NAND device
+ * @mtd:	MTD device structure
+ * @maxchips:	Number of chips to scan for
+ *
+ * This fills out all the uninitialized function pointers
+ * with the defaults.
+ * The flash ID is read and the mtd/chip structures are
+ * filled with the appropriate values.
+ * The mtd->owner field must be set to the module of the caller
+ *
+ */
+int nand_scan(struct mtd_info *mtd, int maxchips)
+{
+	int ret;
+
+	/* Many callers got this wrong, so check for it for a while... */
+	if (!mtd->owner && caller_is_module()) {
+		printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
+		BUG();
+	}
+
+	ret = nand_scan_ident(mtd, maxchips);
+	if (!ret)
+		ret = nand_scan_tail(mtd);
+	return ret;
+}
+
 /**
  * nand_release - [NAND Interface] Free resources held by the NAND device
  * @mtd:	MTD device structure
@@ -2520,9 +2562,13 @@
 
 	/* Free bad block table memory */
 	kfree(chip->bbt);
+	if (!(chip->options & NAND_OWN_BUFFERS))
+		kfree(chip->buffers);
 }
 
 EXPORT_SYMBOL_GPL(nand_scan);
+EXPORT_SYMBOL_GPL(nand_scan_ident);
+EXPORT_SYMBOL_GPL(nand_scan_tail);
 EXPORT_SYMBOL_GPL(nand_release);
 
 static int __init nand_base_init(void)
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index a612c4e..9402653 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -759,7 +759,7 @@
 	struct nand_chip *this = mtd->priv;
 
 	bd->options &= ~NAND_BBT_SCANEMPTY;
-	return create_bbt(mtd, this->buffers.databuf, bd, -1);
+	return create_bbt(mtd, this->buffers->databuf, bd, -1);
 }
 
 /**
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index dd5cea8..b5a5f8d 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -175,6 +175,8 @@
 	return res;
 }
 
+#ifdef CONFIG_NFTL_RW
+
 /*
  * Write data and oob to flash
  */
@@ -196,8 +198,6 @@
 	return res;
 }
 
-#ifdef CONFIG_NFTL_RW
-
 /* Actual NFTL access routines */
 /* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used
  *	when the give Virtual Unit Chain
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index 5930a03..373bddc 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -21,7 +21,7 @@
 	  OneNAND flash device internally checks only bits transitioning
 	  from 1 to 0. There is a rare possibility that even though the
 	  device thinks the write was successful, a bit could have been
-	  flipped accidentaly due to device wear or something else.
+	  flipped accidentally due to device wear or something else.
 
 config MTD_ONENAND_GENERIC
 	tristate "OneNAND Flash device via platform device driver"
@@ -43,10 +43,4 @@
 
 	  OTP block is fully-guaranteed to be a valid block.
 
-config MTD_ONENAND_SYNC_READ
-	bool "OneNAND Sync. Burst Read Support"
-	depends on ARCH_OMAP
-	help
-	  This enables support for Sync. Burst Read.
-
 endmenu
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 84ec40d..8ed68b2 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/mtd/onenand/onenand_base.c
  *
- *  Copyright (C) 2005 Samsung Electronics
+ *  Copyright (C) 2005-2006 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -199,6 +199,7 @@
 	case ONENAND_CMD_UNLOCK:
 	case ONENAND_CMD_LOCK:
 	case ONENAND_CMD_LOCK_TIGHT:
+	case ONENAND_CMD_UNLOCK_ALL:
 		block = -1;
 		page = -1;
 		break;
@@ -1211,11 +1212,11 @@
 	end = len >> this->erase_shift;
 
 	/* Continuous lock scheme */
-	if (this->options & ONENAND_CONT_LOCK) {
+	if (this->options & ONENAND_HAS_CONT_LOCK) {
 		/* Set start block address */
 		this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
 		/* Set end block address */
-		this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
+		this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
 		/* Write unlock command */
 		this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
 
@@ -1236,7 +1237,7 @@
 	}
 
 	/* Block lock scheme */
-	for (block = start; block < end; block++) {
+	for (block = start; block < start + end; block++) {
 		/* Set block address */
 		value = onenand_block_address(this, block);
 		this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
@@ -1265,6 +1266,79 @@
 	return 0;
 }
 
+/**
+ * onenand_check_lock_status - [OneNAND Interface] Check lock status
+ * @param this		onenand chip data structure
+ *
+ * Check lock status
+ */
+static void onenand_check_lock_status(struct onenand_chip *this)
+{
+	unsigned int value, block, status;
+	unsigned int end;
+
+	end = this->chipsize >> this->erase_shift;
+	for (block = 0; block < end; block++) {
+		/* Set block address */
+		value = onenand_block_address(this, block);
+		this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
+		/* Select DataRAM for DDP */
+		value = onenand_bufferram_address(this, block);
+		this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
+		/* Set start block address */
+		this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
+
+		/* Check lock status */
+		status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
+		if (!(status & ONENAND_WP_US))
+			printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
+	}
+}
+
+/**
+ * onenand_unlock_all - [OneNAND Interface] unlock all blocks
+ * @param mtd		MTD device structure
+ *
+ * Unlock all blocks
+ */
+static int onenand_unlock_all(struct mtd_info *mtd)
+{
+	struct onenand_chip *this = mtd->priv;
+
+	if (this->options & ONENAND_HAS_UNLOCK_ALL) {
+		/* Write unlock command */
+		this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
+
+		/* There's no return value */
+		this->wait(mtd, FL_UNLOCKING);
+
+		/* Sanity check */
+		while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+		    & ONENAND_CTRL_ONGO)
+			continue;
+
+		/* Workaround for all block unlock in DDP */
+		if (this->device_id & ONENAND_DEVICE_IS_DDP) {
+			loff_t ofs;
+			size_t len;
+
+			/* 1st block on another chip */
+			ofs = this->chipsize >> 1;
+			len = 1 << this->erase_shift;
+
+			onenand_unlock(mtd, ofs, len);
+		}
+
+		onenand_check_lock_status(this);
+
+		return 0;
+	}
+
+	mtd->unlock(mtd, 0x0, this->chipsize);
+
+	return 0;
+}
+
 #ifdef CONFIG_MTD_ONENAND_OTP
 
 /* Interal OTP operation */
@@ -1564,12 +1638,43 @@
 #endif	/* CONFIG_MTD_ONENAND_OTP */
 
 /**
+ * onenand_lock_scheme - Check and set OneNAND lock scheme
+ * @param mtd		MTD data structure
+ *
+ * Check and set OneNAND lock scheme
+ */
+static void onenand_lock_scheme(struct mtd_info *mtd)
+{
+	struct onenand_chip *this = mtd->priv;
+	unsigned int density, process;
+
+	/* Lock scheme depends on density and process */
+	density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+	process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
+
+	/* Lock scheme */
+	if (density >= ONENAND_DEVICE_DENSITY_1Gb) {
+		/* A-Die has all block unlock */
+		if (process) {
+			printk(KERN_DEBUG "Chip support all block unlock\n");
+			this->options |= ONENAND_HAS_UNLOCK_ALL;
+		}
+	} else {
+		/* Some OneNAND has continues lock scheme */
+		if (!process) {
+			printk(KERN_DEBUG "Lock scheme is Continues Lock\n");
+			this->options |= ONENAND_HAS_CONT_LOCK;
+		}
+	}
+}
+
+/**
  * onenand_print_device_info - Print device ID
  * @param device        device ID
  *
  * Print device ID
  */
-static void onenand_print_device_info(int device)
+static void onenand_print_device_info(int device, int version)
 {
         int vcc, demuxed, ddp, density;
 
@@ -1583,6 +1688,7 @@
                 (16 << density),
                 vcc ? "2.65/3.3" : "1.8",
                 device);
+	printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version);
 }
 
 static const struct onenand_manufacturers onenand_manuf_ids[] = {
@@ -1625,9 +1731,14 @@
 static int onenand_probe(struct mtd_info *mtd)
 {
 	struct onenand_chip *this = mtd->priv;
-	int bram_maf_id, bram_dev_id, maf_id, dev_id;
-	int version_id;
+	int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
 	int density;
+	int syscfg;
+
+	/* Save system configuration 1 */
+	syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
+	/* Clear Sync. Burst Read mode to read BootRAM */
+	this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
 
 	/* Send the command for reading device ID from BootRAM */
 	this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
@@ -1636,24 +1747,31 @@
 	bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
 	bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
 
+	/* Reset OneNAND to read default register values */
+	this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
+	/* Wait reset */
+	this->wait(mtd, FL_RESETING);
+
+	/* Restore system configuration 1 */
+	this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
+
 	/* Check manufacturer ID */
 	if (onenand_check_maf(bram_maf_id))
 		return -ENXIO;
 
-	/* Reset OneNAND to read default register values */
-	this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
-
 	/* Read manufacturer and device IDs from Register */
 	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
 	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+	ver_id= this->read_word(this->base + ONENAND_REG_VERSION_ID);
 
 	/* Check OneNAND device */
 	if (maf_id != bram_maf_id || dev_id != bram_dev_id)
 		return -ENXIO;
 
 	/* Flash device information */
-	onenand_print_device_info(dev_id);
+	onenand_print_device_info(dev_id, ver_id);
 	this->device_id = dev_id;
+	this->version_id = ver_id;
 
 	density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
 	this->chipsize = (16 << density) << 20;
@@ -1676,16 +1794,8 @@
 
 	mtd->size = this->chipsize;
 
-	/* Version ID */
-	version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
-	printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
-
-	/* Lock scheme */
-	if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
-	    !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
-		printk(KERN_INFO "Lock scheme is Continues Lock\n");
-		this->options |= ONENAND_CONT_LOCK;
-	}
+	/* Check OneNAND lock scheme */
+	onenand_lock_scheme(mtd);
 
 	return 0;
 }
@@ -1821,7 +1931,7 @@
 	mtd->owner = THIS_MODULE;
 
 	/* Unlock whole block */
-	mtd->unlock(mtd, 0x0, this->chipsize);
+	onenand_unlock_all(mtd);
 
 	return this->scan_bbt(mtd);
 }
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ff8a8c0..ab92cc7 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2115,7 +2115,7 @@
 	depends on PCI && EXPERIMENTAL
 	select CRC32
 	---help---
-	  This driver supports Gigabit Ethernet adapters based on the the
+	  This driver supports Gigabit Ethernet adapters based on the
 	  Marvell Yukon 2 chipset:
 	  Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
 	  88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 9953201..a67f5ef 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -165,7 +165,7 @@
  * look for EISA/PCI/MCA cards in addition to ISA cards).
  */
 static struct devprobe2 isa_probes[] __initdata = {
-#ifdef CONFIG_HP100 		/* ISA, EISA & PCI */
+#if defined(CONFIG_HP100) && defined(CONFIG_ISA)	/* ISA, EISA */
 	{hp100_probe, 0},
 #endif
 #ifdef CONFIG_3C515
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h
index 6a49ac7..483009f 100644
--- a/drivers/net/arm/am79c961a.h
+++ b/drivers/net/arm/am79c961a.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/net/am79c961.h
+ * linux/drivers/net/arm/am79c961a.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
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index dc5e38a..26073c3 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
+  Intel PRO/100 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
+  This program is distributed in the hope 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.
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
 
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
@@ -159,7 +159,7 @@
 
 #define DRV_NAME		"e100"
 #define DRV_EXT			"-NAPI"
-#define DRV_VERSION		"3.5.16-k2"DRV_EXT
+#define DRV_VERSION		"3.5.17-k2"DRV_EXT
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2006 Intel Corporation"
 #define PFX			DRV_NAME ": "
@@ -1657,13 +1657,14 @@
 
 	spin_lock(&nic->cb_lock);
 
-	DPRINTK(TX_DONE, DEBUG, "cb->status = 0x%04X\n",
-		nic->cb_to_clean->status);
-
 	/* Clean CBs marked complete */
 	for(cb = nic->cb_to_clean;
 	    cb->status & cpu_to_le16(cb_complete);
 	    cb = nic->cb_to_clean = cb->next) {
+		DPRINTK(TX_DONE, DEBUG, "cb[%d]->status = 0x%04X\n",
+		        (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
+		        cb->status);
+
 		if(likely(cb->skb != NULL)) {
 			nic->net_stats.tx_packets++;
 			nic->net_stats.tx_bytes += cb->skb->len;
@@ -2572,7 +2573,7 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	netdev->poll_controller = e100_netpoll;
 #endif
-	strcpy(netdev->name, pci_name(pdev));
+	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
 	nic = netdev_priv(netdev);
 	nic->netdev = netdev;
@@ -2714,68 +2715,56 @@
 	}
 }
 
-#ifdef CONFIG_PM
 static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
-	int retval;
 
-	if(netif_running(netdev))
+	if (netif_running(netdev))
 		e100_down(nic);
 	e100_hw_reset(nic);
 	netif_device_detach(netdev);
 
+#ifdef CONFIG_PM
 	pci_save_state(pdev);
-	retval = pci_enable_wake(pdev, pci_choose_state(pdev, state),
-	                         nic->flags & (wol_magic | e100_asf(nic)));
-	if (retval)
-		DPRINTK(PROBE,ERR, "Error enabling wake\n");
+	if (nic->flags & (wol_magic | e100_asf(nic)))
+#else
+	if (nic->flags & (wol_magic))
+#endif
+		pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+	else
+		/* disable PME */
+		pci_enable_wake(pdev, 0, 0);
+
 	pci_disable_device(pdev);
-	retval = pci_set_power_state(pdev, pci_choose_state(pdev, state));
-	if (retval)
-		DPRINTK(PROBE,ERR, "Error %d setting power state\n", retval);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
 }
 
+#ifdef CONFIG_PM
 static int e100_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
-	int retval;
 
-	retval = pci_set_power_state(pdev, PCI_D0);
-	if (retval)
-		DPRINTK(PROBE,ERR, "Error waking adapter\n");
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	/* ack any pending wake events, disable PME */
-	retval = pci_enable_wake(pdev, 0, 0);
-	if (retval)
-		DPRINTK(PROBE,ERR, "Error clearing wake events\n");
+	pci_enable_wake(pdev, 0, 0);
 
 	netif_device_attach(netdev);
-	if(netif_running(netdev))
+	if (netif_running(netdev))
 		e100_up(nic);
 
 	return 0;
 }
-#endif
+#endif /* CONFIG_PM */
 
 
 static void e100_shutdown(struct pci_dev *pdev)
 {
-	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct nic *nic = netdev_priv(netdev);
-	int retval;
-
-#ifdef CONFIG_PM
-	retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
-#else
-	retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
-#endif
-	if (retval)
-		DPRINTK(PROBE,ERR, "Error enabling wake\n");
+	e100_suspend(pdev, PMSG_SUSPEND);
 }
 
 /* ------------------ PCI Error Recovery infrastructure  -------------- */
@@ -2859,8 +2848,9 @@
 	.id_table =     e100_id_table,
 	.probe =        e100_probe,
 	.remove =       __devexit_p(e100_remove),
-#ifdef CONFIG_PM
+	/* Power Management hooks */
 	.suspend =      e100_suspend,
+#ifdef CONFIG_PM
 	.resume =       e100_resume,
 #endif
 	.shutdown =     e100_shutdown,
diff --git a/drivers/net/e1000/LICENSE b/drivers/net/e1000/LICENSE
deleted file mode 100644
index 5f297e5..0000000
--- a/drivers/net/e1000/LICENSE
+++ /dev/null
@@ -1,339 +0,0 @@
-
-"This software program is licensed subject to the GNU General Public License 
-(GPL). Version 2, June 1991, available at 
-<http://www.fsf.org/copyleft/gpl.html>"
-
-GNU General Public License 
-
-Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
-59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
-
-Everyone is permitted to copy and distribute verbatim copies of this license
-document, but changing it is not allowed.
-
-Preamble
-
-The licenses for most software are designed to take away your freedom to 
-share and change it. By contrast, the GNU General Public License is intended
-to guarantee your freedom to share and change free software--to make sure 
-the software is free for all its users. This General Public License applies 
-to most of the Free Software Foundation's software and to any other program 
-whose authors commit to using it. (Some other Free Software Foundation 
-software is covered by the GNU Library General Public License instead.) You 
-can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom 
-to distribute copies of free software (and charge for this service if you 
-wish), that you receive source code or can get it if you want it, that you 
-can change the software or use pieces of it in new free programs; and that 
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to 
-deny you these rights or to ask you to surrender the rights. These 
-restrictions translate to certain responsibilities for you if you distribute
-copies of the software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or 
-for a fee, you must give the recipients all the rights that you have. You 
-must make sure that they, too, receive or can get the source code. And you 
-must show them these terms so they know their rights.
- 
-We protect your rights with two steps: (1) copyright the software, and (2) 
-offer you this license which gives you legal permission to copy, distribute 
-and/or modify the software. 
-
-Also, for each author's protection and ours, we want to make certain that 
-everyone understands that there is no warranty for this free software. If 
-the software is modified by someone else and passed on, we want its 
-recipients to know that what they have is not the original, so that any 
-problems introduced by others will not reflect on the original authors' 
-reputations. 
-
-Finally, any free program is threatened constantly by software patents. We 
-wish to avoid the danger that redistributors of a free program will 
-individually obtain patent licenses, in effect making the program 
-proprietary. To prevent this, we have made it clear that any patent must be 
-licensed for everyone's free use or not licensed at all. 
-
-The precise terms and conditions for copying, distribution and modification 
-follow. 
-
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
-   placed by the copyright holder saying it may be distributed under the 
-   terms of this General Public License. The "Program", below, refers to any
-   such program or work, and a "work based on the Program" means either the 
-   Program or any derivative work under copyright law: that is to say, a 
-   work containing the Program or a portion of it, either verbatim or with 
-   modifications and/or translated into another language. (Hereinafter, 
-   translation is included without limitation in the term "modification".) 
-   Each licensee is addressed as "you". 
-
-   Activities other than copying, distribution and modification are not 
-   covered by this License; they are outside its scope. The act of running 
-   the Program is not restricted, and the output from the Program is covered 
-   only if its contents constitute a work based on the Program (independent 
-   of having been made by running the Program). Whether that is true depends
-   on what the Program does. 
-
-1. You may copy and distribute verbatim copies of the Program's source code 
-   as you receive it, in any medium, provided that you conspicuously and 
-   appropriately publish on each copy an appropriate copyright notice and 
-   disclaimer of warranty; keep intact all the notices that refer to this 
-   License and to the absence of any warranty; and give any other recipients 
-   of the Program a copy of this License along with the Program. 
-
-   You may charge a fee for the physical act of transferring a copy, and you 
-   may at your option offer warranty protection in exchange for a fee. 
-
-2. You may modify your copy or copies of the Program or any portion of it, 
-   thus forming a work based on the Program, and copy and distribute such 
-   modifications or work under the terms of Section 1 above, provided that 
-   you also meet all of these conditions: 
-
-   * a) You must cause the modified files to carry prominent notices stating 
-        that you changed the files and the date of any change. 
-
-   * b) You must cause any work that you distribute or publish, that in 
-        whole or in part contains or is derived from the Program or any part 
-        thereof, to be licensed as a whole at no charge to all third parties
-        under the terms of this License. 
-
-   * c) If the modified program normally reads commands interactively when 
-        run, you must cause it, when started running for such interactive 
-        use in the most ordinary way, to print or display an announcement 
-        including an appropriate copyright notice and a notice that there is
-        no warranty (or else, saying that you provide a warranty) and that 
-        users may redistribute the program under these conditions, and 
-        telling the user how to view a copy of this License. (Exception: if 
-        the Program itself is interactive but does not normally print such 
-        an announcement, your work based on the Program is not required to 
-        print an announcement.) 
-
-   These requirements apply to the modified work as a whole. If identifiable 
-   sections of that work are not derived from the Program, and can be 
-   reasonably considered independent and separate works in themselves, then 
-   this License, and its terms, do not apply to those sections when you 
-   distribute them as separate works. But when you distribute the same 
-   sections as part of a whole which is a work based on the Program, the 
-   distribution of the whole must be on the terms of this License, whose 
-   permissions for other licensees extend to the entire whole, and thus to 
-   each and every part regardless of who wrote it. 
-
-   Thus, it is not the intent of this section to claim rights or contest 
-   your rights to work written entirely by you; rather, the intent is to 
-   exercise the right to control the distribution of derivative or 
-   collective works based on the Program. 
-
-   In addition, mere aggregation of another work not based on the Program 
-   with the Program (or with a work based on the Program) on a volume of a 
-   storage or distribution medium does not bring the other work under the 
-   scope of this License. 
-
-3. You may copy and distribute the Program (or a work based on it, under 
-   Section 2) in object code or executable form under the terms of Sections 
-   1 and 2 above provided that you also do one of the following: 
-
-   * a) Accompany it with the complete corresponding machine-readable source 
-        code, which must be distributed under the terms of Sections 1 and 2 
-        above on a medium customarily used for software interchange; or, 
-
-   * b) Accompany it with a written offer, valid for at least three years, 
-        to give any third party, for a charge no more than your cost of 
-        physically performing source distribution, a complete machine-
-        readable copy of the corresponding source code, to be distributed 
-        under the terms of Sections 1 and 2 above on a medium customarily 
-        used for software interchange; or, 
-
-   * c) Accompany it with the information you received as to the offer to 
-        distribute corresponding source code. (This alternative is allowed 
-        only for noncommercial distribution and only if you received the 
-        program in object code or executable form with such an offer, in 
-        accord with Subsection b above.) 
-
-   The source code for a work means the preferred form of the work for 
-   making modifications to it. For an executable work, complete source code 
-   means all the source code for all modules it contains, plus any 
-   associated interface definition files, plus the scripts used to control 
-   compilation and installation of the executable. However, as a special 
-   exception, the source code distributed need not include anything that is 
-   normally distributed (in either source or binary form) with the major 
-   components (compiler, kernel, and so on) of the operating system on which
-   the executable runs, unless that component itself accompanies the 
-   executable. 
-
-   If distribution of executable or object code is made by offering access 
-   to copy from a designated place, then offering equivalent access to copy 
-   the source code from the same place counts as distribution of the source 
-   code, even though third parties are not compelled to copy the source 
-   along with the object code. 
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
-   expressly provided under this License. Any attempt otherwise to copy, 
-   modify, sublicense or distribute the Program is void, and will 
-   automatically terminate your rights under this License. However, parties 
-   who have received copies, or rights, from you under this License will not
-   have their licenses terminated so long as such parties remain in full 
-   compliance. 
-
-5. You are not required to accept this License, since you have not signed 
-   it. However, nothing else grants you permission to modify or distribute 
-   the Program or its derivative works. These actions are prohibited by law 
-   if you do not accept this License. Therefore, by modifying or 
-   distributing the Program (or any work based on the Program), you 
-   indicate your acceptance of this License to do so, and all its terms and
-   conditions for copying, distributing or modifying the Program or works 
-   based on it. 
-
-6. Each time you redistribute the Program (or any work based on the 
-   Program), the recipient automatically receives a license from the 
-   original licensor to copy, distribute or modify the Program subject to 
-   these terms and conditions. You may not impose any further restrictions 
-   on the recipients' exercise of the rights granted herein. You are not 
-   responsible for enforcing compliance by third parties to this License. 
-
-7. If, as a consequence of a court judgment or allegation of patent 
-   infringement or for any other reason (not limited to patent issues), 
-   conditions are imposed on you (whether by court order, agreement or 
-   otherwise) that contradict the conditions of this License, they do not 
-   excuse you from the conditions of this License. If you cannot distribute 
-   so as to satisfy simultaneously your obligations under this License and 
-   any other pertinent obligations, then as a consequence you may not 
-   distribute the Program at all. For example, if a patent license would 
-   not permit royalty-free redistribution of the Program by all those who 
-   receive copies directly or indirectly through you, then the only way you 
-   could satisfy both it and this License would be to refrain entirely from 
-   distribution of the Program. 
-
-   If any portion of this section is held invalid or unenforceable under any
-   particular circumstance, the balance of the section is intended to apply
-   and the section as a whole is intended to apply in other circumstances. 
-
-   It is not the purpose of this section to induce you to infringe any 
-   patents or other property right claims or to contest validity of any 
-   such claims; this section has the sole purpose of protecting the 
-   integrity of the free software distribution system, which is implemented 
-   by public license practices. Many people have made generous contributions
-   to the wide range of software distributed through that system in 
-   reliance on consistent application of that system; it is up to the 
-   author/donor to decide if he or she is willing to distribute software 
-   through any other system and a licensee cannot impose that choice. 
-
-   This section is intended to make thoroughly clear what is believed to be 
-   a consequence of the rest of this License. 
-
-8. If the distribution and/or use of the Program is restricted in certain 
-   countries either by patents or by copyrighted interfaces, the original 
-   copyright holder who places the Program under this License may add an 
-   explicit geographical distribution limitation excluding those countries, 
-   so that distribution is permitted only in or among countries not thus 
-   excluded. In such case, this License incorporates the limitation as if 
-   written in the body of this License. 
-
-9. The Free Software Foundation may publish revised and/or new versions of 
-   the General Public License from time to time. Such new versions will be 
-   similar in spirit to the present version, but may differ in detail to 
-   address new problems or concerns. 
-
-   Each version is given a distinguishing version number. If the Program 
-   specifies a version number of this License which applies to it and "any 
-   later version", you have the option of following the terms and 
-   conditions either of that version or of any later version published by 
-   the Free Software Foundation. If the Program does not specify a version 
-   number of this License, you may choose any version ever published by the 
-   Free Software Foundation. 
-
-10. If you wish to incorporate parts of the Program into other free programs
-    whose distribution conditions are different, write to the author to ask 
-    for permission. For software which is copyrighted by the Free Software 
-    Foundation, write to the Free Software Foundation; we sometimes make 
-    exceptions for this. Our decision will be guided by the two goals of 
-    preserving the free status of all derivatives of our free software and 
-    of promoting the sharing and reuse of software generally. 
-
-   NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 
-    FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 
-    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 
-    PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 
-    EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 
-    ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH 
-    YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 
-    NECESSARY SERVICING, REPAIR OR CORRECTION. 
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 
-    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 
-    REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR 
-    DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL 
-    DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM 
-    (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED 
-    INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF 
-    THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR 
-    OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
-
-END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest 
-possible use to the public, the best way to achieve this is to make it free 
-software which everyone can redistribute and change under these terms. 
-
-To do so, attach the following notices to the program. It is safest to 
-attach them to the start of each source file to most effectively convey the
-exclusion of warranty; and each file should have at least the "copyright" 
-line and a pointer to where the full notice is found. 
-
-one line to give the program's name and an idea of what it does.
-Copyright (C) yyyy  name of author
-
-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.
-
-Also add information on how to contact you by electronic and paper mail. 
-
-If the program is interactive, make it output a short notice like this when 
-it starts in an interactive mode: 
-
-Gnomovision version 69, Copyright (C) year name of author Gnomovision comes 
-with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free 
-software, and you are welcome to redistribute it under certain conditions; 
-type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate 
-parts of the General Public License. Of course, the commands you use may be 
-called something other than 'show w' and 'show c'; they could even be 
-mouse-clicks or menu items--whatever suits your program. 
-
-You should also get your employer (if you work as a programmer) or your 
-school, if any, to sign a "copyright disclaimer" for the program, if 
-necessary. Here is a sample; alter the names: 
-
-Yoyodyne, Inc., hereby disclaims all copyright interest in the program 
-'Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-signature of Ty Coon, 1 April 1989
-Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into 
-proprietary programs. If your program is a subroutine library, you may 
-consider it more useful to permit linking proprietary applications with the 
-library. If this is what you want to do, use the GNU Library General Public 
-License instead of this License.
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
index 5dea2b7..4a6ab15 100644
--- a/drivers/net/e1000/Makefile
+++ b/drivers/net/e1000/Makefile
@@ -1,25 +1,24 @@
 ################################################################################
 #
-# 
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-# 
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of the GNU General Public License as published by the Free 
-# Software Foundation; either version 2 of the License, or (at your option) 
-# 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 
+# Intel PRO/1000 Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
-# 
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-# 
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
 # Contact Information:
 # Linux NICS <linux.nics@intel.com>
 # e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 98afa9c..7ecce43 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -346,29 +345,9 @@
 };
 
 enum e1000_state_t {
-	__E1000_DRIVER_TESTING,
+	__E1000_TESTING,
 	__E1000_RESETTING,
+	__E1000_DOWN
 };
 
-/*  e1000_main.c  */
-extern char e1000_driver_name[];
-extern char e1000_driver_version[];
-int e1000_up(struct e1000_adapter *adapter);
-void e1000_down(struct e1000_adapter *adapter);
-void e1000_reset(struct e1000_adapter *adapter);
-void e1000_reinit_locked(struct e1000_adapter *adapter);
-int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
-int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_update_stats(struct e1000_adapter *adapter);
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-
-/*  e1000_ethtool.c  */
-void e1000_set_ethtool_ops(struct net_device *netdev);
-
-/*  e1000_param.c  */
-void e1000_check_options(struct e1000_adapter *adapter);
-
-
 #endif /* _E1000_H_ */
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index e39aa1f..778ede3 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -33,6 +32,21 @@
 
 #include <asm/uaccess.h>
 
+extern char e1000_driver_name[];
+extern char e1000_driver_version[];
+
+extern int e1000_up(struct e1000_adapter *adapter);
+extern void e1000_down(struct e1000_adapter *adapter);
+extern void e1000_reinit_locked(struct e1000_adapter *adapter);
+extern void e1000_reset(struct e1000_adapter *adapter);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_update_stats(struct e1000_adapter *adapter);
+
+
 struct e1000_stats {
 	char stat_string[ETH_GSTRING_LEN];
 	int sizeof_stat;
@@ -42,26 +56,30 @@
 #define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
 		      offsetof(struct e1000_adapter, m)
 static const struct e1000_stats e1000_gstrings_stats[] = {
-	{ "rx_packets", E1000_STAT(net_stats.rx_packets) },
-	{ "tx_packets", E1000_STAT(net_stats.tx_packets) },
-	{ "rx_bytes", E1000_STAT(net_stats.rx_bytes) },
-	{ "tx_bytes", E1000_STAT(net_stats.tx_bytes) },
-	{ "rx_errors", E1000_STAT(net_stats.rx_errors) },
-	{ "tx_errors", E1000_STAT(net_stats.tx_errors) },
+	{ "rx_packets", E1000_STAT(stats.gprc) },
+	{ "tx_packets", E1000_STAT(stats.gptc) },
+	{ "rx_bytes", E1000_STAT(stats.gorcl) },
+	{ "tx_bytes", E1000_STAT(stats.gotcl) },
+	{ "rx_broadcast", E1000_STAT(stats.bprc) },
+	{ "tx_broadcast", E1000_STAT(stats.bptc) },
+	{ "rx_multicast", E1000_STAT(stats.mprc) },
+	{ "tx_multicast", E1000_STAT(stats.mptc) },
+	{ "rx_errors", E1000_STAT(stats.rxerrc) },
+	{ "tx_errors", E1000_STAT(stats.txerrc) },
 	{ "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
-	{ "multicast", E1000_STAT(net_stats.multicast) },
-	{ "collisions", E1000_STAT(net_stats.collisions) },
-	{ "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) },
+	{ "multicast", E1000_STAT(stats.mprc) },
+	{ "collisions", E1000_STAT(stats.colc) },
+	{ "rx_length_errors", E1000_STAT(stats.rlerrc) },
 	{ "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
-	{ "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
+	{ "rx_crc_errors", E1000_STAT(stats.crcerrs) },
 	{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
 	{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
-	{ "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
-	{ "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
-	{ "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
+	{ "rx_missed_errors", E1000_STAT(stats.mpc) },
+	{ "tx_aborted_errors", E1000_STAT(stats.ecol) },
+	{ "tx_carrier_errors", E1000_STAT(stats.tncrs) },
 	{ "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
 	{ "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
-	{ "tx_window_errors", E1000_STAT(net_stats.tx_window_errors) },
+	{ "tx_window_errors", E1000_STAT(stats.latecol) },
 	{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
 	{ "tx_deferred_ok", E1000_STAT(stats.dc) },
 	{ "tx_single_coll_ok", E1000_STAT(stats.scc) },
@@ -193,13 +211,9 @@
 				     ADVERTISED_FIBRE |
 				     ADVERTISED_Autoneg;
 		else
-			hw->autoneg_advertised = ADVERTISED_10baseT_Half |
-						  ADVERTISED_10baseT_Full |
-						  ADVERTISED_100baseT_Half |
-						  ADVERTISED_100baseT_Full |
-						  ADVERTISED_1000baseT_Full|
-						  ADVERTISED_Autoneg |
-						  ADVERTISED_TP;
+			hw->autoneg_advertised = ecmd->advertising |
+			                         ADVERTISED_TP |
+			                         ADVERTISED_Autoneg;
 		ecmd->advertising = hw->autoneg_advertised;
 	} else
 		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
@@ -229,11 +243,11 @@
 	pause->autoneg =
 		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
 
-	if (hw->fc == e1000_fc_rx_pause)
+	if (hw->fc == E1000_FC_RX_PAUSE)
 		pause->rx_pause = 1;
-	else if (hw->fc == e1000_fc_tx_pause)
+	else if (hw->fc == E1000_FC_TX_PAUSE)
 		pause->tx_pause = 1;
-	else if (hw->fc == e1000_fc_full) {
+	else if (hw->fc == E1000_FC_FULL) {
 		pause->rx_pause = 1;
 		pause->tx_pause = 1;
 	}
@@ -253,13 +267,13 @@
 		msleep(1);
 
 	if (pause->rx_pause && pause->tx_pause)
-		hw->fc = e1000_fc_full;
+		hw->fc = E1000_FC_FULL;
 	else if (pause->rx_pause && !pause->tx_pause)
-		hw->fc = e1000_fc_rx_pause;
+		hw->fc = E1000_FC_RX_PAUSE;
 	else if (!pause->rx_pause && pause->tx_pause)
-		hw->fc = e1000_fc_tx_pause;
+		hw->fc = E1000_FC_TX_PAUSE;
 	else if (!pause->rx_pause && !pause->tx_pause)
-		hw->fc = e1000_fc_none;
+		hw->fc = E1000_FC_NONE;
 
 	hw->original_fc = hw->fc;
 
@@ -632,8 +646,8 @@
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	e1000_mac_type mac_type = adapter->hw.mac_type;
-	struct e1000_tx_ring *txdr, *tx_old, *tx_new;
-	struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+	struct e1000_tx_ring *txdr, *tx_old;
+	struct e1000_rx_ring *rxdr, *rx_old;
 	int i, err, tx_ring_size, rx_ring_size;
 
 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -651,23 +665,17 @@
 	tx_old = adapter->tx_ring;
 	rx_old = adapter->rx_ring;
 
-	adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
-	if (!adapter->tx_ring) {
-		err = -ENOMEM;
-		goto err_setup_rx;
-	}
-	memset(adapter->tx_ring, 0, tx_ring_size);
+	err = -ENOMEM;
+	txdr = kzalloc(tx_ring_size, GFP_KERNEL);
+	if (!txdr)
+		goto err_alloc_tx;
 
-	adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
-	if (!adapter->rx_ring) {
-		kfree(adapter->tx_ring);
-		err = -ENOMEM;
-		goto err_setup_rx;
-	}
-	memset(adapter->rx_ring, 0, rx_ring_size);
+	rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
+	if (!rxdr)
+		goto err_alloc_rx;
 
-	txdr = adapter->tx_ring;
-	rxdr = adapter->rx_ring;
+	adapter->tx_ring = txdr;
+	adapter->rx_ring = rxdr;
 
 	rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
 	rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
@@ -694,16 +702,14 @@
 		/* save the new, restore the old in order to free it,
 		 * then restore the new back again */
 
-		rx_new = adapter->rx_ring;
-		tx_new = adapter->tx_ring;
 		adapter->rx_ring = rx_old;
 		adapter->tx_ring = tx_old;
 		e1000_free_all_rx_resources(adapter);
 		e1000_free_all_tx_resources(adapter);
 		kfree(tx_old);
 		kfree(rx_old);
-		adapter->rx_ring = rx_new;
-		adapter->tx_ring = tx_new;
+		adapter->rx_ring = rxdr;
+		adapter->tx_ring = txdr;
 		if ((err = e1000_up(adapter)))
 			goto err_setup;
 	}
@@ -715,6 +721,10 @@
 err_setup_rx:
 	adapter->rx_ring = rx_old;
 	adapter->tx_ring = tx_old;
+	kfree(rxdr);
+err_alloc_rx:
+	kfree(txdr);
+err_alloc_tx:
 	e1000_up(adapter);
 err_setup:
 	clear_bit(__E1000_RESETTING, &adapter->flags);
@@ -1610,7 +1620,7 @@
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	boolean_t if_running = netif_running(netdev);
 
-	set_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+	set_bit(__E1000_TESTING, &adapter->flags);
 	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
 		/* Offline tests */
 
@@ -1655,7 +1665,7 @@
 		adapter->hw.autoneg = autoneg;
 
 		e1000_reset(adapter);
-		clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+		clear_bit(__E1000_TESTING, &adapter->flags);
 		if (if_running)
 			dev_open(netdev);
 	} else {
@@ -1670,7 +1680,7 @@
 		data[2] = 0;
 		data[3] = 0;
 
-		clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+		clear_bit(__E1000_TESTING, &adapter->flags);
 	}
 	msleep_interruptible(4 * 1000);
 }
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 10b8c8c..65077f3 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -34,6 +33,63 @@
 
 #include "e1000_hw.h"
 
+static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
+static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data);
+static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
+static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
+static void e1000_release_software_semaphore(struct e1000_hw *hw);
+
+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, e1000_rev_polarity *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_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank);
+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_get_software_flag(struct e1000_hw *hw);
+static int32_t e1000_ich8_cycle_init(struct e1000_hw *hw);
+static int32_t e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout);
+static int32_t e1000_id_led_init(struct e1000_hw *hw);
+static int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size);
+static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static void e1000_initialize_hardware_bits(struct e1000_hw *hw);
+static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
+static int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
+static int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer, uint16_t length, uint16_t offset, uint8_t *sum);
+static int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, struct e1000_host_mng_command_header* hdr);
+static int32_t e1000_mng_write_commit(struct e1000_hw *hw);
+static int32_t e1000_phy_ife_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+static int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t *data);
+static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data);
+static int32_t e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t *data);
+static int32_t e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t data);
+static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static void e1000_release_software_flag(struct e1000_hw *hw);
+static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop);
+static void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
+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);
 static int32_t e1000_set_phy_type(struct e1000_hw *hw);
 static void e1000_phy_init_script(struct e1000_hw *hw);
 static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
@@ -70,69 +126,10 @@
 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)
 static int32_t e1000_configure_kmrn_for_10_100(struct e1000_hw *hw,
                                                uint16_t duplex);
 static int32_t e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
 
-static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw,
-					   uint32_t segment);
-static int32_t e1000_get_software_flag(struct e1000_hw *hw);
-static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
-static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
-static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
-				      uint16_t words, uint16_t *data);
-static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index,
-				    uint8_t* data);
-static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index,
-				    uint16_t *data);
-static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
-				   uint16_t *data);
-static void e1000_release_software_flag(struct e1000_hw *hw);
-static void e1000_release_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw,
-					 uint32_t no_snoop);
-static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw,
-					    uint32_t index, uint8_t byte);
-static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
-				       uint16_t words, uint16_t *data);
-static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index,
-				     uint8_t data);
-static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
-				    uint16_t data);
-
 /* IGP cable length table */
 static const
 uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
@@ -156,13 +153,12 @@
       83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
       104, 109, 114, 118, 121, 124};
 
-
 /******************************************************************************
  * Set the phy type member in the hw struct.
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_set_phy_type(struct e1000_hw *hw)
 {
     DEBUGFUNC("e1000_set_phy_type");
@@ -208,7 +204,6 @@
     return E1000_SUCCESS;
 }
 
-
 /******************************************************************************
  * IGP phy init script - initializes the GbE PHY
  *
@@ -667,19 +662,12 @@
                 E1000_WRITE_FLUSH(hw);
             }
             /* fall through */
-        case e1000_82571:
-        case e1000_82572:
-        case e1000_ich8lan:
-        case e1000_80003es2lan:
+        default:
+            /* Auto read done will delay 5ms or poll based on mac type */
             ret_val = e1000_get_auto_rd_done(hw);
             if (ret_val)
-                /* We don't want to continue accessing MAC registers. */
                 return ret_val;
             break;
-        default:
-            /* Wait for EEPROM reload (it happens automatically) */
-            msleep(5);
-            break;
     }
 
     /* Disable HW ARPs on ASF enabled adapters */
@@ -722,6 +710,123 @@
 }
 
 /******************************************************************************
+ *
+ * Initialize a number of hardware-dependent bits
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * This function contains hardware limitation workarounds for PCI-E adapters
+ *
+ *****************************************************************************/
+static void
+e1000_initialize_hardware_bits(struct e1000_hw *hw)
+{
+    if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) {
+        /* Settings common to all PCI-express silicon */
+        uint32_t reg_ctrl, reg_ctrl_ext;
+        uint32_t reg_tarc0, reg_tarc1;
+        uint32_t reg_tctl;
+        uint32_t reg_txdctl, reg_txdctl1;
+
+        /* link autonegotiation/sync workarounds */
+        reg_tarc0 = E1000_READ_REG(hw, TARC0);
+        reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
+
+        /* Enable not-done TX descriptor counting */
+        reg_txdctl = E1000_READ_REG(hw, TXDCTL);
+        reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
+        E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
+        reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
+        reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
+        E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);
+
+        switch (hw->mac_type) {
+            case e1000_82571:
+            case e1000_82572:
+                /* Clear PHY TX compatible mode bits */
+                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                reg_tarc1 &= ~((1 << 30)|(1 << 29));
+
+                /* link autonegotiation/sync workarounds */
+                reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23));
+
+                /* TX ring control fixes */
+                reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));
+
+                /* Multiple read bit is reversed polarity */
+                reg_tctl = E1000_READ_REG(hw, TCTL);
+                if (reg_tctl & E1000_TCTL_MULR)
+                    reg_tarc1 &= ~(1 << 28);
+                else
+                    reg_tarc1 |= (1 << 28);
+
+                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                break;
+            case e1000_82573:
+                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                reg_ctrl_ext &= ~(1 << 23);
+                reg_ctrl_ext |= (1 << 22);
+
+                /* TX byte count fix */
+                reg_ctrl = E1000_READ_REG(hw, CTRL);
+                reg_ctrl &= ~(1 << 29);
+
+                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+                E1000_WRITE_REG(hw, CTRL, reg_ctrl);
+                break;
+            case e1000_80003es2lan:
+                /* improve small packet performace for fiber/serdes */
+                if ((hw->media_type == e1000_media_type_fiber) ||
+                    (hw->media_type == e1000_media_type_internal_serdes)) {
+                    reg_tarc0 &= ~(1 << 20);
+                }
+
+                /* Multiple read bit is reversed polarity */
+                reg_tctl = E1000_READ_REG(hw, TCTL);
+                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                if (reg_tctl & E1000_TCTL_MULR)
+                    reg_tarc1 &= ~(1 << 28);
+                else
+                    reg_tarc1 |= (1 << 28);
+
+                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                break;
+            case e1000_ich8lan:
+                /* Reduce concurrent DMA requests to 3 from 4 */
+                if ((hw->revision_id < 3) ||
+                    ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+                     (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
+                    reg_tarc0 |= ((1 << 29)|(1 << 28));
+
+                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                reg_ctrl_ext |= (1 << 22);
+                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+
+                /* workaround TX hang with TSO=on */
+                reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));
+
+                /* Multiple read bit is reversed polarity */
+                reg_tctl = E1000_READ_REG(hw, TCTL);
+                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                if (reg_tctl & E1000_TCTL_MULR)
+                    reg_tarc1 &= ~(1 << 28);
+                else
+                    reg_tarc1 |= (1 << 28);
+
+                /* workaround TX hang with TSO=on */
+                reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));
+
+                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                break;
+            default:
+                break;
+        }
+
+        E1000_WRITE_REG(hw, TARC0, reg_tarc0);
+    }
+}
+
+/******************************************************************************
  * Performs basic configuration of the adapter.
  *
  * hw - Struct containing variables accessed by shared code
@@ -749,14 +854,13 @@
     DEBUGFUNC("e1000_init_hw");
 
     /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */
-    if (hw->mac_type == e1000_ich8lan) {
-        reg_data = E1000_READ_REG(hw, TARC0);
-        reg_data |= 0x30000000;
-        E1000_WRITE_REG(hw, TARC0, reg_data);
-
-        reg_data = E1000_READ_REG(hw, STATUS);
-        reg_data &= ~0x80000000;
-        E1000_WRITE_REG(hw, STATUS, reg_data);
+    if ((hw->mac_type == e1000_ich8lan) &&
+        ((hw->revision_id < 3) ||
+         ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+          (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
+            reg_data = E1000_READ_REG(hw, STATUS);
+            reg_data &= ~0x80000000;
+            E1000_WRITE_REG(hw, STATUS, reg_data);
     }
 
     /* Initialize Identification LED */
@@ -769,6 +873,9 @@
     /* Set the media type and TBI compatibility */
     e1000_set_media_type(hw);
 
+    /* Must be called after e1000_set_media_type because media_type is used */
+    e1000_initialize_hardware_bits(hw);
+
     /* Disabling VLAN filtering. */
     DEBUGOUT("Initializing the IEEE VLAN\n");
     /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
@@ -860,17 +967,6 @@
     if (hw->mac_type > e1000_82544) {
         ctrl = E1000_READ_REG(hw, TXDCTL);
         ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-        switch (hw->mac_type) {
-        default:
-            break;
-        case e1000_82571:
-        case e1000_82572:
-        case e1000_82573:
-        case e1000_ich8lan:
-        case e1000_80003es2lan:
-            ctrl |= E1000_TXDCTL_COUNT_DESC;
-            break;
-        }
         E1000_WRITE_REG(hw, TXDCTL, ctrl);
     }
 
@@ -908,8 +1004,6 @@
     case e1000_ich8lan:
         ctrl = E1000_READ_REG(hw, TXDCTL1);
         ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-        if (hw->mac_type >= e1000_82571)
-            ctrl |= E1000_TXDCTL_COUNT_DESC;
         E1000_WRITE_REG(hw, TXDCTL1, ctrl);
         break;
     }
@@ -1018,11 +1112,11 @@
      * control setting, then the variable hw->fc will
      * be initialized based on a value in the EEPROM.
      */
-    if (hw->fc == e1000_fc_default) {
+    if (hw->fc == E1000_FC_DEFAULT) {
         switch (hw->mac_type) {
         case e1000_ich8lan:
         case e1000_82573:
-            hw->fc = e1000_fc_full;
+            hw->fc = E1000_FC_FULL;
             break;
         default:
             ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
@@ -1032,12 +1126,12 @@
                 return -E1000_ERR_EEPROM;
             }
             if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-                hw->fc = e1000_fc_none;
+                hw->fc = E1000_FC_NONE;
             else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
                     EEPROM_WORD0F_ASM_DIR)
-                hw->fc = e1000_fc_tx_pause;
+                hw->fc = E1000_FC_TX_PAUSE;
             else
-                hw->fc = e1000_fc_full;
+                hw->fc = E1000_FC_FULL;
             break;
         }
     }
@@ -1047,10 +1141,10 @@
      * hub or switch with different Flow Control capabilities.
      */
     if (hw->mac_type == e1000_82542_rev2_0)
-        hw->fc &= (~e1000_fc_tx_pause);
+        hw->fc &= (~E1000_FC_TX_PAUSE);
 
     if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
-        hw->fc &= (~e1000_fc_rx_pause);
+        hw->fc &= (~E1000_FC_RX_PAUSE);
 
     hw->original_fc = hw->fc;
 
@@ -1102,7 +1196,7 @@
      * ability to transmit pause frames in not enabled, then these
      * registers will be set to 0.
      */
-    if (!(hw->fc & e1000_fc_tx_pause)) {
+    if (!(hw->fc & E1000_FC_TX_PAUSE)) {
         E1000_WRITE_REG(hw, FCRTL, 0);
         E1000_WRITE_REG(hw, FCRTH, 0);
     } else {
@@ -1149,11 +1243,11 @@
     if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
         E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
 
-    /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+    /* On adapters with a MAC newer than 82544, SWDP 1 will be
      * set when the optics detect a signal. On older adapters, it will be
      * cleared when there is a signal.  This applies to fiber media only.
-     * If we're on serdes media, adjust the output amplitude to value set in
-     * the EEPROM.
+     * If we're on serdes media, adjust the output amplitude to value
+     * set in the EEPROM.
      */
     ctrl = E1000_READ_REG(hw, CTRL);
     if (hw->media_type == e1000_media_type_fiber)
@@ -1189,11 +1283,11 @@
      *      3:  Both Rx and TX flow control (symmetric) are enabled.
      */
     switch (hw->fc) {
-    case e1000_fc_none:
+    case E1000_FC_NONE:
         /* Flow control is completely disabled by a software over-ride. */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
         break;
-    case e1000_fc_rx_pause:
+    case E1000_FC_RX_PAUSE:
         /* RX Flow control is enabled and TX Flow control is disabled by a
          * software over-ride. Since there really isn't a way to advertise
          * that we are capable of RX Pause ONLY, we will advertise that we
@@ -1202,13 +1296,13 @@
          */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
         break;
-    case e1000_fc_tx_pause:
+    case E1000_FC_TX_PAUSE:
         /* TX Flow control is enabled, and RX Flow control is disabled, by a
          * software over-ride.
          */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
         break;
-    case e1000_fc_full:
+    case E1000_FC_FULL:
         /* Flow control (both RX and TX) is enabled by a software over-ride. */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
         break;
@@ -2124,13 +2218,13 @@
      *          in the EEPROM is used.
      */
     switch (hw->fc) {
-    case e1000_fc_none: /* 0 */
+    case E1000_FC_NONE: /* 0 */
         /* Flow control (RX & TX) is completely disabled by a
          * software over-ride.
          */
         mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
         break;
-    case e1000_fc_rx_pause: /* 1 */
+    case E1000_FC_RX_PAUSE: /* 1 */
         /* RX Flow control is enabled, and TX Flow control is
          * disabled, by a software over-ride.
          */
@@ -2142,14 +2236,14 @@
          */
         mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
         break;
-    case e1000_fc_tx_pause: /* 2 */
+    case E1000_FC_TX_PAUSE: /* 2 */
         /* TX Flow control is enabled, and RX Flow control is
          * disabled, by a software over-ride.
          */
         mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
         mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
         break;
-    case e1000_fc_full: /* 3 */
+    case E1000_FC_FULL: /* 3 */
         /* Flow control (both RX and TX) is enabled by a software
          * over-ride.
          */
@@ -2193,7 +2287,7 @@
     DEBUGFUNC("e1000_phy_force_speed_duplex");
 
     /* Turn off Flow control if we are forcing speed and duplex. */
-    hw->fc = e1000_fc_none;
+    hw->fc = E1000_FC_NONE;
 
     DEBUGOUT1("hw->fc = %d\n", hw->fc);
 
@@ -2547,18 +2641,18 @@
      */
 
     switch (hw->fc) {
-    case e1000_fc_none:
+    case E1000_FC_NONE:
         ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
         break;
-    case e1000_fc_rx_pause:
+    case E1000_FC_RX_PAUSE:
         ctrl &= (~E1000_CTRL_TFCE);
         ctrl |= E1000_CTRL_RFCE;
         break;
-    case e1000_fc_tx_pause:
+    case E1000_FC_TX_PAUSE:
         ctrl &= (~E1000_CTRL_RFCE);
         ctrl |= E1000_CTRL_TFCE;
         break;
-    case e1000_fc_full:
+    case E1000_FC_FULL:
         ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
         break;
     default:
@@ -2657,14 +2751,14 @@
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
              *-------|---------|-------|---------|--------------------
-             *   0   |    0    |  DC   |   DC    | e1000_fc_none
-             *   0   |    1    |   0   |   DC    | e1000_fc_none
-             *   0   |    1    |   1   |    0    | e1000_fc_none
-             *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-             *   1   |    0    |   0   |   DC    | e1000_fc_none
-             *   1   |   DC    |   1   |   DC    | e1000_fc_full
-             *   1   |    1    |   0   |    0    | e1000_fc_none
-             *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+             *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
+             *   0   |    1    |   0   |   DC    | E1000_FC_NONE
+             *   0   |    1    |   1   |    0    | E1000_FC_NONE
+             *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
+             *   1   |    0    |   0   |   DC    | E1000_FC_NONE
+             *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
+             *   1   |    1    |   0   |    0    | E1000_FC_NONE
+             *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
              *
              */
             /* Are both PAUSE bits set to 1?  If so, this implies
@@ -2676,7 +2770,7 @@
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
              *-------|---------|-------|---------|--------------------
-             *   1   |   DC    |   1   |   DC    | e1000_fc_full
+             *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
              *
              */
             if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
@@ -2687,11 +2781,11 @@
                  * ONLY. Hence, we must now check to see if we need to
                  * turn OFF  the TRANSMISSION of PAUSE frames.
                  */
-                if (hw->original_fc == e1000_fc_full) {
-                    hw->fc = e1000_fc_full;
+                if (hw->original_fc == E1000_FC_FULL) {
+                    hw->fc = E1000_FC_FULL;
                     DEBUGOUT("Flow Control = FULL.\n");
                 } else {
-                    hw->fc = e1000_fc_rx_pause;
+                    hw->fc = E1000_FC_RX_PAUSE;
                     DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
                 }
             }
@@ -2700,14 +2794,14 @@
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
              *-------|---------|-------|---------|--------------------
-             *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+             *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
              *
              */
             else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
                      (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                      (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                      (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                hw->fc = e1000_fc_tx_pause;
+                hw->fc = E1000_FC_TX_PAUSE;
                 DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
             }
             /* For transmitting PAUSE frames ONLY.
@@ -2715,14 +2809,14 @@
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
              *-------|---------|-------|---------|--------------------
-             *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+             *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
              *
              */
             else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
                      (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                      !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                      (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                hw->fc = e1000_fc_rx_pause;
+                hw->fc = E1000_FC_RX_PAUSE;
                 DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
             }
             /* Per the IEEE spec, at this point flow control should be
@@ -2745,13 +2839,13 @@
              * be asked to delay transmission of packets than asking
              * our link partner to pause transmission of frames.
              */
-            else if ((hw->original_fc == e1000_fc_none ||
-                      hw->original_fc == e1000_fc_tx_pause) ||
+            else if ((hw->original_fc == E1000_FC_NONE ||
+                      hw->original_fc == E1000_FC_TX_PAUSE) ||
                       hw->fc_strict_ieee) {
-                hw->fc = e1000_fc_none;
+                hw->fc = E1000_FC_NONE;
                 DEBUGOUT("Flow Control = NONE.\n");
             } else {
-                hw->fc = e1000_fc_rx_pause;
+                hw->fc = E1000_FC_RX_PAUSE;
                 DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
             }
 
@@ -2766,7 +2860,7 @@
             }
 
             if (duplex == HALF_DUPLEX)
-                hw->fc = e1000_fc_none;
+                hw->fc = E1000_FC_NONE;
 
             /* Now we call a subroutine to actually force the MAC
              * controller to use the correct flow control settings.
@@ -3417,9 +3511,8 @@
     return ret_val;
 }
 
-int32_t
-e1000_read_phy_reg_ex(struct e1000_hw *hw,
-                      uint32_t reg_addr,
+static int32_t
+e1000_read_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
                       uint16_t *phy_data)
 {
     uint32_t i;
@@ -3499,8 +3592,7 @@
 * data - data to write to the PHY
 ******************************************************************************/
 int32_t
-e1000_write_phy_reg(struct e1000_hw *hw,
-                    uint32_t reg_addr,
+e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
                     uint16_t phy_data)
 {
     uint32_t ret_val;
@@ -3557,10 +3649,9 @@
     return ret_val;
 }
 
-int32_t
-e1000_write_phy_reg_ex(struct e1000_hw *hw,
-                    uint32_t reg_addr,
-                    uint16_t phy_data)
+static int32_t
+e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
+                       uint16_t phy_data)
 {
     uint32_t i;
     uint32_t mdic = 0;
@@ -3711,7 +3802,7 @@
             swfw = E1000_SWFW_PHY0_SM;
         }
         if (e1000_swfw_sync_acquire(hw, swfw)) {
-            e1000_release_software_semaphore(hw);
+            DEBUGOUT("Unable to acquire swfw sync\n");
             return -E1000_ERR_SWFW_SYNC;
         }
         /* Read the device control register and assert the E1000_CTRL_PHY_RST
@@ -3734,6 +3825,7 @@
 
         if (hw->mac_type >= e1000_82571)
             mdelay(10);
+
         e1000_swfw_sync_release(hw, swfw);
     } else {
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
@@ -3792,15 +3884,14 @@
     if (ret_val)
         return E1000_SUCCESS;
 
-    switch (hw->mac_type) {
-    case e1000_82541_rev_2:
-    case e1000_82571:
-    case e1000_82572:
-    case e1000_ich8lan:
+    switch (hw->phy_type) {
+    case e1000_phy_igp:
+    case e1000_phy_igp_2:
+    case e1000_phy_igp_3:
+    case e1000_phy_ife:
         ret_val = e1000_phy_hw_reset(hw);
         if (ret_val)
             return ret_val;
-
         break;
     default:
         ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
@@ -3936,7 +4027,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;
@@ -3945,6 +4036,9 @@
 
     DEBUGFUNC("e1000_detect_gig_phy");
 
+    if (hw->phy_id != 0)
+        return E1000_SUCCESS;
+
     /* The 82571 firmware may still be configuring the PHY.  In this
      * case, we cannot access the PHY until the configuration is done.  So
      * we explicitly set the PHY values. */
@@ -4061,7 +4155,8 @@
                        struct e1000_phy_info *phy_info)
 {
     int32_t ret_val;
-    uint16_t phy_data, polarity, min_length, max_length, average;
+    uint16_t phy_data, min_length, max_length, average;
+    e1000_rev_polarity polarity;
 
     DEBUGFUNC("e1000_phy_igp_get_info");
 
@@ -4086,8 +4181,8 @@
     if (ret_val)
         return ret_val;
 
-    phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
-                          IGP01E1000_PSSR_MDIX_SHIFT;
+    phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & IGP01E1000_PSSR_MDIX) >>
+                          IGP01E1000_PSSR_MDIX_SHIFT);
 
     if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
        IGP01E1000_PSSR_SPEED_1000MBPS) {
@@ -4096,10 +4191,12 @@
         if (ret_val)
             return ret_val;
 
-        phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
-                             SR_1000T_LOCAL_RX_STATUS_SHIFT;
-        phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
-                              SR_1000T_REMOTE_RX_STATUS_SHIFT;
+        phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                             SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+                             e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+        phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+                              SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+                              e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
 
         /* Get cable length */
         ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
@@ -4135,7 +4232,8 @@
                        struct e1000_phy_info *phy_info)
 {
     int32_t ret_val;
-    uint16_t phy_data, polarity;
+    uint16_t phy_data;
+    e1000_rev_polarity polarity;
 
     DEBUGFUNC("e1000_phy_ife_get_info");
 
@@ -4146,8 +4244,9 @@
     if (ret_val)
         return ret_val;
     phy_info->polarity_correction =
-                        (phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
-                        IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT;
+                        ((phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
+                        IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT) ?
+                        e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
 
     if (phy_info->polarity_correction == e1000_polarity_reversal_enabled) {
         ret_val = e1000_check_polarity(hw, &polarity);
@@ -4155,8 +4254,9 @@
             return ret_val;
     } else {
         /* Polarity is forced. */
-        polarity = (phy_data & IFE_PSC_FORCE_POLARITY) >>
-                       IFE_PSC_FORCE_POLARITY_SHIFT;
+        polarity = ((phy_data & IFE_PSC_FORCE_POLARITY) >>
+                     IFE_PSC_FORCE_POLARITY_SHIFT) ?
+                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
     }
     phy_info->cable_polarity = polarity;
 
@@ -4164,9 +4264,9 @@
     if (ret_val)
         return ret_val;
 
-    phy_info->mdix_mode =
-                     (phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
-                     IFE_PMC_MDIX_MODE_SHIFT;
+    phy_info->mdix_mode = (e1000_auto_x_mode)
+                     ((phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
+                     IFE_PMC_MDIX_MODE_SHIFT);
 
     return E1000_SUCCESS;
 }
@@ -4182,7 +4282,8 @@
                        struct e1000_phy_info *phy_info)
 {
     int32_t ret_val;
-    uint16_t phy_data, polarity;
+    uint16_t phy_data;
+    e1000_rev_polarity polarity;
 
     DEBUGFUNC("e1000_phy_m88_get_info");
 
@@ -4195,11 +4296,14 @@
         return ret_val;
 
     phy_info->extended_10bt_distance =
-        (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
-        M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
+        ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+        M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
+        e1000_10bt_ext_dist_enable_lower : e1000_10bt_ext_dist_enable_normal;
+
     phy_info->polarity_correction =
-        (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
-        M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+        ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
+        M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
+        e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
 
     /* Check polarity status */
     ret_val = e1000_check_polarity(hw, &polarity);
@@ -4211,15 +4315,15 @@
     if (ret_val)
         return ret_val;
 
-    phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
-                          M88E1000_PSSR_MDIX_SHIFT;
+    phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & M88E1000_PSSR_MDIX) >>
+                          M88E1000_PSSR_MDIX_SHIFT);
 
     if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
         /* Cable Length Estimation and Local/Remote Receiver Information
          * are only valid at 1000 Mbps.
          */
         if (hw->phy_type != e1000_phy_gg82563) {
-            phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+            phy_info->cable_length = (e1000_cable_length)((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
                                       M88E1000_PSSR_CABLE_LENGTH_SHIFT);
         } else {
             ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
@@ -4227,18 +4331,20 @@
             if (ret_val)
                 return ret_val;
 
-            phy_info->cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;
+            phy_info->cable_length = (e1000_cable_length)(phy_data & GG82563_DSPD_CABLE_LENGTH);
         }
 
         ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
         if (ret_val)
             return ret_val;
 
-        phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
-                             SR_1000T_LOCAL_RX_STATUS_SHIFT;
+        phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                             SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+                             e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+        phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+                              SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+                              e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
 
-        phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
-                              SR_1000T_REMOTE_RX_STATUS_SHIFT;
     }
 
     return E1000_SUCCESS;
@@ -4441,7 +4547,7 @@
         eeprom->use_eewr = FALSE;
         break;
     case e1000_ich8lan:
-    {
+        {
         int32_t  i = 0;
         uint32_t flash_size = E1000_READ_ICH8_REG(hw, ICH8_FLASH_GFPREG);
 
@@ -4468,7 +4574,7 @@
         hw->flash_bank_size /= 2 * sizeof(uint16_t);
 
         break;
-    }
+        }
     default:
         break;
     }
@@ -4800,7 +4906,7 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_spi_eeprom_ready(struct e1000_hw *hw)
 {
     uint16_t retry_count = 0;
@@ -4854,44 +4960,43 @@
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     uint32_t i = 0;
-    int32_t ret_val;
 
     DEBUGFUNC("e1000_read_eeprom");
 
+    /* If eeprom is not yet detected, do so now */
+    if (eeprom->word_size == 0)
+        e1000_init_eeprom_params(hw);
+
     /* A check for invalid values:  offset too large, too many words, and not
      * enough words.
      */
     if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
        (words == 0)) {
-        DEBUGOUT("\"words\" parameter out of bounds\n");
+        DEBUGOUT2("\"words\" parameter out of bounds. Words = %d, size = %d\n", offset, eeprom->word_size);
         return -E1000_ERR_EEPROM;
     }
 
-    /* FLASH reads without acquiring the semaphore are safe */
+    /* EEPROM's that don't use EERD to read require us to bit-bang the SPI
+     * directly. In this case, we need to acquire the EEPROM so that
+     * FW or other port software does not interrupt.
+     */
     if (e1000_is_onboard_nvm_eeprom(hw) == TRUE &&
         hw->eeprom.use_eerd == FALSE) {
-        switch (hw->mac_type) {
-        case e1000_80003es2lan:
-            break;
-        default:
-            /* Prepare the EEPROM for reading  */
-            if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
-                return -E1000_ERR_EEPROM;
-            break;
-        }
+        /* Prepare the EEPROM for bit-bang reading */
+        if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+            return -E1000_ERR_EEPROM;
     }
 
-    if (eeprom->use_eerd == TRUE) {
-        ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
-        if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
-            (hw->mac_type != e1000_82573))
-            e1000_release_eeprom(hw);
-        return ret_val;
-    }
+    /* Eerd register EEPROM access requires no eeprom aquire/release */
+    if (eeprom->use_eerd == TRUE)
+        return e1000_read_eeprom_eerd(hw, offset, words, data);
 
+    /* ICH EEPROM access is done via the ICH flash controller */
     if (eeprom->type == e1000_eeprom_ich8)
         return e1000_read_eeprom_ich8(hw, offset, words, data);
 
+    /* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
+     * acquired the EEPROM at this point, so any returns should relase it */
     if (eeprom->type == e1000_eeprom_spi) {
         uint16_t word_in;
         uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
@@ -5206,6 +5311,10 @@
 
     DEBUGFUNC("e1000_write_eeprom");
 
+    /* If eeprom is not yet detected, do so now */
+    if (eeprom->word_size == 0)
+        e1000_init_eeprom_params(hw);
+
     /* A check for invalid values:  offset too large, too many words, and not
      * enough words.
      */
@@ -5248,7 +5357,7 @@
  * data - pointer to array of 8 bit words to be written to the EEPROM
  *
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_write_eeprom_spi(struct e1000_hw *hw,
                        uint16_t offset,
                        uint16_t words,
@@ -5314,7 +5423,7 @@
  * data - pointer to array of 16 bit words to be written to the EEPROM
  *
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_write_eeprom_microwire(struct e1000_hw *hw,
                              uint16_t offset,
                              uint16_t words,
@@ -5411,10 +5520,8 @@
     int32_t error = E1000_SUCCESS;
     uint32_t old_bank_offset = 0;
     uint32_t new_bank_offset = 0;
-    uint32_t sector_retries = 0;
     uint8_t low_byte = 0;
     uint8_t high_byte = 0;
-    uint8_t temp_byte = 0;
     boolean_t sector_write_failed = FALSE;
 
     if (hw->mac_type == e1000_82573) {
@@ -5467,41 +5574,46 @@
             e1000_erase_ich8_4k_segment(hw, 0);
         }
 
-        do {
-            sector_write_failed = FALSE;
-            /* Loop for every byte in the shadow RAM,
-             * which is in units of words. */
-            for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
-                /* Determine whether to write the value stored
-                 * in the other NVM bank or a modified value stored
-                 * in the shadow RAM */
-                if (hw->eeprom_shadow_ram[i].modified == TRUE) {
-                    low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
-                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
-                                         &temp_byte);
-                    udelay(100);
-                    error = e1000_verify_write_ich8_byte(hw,
-                                                 (i << 1) + new_bank_offset,
-                                                 low_byte);
-                    if (error != E1000_SUCCESS)
-                        sector_write_failed = TRUE;
+        sector_write_failed = FALSE;
+        /* Loop for every byte in the shadow RAM,
+         * which is in units of words. */
+        for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+            /* Determine whether to write the value stored
+             * in the other NVM bank or a modified value stored
+             * in the shadow RAM */
+            if (hw->eeprom_shadow_ram[i].modified == TRUE) {
+                low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
+                udelay(100);
+                error = e1000_verify_write_ich8_byte(hw,
+                            (i << 1) + new_bank_offset, low_byte);
+
+                if (error != E1000_SUCCESS)
+                    sector_write_failed = TRUE;
+                else {
                     high_byte =
                         (uint8_t)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
-                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
-                                         &temp_byte);
                     udelay(100);
-                } else {
-                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
-                                         &low_byte);
-                    udelay(100);
-                    error = e1000_verify_write_ich8_byte(hw,
-                                 (i << 1) + new_bank_offset, low_byte);
-                    if (error != E1000_SUCCESS)
-                        sector_write_failed = TRUE;
+                }
+            } else {
+                e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
+                                     &low_byte);
+                udelay(100);
+                error = e1000_verify_write_ich8_byte(hw,
+                            (i << 1) + new_bank_offset, low_byte);
+
+                if (error != E1000_SUCCESS)
+                    sector_write_failed = TRUE;
+                else {
                     e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
                                          &high_byte);
+                    udelay(100);
                 }
+            }
 
+            /* If the write of the low byte was successful, go ahread and
+             * write the high byte while checking to make sure that if it
+             * is the signature byte, then it is handled properly */
+            if (sector_write_failed == FALSE) {
                 /* If the word is 0x13, then make sure the signature bits
                  * (15:14) are 11b until the commit has completed.
                  * This will allow us to write 10b which indicates the
@@ -5512,45 +5624,45 @@
                     high_byte = E1000_ICH8_NVM_SIG_MASK | high_byte;
 
                 error = e1000_verify_write_ich8_byte(hw,
-                             (i << 1) + new_bank_offset + 1, high_byte);
+                            (i << 1) + new_bank_offset + 1, high_byte);
                 if (error != E1000_SUCCESS)
                     sector_write_failed = TRUE;
 
-                if (sector_write_failed == FALSE) {
-                    /* Clear the now not used entry in the cache */
-                    hw->eeprom_shadow_ram[i].modified = FALSE;
-                    hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
-                }
+            } else {
+                /* If the write failed then break from the loop and
+                 * return an error */
+                break;
+            }
+        }
+
+        /* Don't bother writing the segment valid bits if sector
+         * programming failed. */
+        if (sector_write_failed == FALSE) {
+            /* Finally validate the new segment by setting bit 15:14
+             * to 10b in word 0x13 , this can be done without an
+             * erase as well since these bits are 11 to start with
+             * and we need to change bit 14 to 0b */
+            e1000_read_ich8_byte(hw,
+                                 E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
+                                 &high_byte);
+            high_byte &= 0xBF;
+            error = e1000_verify_write_ich8_byte(hw,
+                        E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset, high_byte);
+            /* And invalidate the previously valid segment by setting
+             * its signature word (0x13) high_byte to 0b. This can be
+             * done without an erase because flash erase sets all bits
+             * to 1's. We can write 1's to 0's without an erase */
+            if (error == E1000_SUCCESS) {
+                error = e1000_verify_write_ich8_byte(hw,
+                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset, 0);
             }
 
-            /* Don't bother writing the segment valid bits if sector
-             * programming failed. */
-            if (sector_write_failed == FALSE) {
-                /* Finally validate the new segment by setting bit 15:14
-                 * to 10b in word 0x13 , this can be done without an
-                 * erase as well since these bits are 11 to start with
-                 * and we need to change bit 14 to 0b */
-                e1000_read_ich8_byte(hw,
-                    E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
-                    &high_byte);
-                high_byte &= 0xBF;
-                error = e1000_verify_write_ich8_byte(hw,
-                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
-                            high_byte);
-                if (error != E1000_SUCCESS)
-                    sector_write_failed = TRUE;
-
-                /* And invalidate the previously valid segment by setting
-                 * its signature word (0x13) high_byte to 0b. This can be
-                 * done without an erase because flash erase sets all bits
-                 * to 1's. We can write 1's to 0's without an erase */
-                error = e1000_verify_write_ich8_byte(hw,
-                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset,
-                            0);
-                if (error != E1000_SUCCESS)
-                    sector_write_failed = TRUE;
+            /* Clear the now not used entry in the cache */
+            for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+                hw->eeprom_shadow_ram[i].modified = FALSE;
+                hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
             }
-        } while (++sector_retries < 10 && sector_write_failed == TRUE);
+        }
     }
 
     return error;
@@ -5640,99 +5752,6 @@
 }
 
 /******************************************************************************
- * Updates the MAC's list of multicast addresses.
- *
- * hw - Struct containing variables accessed by shared code
- * mc_addr_list - the list of new multicast addresses
- * mc_addr_count - number of addresses
- * pad - number of bytes between addresses in the list
- * rar_used_count - offset where to start adding mc addresses into the RAR's
- *
- * The given list replaces any existing list. Clears the last 15 receive
- * address registers and the multicast table. Uses receive address registers
- * for the first 15 multicast addresses, and hashes the rest into the
- * multicast table.
- *****************************************************************************/
-#if 0
-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 hash_value;
-    uint32_t i;
-    uint32_t num_rar_entry;
-    uint32_t num_mta_entry;
-
-    DEBUGFUNC("e1000_mc_addr_list_update");
-
-    /* Set the new number of MC addresses that we are being requested to use. */
-    hw->num_mc_addrs = mc_addr_count;
-
-    /* Clear RAR[1-15] */
-    DEBUGOUT(" Clearing RAR[1-15]\n");
-    num_rar_entry = E1000_RAR_ENTRIES;
-    if (hw->mac_type == e1000_ich8lan)
-        num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN;
-    /* Reserve a spot for the Locally Administered Address to work around
-     * an 82571 issue in which a reset on one port will reload the MAC on
-     * the other port. */
-    if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
-        num_rar_entry -= 1;
-
-    for (i = rar_used_count; i < num_rar_entry; i++) {
-        E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
-        E1000_WRITE_FLUSH(hw);
-        E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
-        E1000_WRITE_FLUSH(hw);
-    }
-
-    /* Clear the MTA */
-    DEBUGOUT(" Clearing MTA\n");
-    num_mta_entry = E1000_NUM_MTA_REGISTERS;
-    if (hw->mac_type == e1000_ich8lan)
-        num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN;
-    for (i = 0; i < num_mta_entry; i++) {
-        E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-        E1000_WRITE_FLUSH(hw);
-    }
-
-    /* Add the new addresses */
-    for (i = 0; i < mc_addr_count; i++) {
-        DEBUGOUT(" Adding the multicast addresses:\n");
-        DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 1],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 2],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 3],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 4],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 5]);
-
-        hash_value = e1000_hash_mc_addr(hw,
-                                        mc_addr_list +
-                                        (i * (ETH_LENGTH_OF_ADDRESS + pad)));
-
-        DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
-
-        /* Place this multicast address in the RAR if there is room, *
-         * else put it in the MTA
-         */
-        if (rar_used_count < num_rar_entry) {
-            e1000_rar_set(hw,
-                          mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
-                          rar_used_count);
-            rar_used_count++;
-        } else {
-            e1000_mta_set(hw, hash_value);
-        }
-    }
-    DEBUGOUT("MC Update Complete\n");
-}
-#endif  /*  0  */
-
-/******************************************************************************
  * Hashes an address to determine its location in the multicast table
  *
  * hw - Struct containing variables accessed by shared code
@@ -6290,7 +6309,7 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 e1000_clear_hw_cntrs(struct e1000_hw *hw)
 {
     volatile uint32_t temp;
@@ -6539,6 +6558,8 @@
 void
 e1000_get_bus_info(struct e1000_hw *hw)
 {
+    int32_t ret_val;
+    uint16_t pci_ex_link_status;
     uint32_t status;
 
     switch (hw->mac_type) {
@@ -6548,18 +6569,25 @@
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
         break;
+    case e1000_82571:
     case e1000_82572:
     case e1000_82573:
-        hw->bus_type = e1000_bus_type_pci_express;
-        hw->bus_speed = e1000_bus_speed_2500;
-        hw->bus_width = e1000_bus_width_pciex_1;
-        break;
-    case e1000_82571:
-    case e1000_ich8lan:
     case e1000_80003es2lan:
         hw->bus_type = e1000_bus_type_pci_express;
         hw->bus_speed = e1000_bus_speed_2500;
-        hw->bus_width = e1000_bus_width_pciex_4;
+        ret_val = e1000_read_pcie_cap_reg(hw,
+                                      PCI_EX_LINK_STATUS,
+                                      &pci_ex_link_status);
+        if (ret_val)
+            hw->bus_width = e1000_bus_width_unknown;
+        else
+            hw->bus_width = (pci_ex_link_status & PCI_EX_LINK_WIDTH_MASK) >>
+                          PCI_EX_LINK_WIDTH_SHIFT;
+        break;
+    case e1000_ich8lan:
+        hw->bus_type = e1000_bus_type_pci_express;
+        hw->bus_speed = e1000_bus_speed_2500;
+        hw->bus_width = e1000_bus_width_pciex_1;
         break;
     default:
         status = E1000_READ_REG(hw, STATUS);
@@ -6593,25 +6621,6 @@
         break;
     }
 }
-/******************************************************************************
- * 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.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset to read from
- *****************************************************************************/
-#if 0
-uint32_t
-e1000_read_reg_io(struct e1000_hw *hw,
-                  uint32_t offset)
-{
-    unsigned long io_addr = hw->io_base;
-    unsigned long io_data = hw->io_base + 4;
-
-    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
@@ -6633,7 +6642,6 @@
     e1000_io_write(hw, io_data, value);
 }
 
-
 /******************************************************************************
  * Estimates the cable length.
  *
@@ -6842,7 +6850,7 @@
  *****************************************************************************/
 static int32_t
 e1000_check_polarity(struct e1000_hw *hw,
-                     uint16_t *polarity)
+                     e1000_rev_polarity *polarity)
 {
     int32_t ret_val;
     uint16_t phy_data;
@@ -6856,8 +6864,10 @@
                                      &phy_data);
         if (ret_val)
             return ret_val;
-        *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
-                    M88E1000_PSSR_REV_POLARITY_SHIFT;
+        *polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
+                     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
+                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
+
     } else if (hw->phy_type == e1000_phy_igp ||
               hw->phy_type == e1000_phy_igp_3 ||
               hw->phy_type == e1000_phy_igp_2) {
@@ -6879,19 +6889,22 @@
                 return ret_val;
 
             /* Check the polarity bits */
-            *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
+            *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
+                         e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
         } else {
             /* For 10 Mbps, read the polarity bit in the status register. (for
              * 100 Mbps this bit is always 0) */
-            *polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
+            *polarity = (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
+                         e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
         }
     } else if (hw->phy_type == e1000_phy_ife) {
         ret_val = e1000_read_phy_reg(hw, IFE_PHY_EXTENDED_STATUS_CONTROL,
                                      &phy_data);
         if (ret_val)
             return ret_val;
-        *polarity = (phy_data & IFE_PESC_POLARITY_REVERSED) >>
-                           IFE_PESC_POLARITY_REVERSED_SHIFT;
+        *polarity = ((phy_data & IFE_PESC_POLARITY_REVERSED) >>
+                     IFE_PESC_POLARITY_REVERSED_SHIFT) ?
+                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
     }
     return E1000_SUCCESS;
 }
@@ -7259,7 +7272,7 @@
         } else if (hw->smart_speed == e1000_smart_speed_off) {
             ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          &phy_data);
-	    if (ret_val)
+            if (ret_val)
                 return ret_val;
 
             phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7369,7 +7382,7 @@
         } else if (hw->smart_speed == e1000_smart_speed_off) {
             ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          &phy_data);
-	    if (ret_val)
+            if (ret_val)
                 return ret_val;
 
             phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7475,7 +7488,7 @@
  *
  * returns: - E1000_SUCCESS .
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
 {
     uint8_t i;
@@ -7686,7 +7699,7 @@
  ****************************************************************************/
 int32_t
 e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
-			  uint16_t length)
+                          uint16_t length)
 {
     int32_t ret_val;
     struct e1000_host_mng_command_header hdr;
@@ -7716,7 +7729,7 @@
  *
  * returns  - checksum of buffer contents.
  ****************************************************************************/
-uint8_t
+static uint8_t
 e1000_calculate_mng_checksum(char *buffer, uint32_t length)
 {
     uint8_t sum = 0;
@@ -7914,32 +7927,6 @@
     E1000_WRITE_REG(hw, CTRL, ctrl);
 }
 
-/***************************************************************************
- *
- * Enables PCI-Express master access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - none.
- *
- ***************************************************************************/
-#if 0
-void
-e1000_enable_pciex_master(struct e1000_hw *hw)
-{
-    uint32_t ctrl;
-
-    DEBUGFUNC("e1000_enable_pciex_master");
-
-    if (hw->bus_type != e1000_bus_type_pci_express)
-        return;
-
-    ctrl = E1000_READ_REG(hw, CTRL);
-    ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
-    E1000_WRITE_REG(hw, CTRL, ctrl);
-}
-#endif  /*  0  */
-
 /*******************************************************************************
  *
  * Disables PCI-Express master access and verifies there are no pending requests
@@ -8063,7 +8050,6 @@
                 msleep(1);
             timeout--;
         }
-
         if (!timeout) {
             DEBUGOUT("MNG configuration cycle has not completed.\n");
             return -E1000_ERR_RESET;
@@ -8172,8 +8158,9 @@
 
     DEBUGFUNC("e1000_get_software_semaphore");
 
-    if (hw->mac_type != e1000_80003es2lan)
+    if (hw->mac_type != e1000_80003es2lan) {
         return E1000_SUCCESS;
+    }
 
     while (timeout) {
         swsm = E1000_READ_REG(hw, SWSM);
@@ -8206,8 +8193,9 @@
 
     DEBUGFUNC("e1000_release_software_semaphore");
 
-    if (hw->mac_type != e1000_80003es2lan)
+    if (hw->mac_type != e1000_80003es2lan) {
         return;
+    }
 
     swsm = E1000_READ_REG(hw, SWSM);
     /* Release the SW semaphores.*/
@@ -8241,7 +8229,7 @@
     if (hw->mac_type > e1000_82547_rev_2)
         manc = E1000_READ_REG(hw, MANC);
     return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
-	    E1000_BLK_PHY_RESET : E1000_SUCCESS;
+        E1000_BLK_PHY_RESET : E1000_SUCCESS;
 }
 
 static uint8_t
@@ -8377,66 +8365,6 @@
     return;
 }
 
-/***************************************************************************
- *
- * Disable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw)
-{
-    uint16_t phy_data;
-    int32_t ret_val = E1000_SUCCESS;
-
-    DEBUGFUNC("e1000_ife_disable_dynamic_power_down");
-
-    if (hw->phy_type == e1000_phy_ife) {
-        ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
-        if (ret_val)
-            return ret_val;
-
-        phy_data |=  IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
-        ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
-    }
-
-    return ret_val;
-}
-#endif  /*  0  */
-
-/***************************************************************************
- *
- * Enable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw)
-{
-    uint16_t phy_data;
-    int32_t ret_val = E1000_SUCCESS;
-
-    DEBUGFUNC("e1000_ife_enable_dynamic_power_down");
-
-    if (hw->phy_type == e1000_phy_ife) {
-        ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
-        if (ret_val)
-            return ret_val;
-
-        phy_data &=  ~IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
-        ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
-    }
-
-    return ret_val;
-}
-#endif  /*  0  */
-
 /******************************************************************************
  * Reads a 16 bit word or words from the EEPROM using the ICH8's flash access
  * register.
@@ -8832,20 +8760,22 @@
 e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte)
 {
     int32_t error = E1000_SUCCESS;
-    int32_t program_retries;
-    uint8_t temp_byte;
+    int32_t program_retries = 0;
 
-    e1000_write_ich8_byte(hw, index, byte);
-    udelay(100);
+    DEBUGOUT2("Byte := %2.2X Offset := %d\n", byte, index);
 
-    for (program_retries = 0; program_retries < 100; program_retries++) {
-        e1000_read_ich8_byte(hw, index, &temp_byte);
-        if (temp_byte == byte)
-            break;
-        udelay(10);
-        e1000_write_ich8_byte(hw, index, byte);
-        udelay(100);
+    error = e1000_write_ich8_byte(hw, index, byte);
+
+    if (error != E1000_SUCCESS) {
+        for (program_retries = 0; program_retries < 100; program_retries++) {
+            DEBUGOUT2("Retrying \t Byte := %2.2X Offset := %d\n", byte, index);
+            error = e1000_write_ich8_byte(hw, index, byte);
+            udelay(100);
+            if (error == E1000_SUCCESS)
+                break;
+        }
     }
+
     if (program_retries == 100)
         error = E1000_ERR_EEPROM;
 
@@ -8886,39 +8816,27 @@
 }
 
 /******************************************************************************
- * Writes a word to the NVM using the ICH8 flash access registers.
+ * Erases the bank specified. Each bank may be a 4, 8 or 64k block. Banks are 0
+ * based.
  *
  * hw - pointer to e1000_hw structure
- * index - The starting byte index of the word to read.
- * data - The word to write to the NVM.
+ * bank - 0 for first bank, 1 for second bank
+ *
+ * Note that this function may actually erase as much as 8 or 64 KBytes.  The
+ * amount of NVM used in each bank is a *minimum* of 4 KBytes, but in fact the
+ * bank size may be 4, 8 or 64 KBytes
  *****************************************************************************/
-#if 0
 int32_t
-e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data)
-{
-    int32_t status = E1000_SUCCESS;
-    status = e1000_write_ich8_data(hw, index, 2, data);
-    return status;
-}
-#endif  /*  0  */
-
-/******************************************************************************
- * Erases the bank specified. Each bank is a 4k block. Segments are 0 based.
- * segment N is 4096 * N + flash_reg_addr.
- *
- * hw - pointer to e1000_hw structure
- * segment - 0 for first segment, 1 for second segment, etc.
- *****************************************************************************/
-static int32_t
-e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
+e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank)
 {
     union ich8_hws_flash_status hsfsts;
     union ich8_hws_flash_ctrl hsflctl;
     uint32_t flash_linear_address;
     int32_t  count = 0;
     int32_t  error = E1000_ERR_EEPROM;
-    int32_t  iteration, seg_size;
-    int32_t  sector_size;
+    int32_t  iteration;
+    int32_t  sub_sector_size = 0;
+    int32_t  bank_size;
     int32_t  j = 0;
     int32_t  error_flag = 0;
 
@@ -8927,22 +8845,27 @@
     /* Determine HW Sector size: Read BERASE bits of Hw flash Status register */
     /* 00: The Hw sector is 256 bytes, hence we need to erase 16
      *     consecutive sectors.  The start index for the nth Hw sector can be
-     *     calculated as = segment * 4096 + n * 256
+     *     calculated as bank * 4096 + n * 256
      * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
      *     The start index for the nth Hw sector can be calculated
-     *     as = segment * 4096
-     * 10: Error condition
-     * 11: The Hw sector size is much bigger than the size asked to
-     *     erase...error condition */
+     *     as bank * 4096
+     * 10: The HW sector is 8K bytes
+     * 11: The Hw sector size is 64K bytes */
     if (hsfsts.hsf_status.berasesz == 0x0) {
         /* Hw sector size 256 */
-        sector_size = seg_size = ICH8_FLASH_SEG_SIZE_256;
+        sub_sector_size = ICH8_FLASH_SEG_SIZE_256;
+        bank_size = ICH8_FLASH_SECTOR_SIZE;
         iteration = ICH8_FLASH_SECTOR_SIZE / ICH8_FLASH_SEG_SIZE_256;
     } else if (hsfsts.hsf_status.berasesz == 0x1) {
-        sector_size = seg_size = ICH8_FLASH_SEG_SIZE_4K;
+        bank_size = ICH8_FLASH_SEG_SIZE_4K;
+        iteration = 1;
+    } else if (hw->mac_type != e1000_ich8lan &&
+               hsfsts.hsf_status.berasesz == 0x2) {
+        /* 8K erase size invalid for ICH8 - added in for ICH9 */
+        bank_size = ICH9_FLASH_SEG_SIZE_8K;
         iteration = 1;
     } else if (hsfsts.hsf_status.berasesz == 0x3) {
-        sector_size = seg_size = ICH8_FLASH_SEG_SIZE_64K;
+        bank_size = ICH8_FLASH_SEG_SIZE_64K;
         iteration = 1;
     } else {
         return error;
@@ -8966,16 +8889,15 @@
 
             /* Write the last 24 bits of an index within the block into Flash
              * Linear address field in Flash Address.  This probably needs to
-             * be calculated here based off the on-chip segment size and the
-             * software segment size assumed (4K) */
-            /* TBD */
-            flash_linear_address = segment * sector_size + j * seg_size;
-            flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
+             * be calculated here based off the on-chip erase sector size and
+             * the software bank size (4, 8 or 64 KBytes) */
+            flash_linear_address = bank * bank_size + j * sub_sector_size;
             flash_linear_address += hw->flash_base_addr;
+            flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
 
             E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FADDR, flash_linear_address);
 
-            error = e1000_ich8_flash_cycle(hw, 1000000);
+            error = e1000_ich8_flash_cycle(hw, ICH8_FLASH_ERASE_TIMEOUT);
             /* Check if FCERR is set to 1.  If 1, clear it and try the whole
              * sequence a few more times else Done */
             if (error == E1000_SUCCESS) {
@@ -8999,44 +8921,6 @@
     return error;
 }
 
-/******************************************************************************
- *
- * Reverse duplex setting without breaking the link.
- *
- * hw: Struct containing variables accessed by shared code
- *
- *****************************************************************************/
-#if 0
-int32_t
-e1000_duplex_reversal(struct e1000_hw *hw)
-{
-    int32_t ret_val;
-    uint16_t phy_data;
-
-    if (hw->phy_type != e1000_phy_igp_3)
-        return E1000_SUCCESS;
-
-    ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
-    if (ret_val)
-        return ret_val;
-
-    phy_data ^= MII_CR_FULL_DUPLEX;
-
-    ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
-    if (ret_val)
-        return ret_val;
-
-    ret_val = e1000_read_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, &phy_data);
-    if (ret_val)
-        return ret_val;
-
-    phy_data |= IGP3_PHY_MISC_DUPLEX_MANUAL_SET;
-    ret_val = e1000_write_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, phy_data);
-
-    return ret_val;
-}
-#endif  /*  0  */
-
 static int32_t
 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
                                       uint32_t cnf_base_addr, uint32_t cnf_size)
@@ -9071,6 +8955,14 @@
 }
 
 
+/******************************************************************************
+ * This function initializes the PHY from the NVM on ICH8 platforms. This
+ * is needed due to an issue where the NVM configuration is not properly
+ * autoloaded after power transitions. Therefore, after each PHY reset, we
+ * will load the configuration data out of the NVM manually.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *****************************************************************************/
 static int32_t
 e1000_init_lcd_from_nvm(struct e1000_hw *hw)
 {
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 4020acb..112447f 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -93,11 +92,11 @@
 
 /* Flow Control Settings */
 typedef enum {
-    e1000_fc_none = 0,
-    e1000_fc_rx_pause = 1,
-    e1000_fc_tx_pause = 2,
-    e1000_fc_full = 3,
-    e1000_fc_default = 0xFF
+    E1000_FC_NONE = 0,
+    E1000_FC_RX_PAUSE = 1,
+    E1000_FC_TX_PAUSE = 2,
+    E1000_FC_FULL = 3,
+    E1000_FC_DEFAULT = 0xFF
 } e1000_fc_type;
 
 struct e1000_shadow_ram {
@@ -302,6 +301,9 @@
 #define E1000_BLK_PHY_RESET   12
 #define E1000_ERR_SWFW_SYNC 13
 
+#define E1000_BYTE_SWAP_WORD(_value) ((((_value) & 0x00ff) << 8) | \
+                                     (((_value) & 0xff00) >> 8))
+
 /* Function prototypes */
 /* Initialization */
 int32_t e1000_reset_hw(struct e1000_hw *hw);
@@ -314,7 +316,7 @@
 int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
 void e1000_config_collision_dist(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_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, uint16_t *duplex);
 int32_t e1000_force_mac_fc(struct e1000_hw *hw);
 
 /* PHY */
@@ -322,9 +324,9 @@
 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);
-void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
 int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
 int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
+void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
 
 /* EEPROM Functions */
 int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
@@ -393,7 +395,6 @@
 int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
 int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
 int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
-int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
 int32_t e1000_read_mac_addr(struct e1000_hw * hw);
 
 /* Filters (multicast, vlan, receive) */
@@ -420,6 +421,7 @@
 void e1000_pci_clear_mwi(struct e1000_hw *hw);
 void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
+int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value);
 /* Port I/O is only supported on 82544 and newer */
 void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
 int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
@@ -574,10 +576,10 @@
  * E1000_RAR_ENTRIES - 1 multicast addresses.
  */
 #define E1000_RAR_ENTRIES 15
-#define E1000_RAR_ENTRIES_ICH8LAN  7
+#define E1000_RAR_ENTRIES_ICH8LAN  6
 
-#define MIN_NUMBER_OF_DESCRIPTORS 8
-#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+#define MIN_NUMBER_OF_DESCRIPTORS  8
+#define MAX_NUMBER_OF_DESCRIPTORS  0xFFF8
 
 /* Receive Descriptor */
 struct e1000_rx_desc {
@@ -1300,6 +1302,7 @@
     uint64_t algnerrc;
     uint64_t symerrs;
     uint64_t rxerrc;
+    uint64_t txerrc;
     uint64_t mpc;
     uint64_t scc;
     uint64_t ecol;
@@ -1332,8 +1335,9 @@
     uint64_t gotch;
     uint64_t rnbc;
     uint64_t ruc;
-    uint64_t rfc;
     uint64_t roc;
+    uint64_t rlerrc;
+    uint64_t rfc;
     uint64_t rjc;
     uint64_t mgprc;
     uint64_t mgpdc;
@@ -1440,6 +1444,7 @@
     boolean_t tbi_compatibility_on;
     boolean_t laa_is_present;
     boolean_t phy_reset_disable;
+    boolean_t initialize_hw_bits_disable;
     boolean_t fc_send_xon;
     boolean_t fc_strict_ieee;
     boolean_t report_tx_early;
@@ -1613,16 +1618,17 @@
 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
 #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
 #define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_KMRN    0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
 #define E1000_CTRL_EXT_LINK_MODE_SERDES  0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII   0x00800000
 #define E1000_CTRL_EXT_WR_WMARK_MASK  0x03000000
 #define E1000_CTRL_EXT_WR_WMARK_256   0x00000000
 #define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
 #define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
 #define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
-#define E1000_CTRL_EXT_DRV_LOAD       0x10000000  /* Driver loaded bit for FW */
-#define E1000_CTRL_EXT_IAME           0x08000000  /* Interrupt acknowledge Auto-mask */
-#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000  /* Clear Interrupt timers after IMS clear */
+#define E1000_CTRL_EXT_DRV_LOAD       0x10000000 /* Driver loaded bit for FW */
+#define E1000_CTRL_EXT_IAME           0x08000000 /* Interrupt acknowledge Auto-mask */
+#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000 /* Clear Interrupt timers after IMS clear */
 #define E1000_CRTL_EXT_PB_PAREN       0x01000000 /* packet buffer parity error detection enabled */
 #define E1000_CTRL_EXT_DF_PAREN       0x02000000 /* descriptor FIFO parity error detection enable */
 #define E1000_CTRL_EXT_GHOST_PAREN    0x40000000
@@ -2218,6 +2224,11 @@
 #define E1000_FACTPS_LAN_FUNC_SEL                   0x40000000
 #define E1000_FACTPS_PM_STATE_CHANGED               0x80000000
 
+/* PCI-Ex Config Space */
+#define PCI_EX_LINK_STATUS           0x12
+#define PCI_EX_LINK_WIDTH_MASK       0x3F0
+#define PCI_EX_LINK_WIDTH_SHIFT      4
+
 /* EEPROM Commands - Microwire */
 #define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
 #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
@@ -3120,6 +3131,7 @@
 /* I = Integrated
  * E = External
  */
+#define M88_VENDOR         0x0141
 #define M88E1000_E_PHY_ID  0x01410C50
 #define M88E1000_I_PHY_ID  0x01410C30
 #define M88E1011_I_PHY_ID  0x01410C20
@@ -3244,10 +3256,12 @@
 #define IFE_PSCL_PROBE_LEDS_OFF              0x0006  /* Force LEDs 0 and 2 off */
 #define IFE_PSCL_PROBE_LEDS_ON               0x0007  /* Force LEDs 0 and 2 on */
 
-#define ICH8_FLASH_COMMAND_TIMEOUT           500   /* 500 ms , should be adjusted */
-#define ICH8_FLASH_CYCLE_REPEAT_COUNT        10    /* 10 cycles , should be adjusted */
+#define ICH8_FLASH_COMMAND_TIMEOUT           5000    /* 5000 uSecs - adjusted */
+#define ICH8_FLASH_ERASE_TIMEOUT             3000000 /* Up to 3 seconds - worst case */
+#define ICH8_FLASH_CYCLE_REPEAT_COUNT        10      /* 10 cycles */
 #define ICH8_FLASH_SEG_SIZE_256              256
 #define ICH8_FLASH_SEG_SIZE_4K               4096
+#define ICH9_FLASH_SEG_SIZE_8K               8192
 #define ICH8_FLASH_SEG_SIZE_64K              65536
 
 #define ICH8_CYCLE_READ                      0x0
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 3f6a752..7dca38f 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -36,7 +35,7 @@
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "7.2.7-k2"DRIVERNAPI
+#define DRV_VERSION "7.2.9-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
 static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -110,16 +109,24 @@
 
 MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
 
+int e1000_up(struct e1000_adapter *adapter);
+void e1000_down(struct e1000_adapter *adapter);
+void e1000_reinit_locked(struct e1000_adapter *adapter);
+void e1000_reset(struct e1000_adapter *adapter);
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+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);
 static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_tx_ring *txdr);
+                             struct e1000_tx_ring *txdr);
 static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_rx_ring *rxdr);
+                             struct e1000_rx_ring *rxdr);
 static void e1000_free_tx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_tx_ring *tx_ring);
+                             struct e1000_tx_ring *tx_ring);
 static void e1000_free_rx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_rx_ring *rx_ring);
-
-/* Local Function Prototypes */
+                             struct e1000_rx_ring *rx_ring);
+void e1000_update_stats(struct e1000_adapter *adapter);
 
 static int e1000_init_module(void);
 static void e1000_exit_module(void);
@@ -172,6 +179,7 @@
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 			   int cmd);
+void e1000_set_ethtool_ops(struct net_device *netdev);
 static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
 static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
 static void e1000_tx_timeout(struct net_device *dev);
@@ -196,6 +204,8 @@
 static void e1000_netpoll (struct net_device *netdev);
 #endif
 
+extern void e1000_check_options(struct e1000_adapter *adapter);
+
 static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
                      pci_channel_state_t state);
 static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
@@ -212,9 +222,9 @@
 	.id_table = e1000_pci_tbl,
 	.probe    = e1000_probe,
 	.remove   = __devexit_p(e1000_remove),
+#ifdef CONFIG_PM
 	/* Power Managment Hooks */
 	.suspend  = e1000_suspend,
-#ifdef CONFIG_PM
 	.resume   = e1000_resume,
 #endif
 	.shutdown = e1000_shutdown,
@@ -466,13 +476,14 @@
 
 	adapter->tx_queue_len = netdev->tx_queue_len;
 
-	mod_timer(&adapter->watchdog_timer, jiffies);
-
 #ifdef CONFIG_E1000_NAPI
 	netif_poll_enable(netdev);
 #endif
 	e1000_irq_enable(adapter);
 
+	clear_bit(__E1000_DOWN, &adapter->flags);
+
+	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
 	return 0;
 }
 
@@ -502,25 +513,48 @@
 
 static void e1000_power_down_phy(struct e1000_adapter *adapter)
 {
-	boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
-	                              e1000_check_mng_mode(&adapter->hw);
-	/* Power down the PHY so no link is implied when interface is down
-	 * The PHY cannot be powered down if any of the following is TRUE
+	/* Power down the PHY so no link is implied when interface is down *
+	 * The PHY cannot be powered down if any of the following is TRUE *
 	 * (a) WoL is enabled
 	 * (b) AMT is active
 	 * (c) SoL/IDER session is active */
 	if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
-	    adapter->hw.mac_type != e1000_ich8lan &&
-	    adapter->hw.media_type == e1000_media_type_copper &&
-	    !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
-	    !mng_mode_enabled &&
-	    !e1000_check_phy_reset_block(&adapter->hw)) {
+	   adapter->hw.media_type == e1000_media_type_copper) {
 		uint16_t mii_reg = 0;
+
+		switch (adapter->hw.mac_type) {
+		case e1000_82540:
+		case e1000_82545:
+		case e1000_82545_rev_3:
+		case e1000_82546:
+		case e1000_82546_rev_3:
+		case e1000_82541:
+		case e1000_82541_rev_2:
+		case e1000_82547:
+		case e1000_82547_rev_2:
+			if (E1000_READ_REG(&adapter->hw, MANC) &
+			    E1000_MANC_SMBUS_EN)
+				goto out;
+			break;
+		case e1000_82571:
+		case e1000_82572:
+		case e1000_82573:
+		case e1000_80003es2lan:
+		case e1000_ich8lan:
+			if (e1000_check_mng_mode(&adapter->hw) ||
+			    e1000_check_phy_reset_block(&adapter->hw))
+				goto out;
+			break;
+		default:
+			goto out;
+		}
 		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
 		mii_reg |= MII_CR_POWER_DOWN;
 		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
 		mdelay(1);
 	}
+out:
+	return;
 }
 
 void
@@ -528,6 +562,10 @@
 {
 	struct net_device *netdev = adapter->netdev;
 
+	/* signal that we're down so the interrupt handler does not
+	 * reschedule our watchdog timer */
+	set_bit(__E1000_DOWN, &adapter->flags);
+
 	e1000_irq_disable(adapter);
 
 	del_timer_sync(&adapter->tx_fifo_stall_timer);
@@ -563,6 +601,9 @@
 e1000_reset(struct e1000_adapter *adapter)
 {
 	uint32_t pba, manc;
+#ifdef DISABLE_MULR
+	uint32_t tctl;
+#endif
 	uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
 
 	/* Repartition Pba for greater than 9k mtu
@@ -629,6 +670,12 @@
 	e1000_reset_hw(&adapter->hw);
 	if (adapter->hw.mac_type >= e1000_82544)
 		E1000_WRITE_REG(&adapter->hw, WUC, 0);
+#ifdef DISABLE_MULR
+	/* disable Multiple Reads in Transmit Control Register for debugging */
+	tctl = E1000_READ_REG(hw, TCTL);
+	E1000_WRITE_REG(hw, TCTL, tctl & ~E1000_TCTL_MULR);
+
+#endif
 	if (e1000_init_hw(&adapter->hw))
 		DPRINTK(PROBE, ERR, "Hardware Error\n");
 	e1000_update_mng_vlan(adapter);
@@ -652,9 +699,7 @@
 		                    phy_data);
 	}
 
-	if (adapter->hw.mac_type < e1000_ich8lan)
-	/* FIXME: this code is duplicate and wrong for PCI Express */
-	if (adapter->en_mng_pt) {
+	if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
 		E1000_WRITE_REG(&adapter->hw, MANC, manc);
@@ -760,7 +805,7 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	netdev->poll_controller = e1000_netpoll;
 #endif
-	strcpy(netdev->name, pci_name(pdev));
+	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
 	netdev->mem_start = mmio_start;
 	netdev->mem_end = mmio_start + mmio_len;
@@ -863,11 +908,6 @@
 	INIT_WORK(&adapter->reset_task,
 		(void (*)(void *))e1000_reset_task, netdev);
 
-	/* we're going to reset, so assume we have no link for now */
-
-	netif_carrier_off(netdev);
-	netif_stop_queue(netdev);
-
 	e1000_check_options(adapter);
 
 	/* Initial Wake on LAN setting
@@ -974,6 +1014,10 @@
 	if ((err = register_netdev(netdev)))
 		goto err_register;
 
+	/* tell the stack to leave us alone until e1000_open() is called */
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
 	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
 
 	cards_found++;
@@ -1032,8 +1076,7 @@
 
 	flush_scheduled_work();
 
-	if (adapter->hw.mac_type >= e1000_82540 &&
-	   adapter->hw.mac_type != e1000_ich8lan &&
+	if (adapter->hw.mac_type < e1000_82571 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		if (manc & E1000_MANC_SMBUS_EN) {
@@ -1161,6 +1204,8 @@
 	atomic_set(&adapter->irq_sem, 1);
 	spin_lock_init(&adapter->stats_lock);
 
+	set_bit(__E1000_DOWN, &adapter->flags);
+
 	return 0;
 }
 
@@ -1226,7 +1271,7 @@
 	int err;
 
 	/* disallow open during test */
-	if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags))
+	if (test_bit(__E1000_TESTING, &adapter->flags))
 		return -EBUSY;
 
 	/* allocate transmit descriptors */
@@ -1299,8 +1344,12 @@
 	e1000_free_all_tx_resources(adapter);
 	e1000_free_all_rx_resources(adapter);
 
+	/* kill manageability vlan ID if supported, but not if a vlan with
+	 * the same ID is registered on the host OS (let 8021q kill it) */
 	if ((adapter->hw.mng_cookie.status &
-			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+	     !(adapter->vlgrp &&
+			  adapter->vlgrp->vlan_devices[adapter->mng_vlan_id])) {
 		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
 	}
 
@@ -1510,27 +1559,14 @@
 	/* Program the Transmit Control Register */
 
 	tctl = E1000_READ_REG(hw, TCTL);
-
 	tctl &= ~E1000_TCTL_CT;
 	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
 		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
 
-#ifdef DISABLE_MULR
-	/* disable Multiple Reads for debugging */
-	tctl &= ~E1000_TCTL_MULR;
-#endif
-
 	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
 		tarc = E1000_READ_REG(hw, TARC0);
-		tarc |= ((1 << 25) | (1 << 21));
+		tarc |= (1 << 21);
 		E1000_WRITE_REG(hw, TARC0, tarc);
-		tarc = E1000_READ_REG(hw, TARC1);
-		tarc |= (1 << 25);
-		if (tctl & E1000_TCTL_MULR)
-			tarc &= ~(1 << 28);
-		else
-			tarc |= (1 << 28);
-		E1000_WRITE_REG(hw, TARC1, tarc);
 	} else if (hw->mac_type == e1000_80003es2lan) {
 		tarc = E1000_READ_REG(hw, TARC0);
 		tarc |= 1;
@@ -2892,6 +2928,35 @@
 	return 0;
 }
 
+static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+
+	netif_stop_queue(netdev);
+	/* Herbert's original patch had:
+	 *  smp_mb__after_netif_stop_queue();
+	 * but since that doesn't exist yet, just open code it. */
+	smp_mb();
+
+	/* We need to check again in a case another CPU has just
+	 * made room available. */
+	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
+		return -EBUSY;
+
+	/* A reprieve! */
+	netif_start_queue(netdev);
+	return 0;
+}
+
+static int e1000_maybe_stop_tx(struct net_device *netdev,
+                               struct e1000_tx_ring *tx_ring, int size)
+{
+	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
+		return 0;
+	return __e1000_maybe_stop_tx(netdev, size);
+}
+
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
 static int
 e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
@@ -2910,6 +2975,10 @@
 	unsigned int f;
 	len -= skb->data_len;
 
+	/* This goes back to the question of how to logically map a tx queue
+	 * to a flow.  Right now, performance is impacted slightly negatively
+	 * if using multiple tx queues.  If the stack breaks away from a
+	 * single qdisc implementation, we can look at this again. */
 	tx_ring = adapter->tx_ring;
 
 	if (unlikely(skb->len <= 0)) {
@@ -3005,8 +3074,7 @@
 
 	/* need: count + 2 desc gap to keep tail from touching
 	 * head, otherwise try next time */
-	if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
-		netif_stop_queue(netdev);
+	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
 		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 		return NETDEV_TX_BUSY;
 	}
@@ -3014,7 +3082,7 @@
 	if (unlikely(adapter->hw.mac_type == e1000_82547)) {
 		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
 			netif_stop_queue(netdev);
-			mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
+			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
 			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 			return NETDEV_TX_BUSY;
 		}
@@ -3053,8 +3121,7 @@
 	netdev->trans_start = jiffies;
 
 	/* Make sure there is space in the ring for the next send. */
-	if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
-		netif_stop_queue(netdev);
+	e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
 
 	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 	return NETDEV_TX_OK;
@@ -3131,11 +3198,13 @@
 		}
 		break;
 	case e1000_82573:
-		/* only enable jumbo frames if ASPM is disabled completely
-		 * this means both bits must be zero in 0x1A bits 3:2 */
+		/* Jumbo Frames not supported if:
+		 * - this is not an 82573L device
+		 * - ASPM is enabled in any way (0x1A bits 3:2) */
 		e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
 		                  &eeprom_data);
-		if (eeprom_data & EEPROM_WORD1A_ASPM_MASK) {
+		if ((adapter->hw.device_id != E1000_DEV_ID_82573L) ||
+		    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
 			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
 				DPRINTK(PROBE, ERR,
 			            	"Jumbo Frames not supported.\n");
@@ -3143,6 +3212,8 @@
 			}
 			break;
 		}
+		/* ERT will be enabled later to enable wire speed receives */
+
 		/* fall through to get support */
 	case e1000_82571:
 	case e1000_82572:
@@ -3328,16 +3399,15 @@
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
 		adapter->stats.ruc + adapter->stats.roc +
 		adapter->stats.cexterr;
-	adapter->net_stats.rx_length_errors = adapter->stats.ruc +
-	                                      adapter->stats.roc;
+	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
+	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
 	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
 	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
 	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
 
 	/* Tx Errors */
-
-	adapter->net_stats.tx_errors = adapter->stats.ecol +
-	                               adapter->stats.latecol;
+	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
+	adapter->net_stats.tx_errors = adapter->stats.txerrc;
 	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
 	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
 	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
@@ -3408,7 +3478,9 @@
 			rctl = E1000_READ_REG(hw, RCTL);
 			E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
 		}
-		mod_timer(&adapter->watchdog_timer, jiffies);
+		/* guard against interrupt when we're going down */
+		if (!test_bit(__E1000_DOWN, &adapter->flags))
+			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
 #ifdef CONFIG_E1000_NAPI
@@ -3546,13 +3618,14 @@
 	tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-	if (unlikely(cleaned && netif_queue_stopped(netdev) &&
-	             netif_carrier_ok(netdev))) {
-		spin_lock(&tx_ring->tx_lock);
-		if (netif_queue_stopped(netdev) &&
-		    (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))
+	if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
+		/* Make sure that anybody stopping the queue after this
+		 * sees the new next_to_clean.
+		 */
+		smp_mb();
+		if (netif_queue_stopped(netdev))
 			netif_wake_queue(netdev);
-		spin_unlock(&tx_ring->tx_lock);
 	}
 
 	if (adapter->detect_tx_hung) {
@@ -4412,13 +4485,21 @@
 	pci_write_config_word(adapter->pdev, reg, *value);
 }
 
-#if 0
-uint32_t
-e1000_io_read(struct e1000_hw *hw, unsigned long port)
+int32_t
+e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
 {
-	return inl(port);
+    struct e1000_adapter *adapter = hw->back;
+    uint16_t cap_offset;
+
+    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+    if (!cap_offset)
+        return -E1000_ERR_CONFIG;
+
+    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
+
+    return E1000_SUCCESS;
 }
-#endif  /*  0  */
+
 
 void
 e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
@@ -4693,9 +4774,7 @@
 		pci_enable_wake(pdev, PCI_D3cold, 0);
 	}
 
-	/* FIXME: this code is incorrect for PCI Express */
-	if (adapter->hw.mac_type >= e1000_82540 &&
-	   adapter->hw.mac_type != e1000_ich8lan &&
+	if (adapter->hw.mac_type < e1000_82571 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		if (manc & E1000_MANC_SMBUS_EN) {
@@ -4747,9 +4826,7 @@
 
 	netif_device_attach(netdev);
 
-	/* FIXME: this code is incorrect for PCI Express */
-	if (adapter->hw.mac_type >= e1000_82540 &&
-	   adapter->hw.mac_type != e1000_ich8lan &&
+	if (adapter->hw.mac_type < e1000_82571 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		manc &= ~(E1000_MANC_ARP_EN);
@@ -4835,8 +4912,8 @@
 	}
 	pci_set_master(pdev);
 
-	pci_enable_wake(pdev, 3, 0);
-	pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	pci_enable_wake(pdev, PCI_D3cold, 0);
 
 	/* Perform card reset only on one instance of the card */
 	if (PCI_FUNC (pdev->devfn) != 0)
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
index 46bc49d..a464cb2 100644
--- a/drivers/net/e1000/e1000_osdep.h
+++ b/drivers/net/e1000/e1000_osdep.h
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 2128427..9c3c1ac 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -397,17 +396,17 @@
 	{ /* Flow Control */
 
 		struct e1000_opt_list fc_list[] =
-			{{ e1000_fc_none,    "Flow Control Disabled" },
-			 { e1000_fc_rx_pause,"Flow Control Receive Only" },
-			 { e1000_fc_tx_pause,"Flow Control Transmit Only" },
-			 { e1000_fc_full,    "Flow Control Enabled" },
-			 { e1000_fc_default, "Flow Control Hardware Default" }};
+			{{ E1000_FC_NONE,    "Flow Control Disabled" },
+			 { E1000_FC_RX_PAUSE,"Flow Control Receive Only" },
+			 { E1000_FC_TX_PAUSE,"Flow Control Transmit Only" },
+			 { E1000_FC_FULL,    "Flow Control Enabled" },
+			 { E1000_FC_DEFAULT, "Flow Control Hardware Default" }};
 
 		struct e1000_option opt = {
 			.type = list_option,
 			.name = "Flow Control",
 			.err  = "reading default settings from EEPROM",
-			.def  = e1000_fc_default,
+			.def  = E1000_FC_DEFAULT,
 			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list),
 					 .p = fc_list }}
 		};
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 34412bc..d018706 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -944,12 +944,13 @@
 extern void fs_mii_disconnect(struct net_device *dev);
 
 static struct net_device *fs_init_instance(struct device *dev,
-		const struct fs_platform_info *fpi)
+		struct fs_platform_info *fpi)
 {
 	struct net_device *ndev = NULL;
 	struct fs_enet_private *fep = NULL;
 	int privsize, i, r, err = 0, registered = 0;
 
+	fpi->fs_no = fs_get_id(fpi);
 	/* guard */
 	if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
 		return ERR_PTR(-EINVAL);
@@ -971,7 +972,7 @@
 	dev_set_drvdata(dev, ndev);
 	fep->fpi = fpi;
 	if (fpi->init_ioports)
-		fpi->init_ioports();
+		fpi->init_ioports((struct fs_platform_info *)fpi);
 
 #ifdef CONFIG_FS_ENET_HAS_FEC
 	if (fs_get_fec_index(fpi->fs_no) >= 0)
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 03b3df3..ae8ad4f 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -188,10 +188,12 @@
 /*
  *  variables
  */
+#ifdef CONFIG_ISA
 static const char *hp100_isa_tbl[] = {
 	"HWPF150", /* HP J2573 rev A */
 	"HWP1950", /* HP J2573 */
 };
+#endif
 
 #ifdef CONFIG_EISA
 static struct eisa_device_id hp100_eisa_tbl[] = {
@@ -333,6 +335,7 @@
 	return str;
 }
 
+#ifdef CONFIG_ISA
 static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
 {
 	const char *sig;
@@ -390,9 +393,9 @@
 	}
 	return err;
 }
+#endif /* CONFIG_ISA */
 
-
-#ifndef MODULE
+#if !defined(MODULE) && defined(CONFIG_ISA)
 struct net_device * __init hp100_probe(int unit)
 {
 	struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
@@ -422,7 +425,7 @@
 	free_netdev(dev);
 	return ERR_PTR(err);
 }
-#endif
+#endif /* !MODULE && CONFIG_ISA */
 
 static int __devinit hp100_probe1(struct net_device *dev, int ioaddr,
 				  u_char bus, struct pci_dev *pci_dev)
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.h b/drivers/net/ibm_emac/ibm_emac_debug.h
index 5761389..6c7dccc 100644
--- a/drivers/net/ibm_emac/ibm_emac_debug.h
+++ b/drivers/net/ibm_emac/ibm_emac_debug.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_emac/ibm_ocp_debug.h
+ * drivers/net/ibm_emac/ibm_emac_debug.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
  *
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h
index 94abde5..117ea48 100644
--- a/drivers/net/ibm_emac/ibm_emac_rgmii.h
+++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_emac/ibm_emac_rgmii.c
+ * drivers/net/ibm_emac/ibm_emac_rgmii.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
  *
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 6469130..c26a4b8 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -200,8 +200,8 @@
 
 	pr_debug("tasklets stats %ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld \n",
 		dp->st_task_enter, dp->st_txq_refl_try, dp->st_rxq_enter,
-		dp->st_rx2tx_tran dp->st_rxq_notenter, dp->st_rx_frm_egr,
-		dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch );
+		dp->st_rx2tx_tran, dp->st_rxq_notenter, dp->st_rx_frm_egr,
+		dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch);
 
 	return stats;
 }
diff --git a/drivers/net/ixgb/Makefile b/drivers/net/ixgb/Makefile
index a8a2d3d..838a508 100644
--- a/drivers/net/ixgb/Makefile
+++ b/drivers/net/ixgb/Makefile
@@ -1,33 +1,33 @@
 ################################################################################
 #
-# 
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-# 
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of the GNU General Public License as published by the Free 
-# Software Foundation; either version 2 of the License, or (at your option) 
-# 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 
+# Intel PRO/10GbE Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
-# 
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-# 
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
 # Contact Information:
 # Linux NICS <linux.nics@intel.com>
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 # Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 #
 ################################################################################
 
 #
-# Makefile for the Intel(R) PRO/10GbE driver
+# Makefile for the Intel(R) PRO/10GbE ethernet driver
 #
 
 obj-$(CONFIG_IXGB) += ixgb.o
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index a51604b..50ffe90 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
@@ -111,7 +111,7 @@
 #define IXGB_RXBUFFER_16384 16384
 
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define IXGB_RX_BUFFER_WRITE	4	/* Must be power of 2 */
+#define IXGB_RX_BUFFER_WRITE	8	/* Must be power of 2 */
 
 /* only works for sizes that are powers of 2 */
 #define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
index 8357c55..f15aebd 100644
--- a/drivers/net/ixgb/ixgb_ee.c
+++ b/drivers/net/ixgb/ixgb_ee.c
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ee.h b/drivers/net/ixgb/ixgb_ee.h
index bf6fa22..ef236b9 100644
--- a/drivers/net/ixgb/ixgb_ee.h
+++ b/drivers/net/ixgb/ixgb_ee.h
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 64a383e..cd22523 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index acc6df7..02089b6 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index cb45689..40ef5ca 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ids.h b/drivers/net/ixgb/ixgb_ids.h
index 9fd6118..4376e7e 100644
--- a/drivers/net/ixgb/ixgb_ids.h
+++ b/drivers/net/ixgb/ixgb_ids.h
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 2e0f4b9..cfde7c2 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
@@ -36,7 +36,7 @@
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION		"1.0.112-k2"DRIVERNAPI
+#define DRV_VERSION		"1.0.117-k2"DRIVERNAPI
 char ixgb_driver_version[] = DRV_VERSION;
 static char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -437,7 +437,7 @@
 	netdev->poll_controller = ixgb_netpoll;
 #endif
 
-	strcpy(netdev->name, pci_name(pdev));
+	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 	netdev->mem_start = mmio_start;
 	netdev->mem_end = mmio_start + mmio_len;
 	netdev->base_addr = adapter->hw.io_base;
@@ -2230,7 +2230,7 @@
 			             enum pci_channel_state state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_adapter *adapter = netdev_priv(netdev);
 
 	if(netif_running(netdev))
 		ixgb_down(adapter, TRUE);
@@ -2253,7 +2253,7 @@
 static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_adapter *adapter = netdev_priv(netdev);
 
 	if(pci_enable_device(pdev)) {
 		DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n");
@@ -2297,7 +2297,7 @@
 static void ixgb_io_resume (struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_adapter *adapter = netdev_priv(netdev);
 
 	pci_set_master(pdev);
 
diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
index 19cb1d5..8434d75 100644
--- a/drivers/net/ixgb/ixgb_osdep.h
+++ b/drivers/net/ixgb/ixgb_osdep.h
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
index 39fbed2..b27442a 100644
--- a/drivers/net/ixgb/ixgb_param.c
+++ b/drivers/net/ixgb/ixgb_param.c
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  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 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 19f7ee6..94b47c8 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -289,9 +289,13 @@
 		goto probe_fail;
 	}
 
-	device_bind_driver(&phydev->dev);
+	err = device_bind_driver(&phydev->dev);
+
 	up_write(&phydev->dev.bus->subsys.rwsem);
 
+	if (err)
+		goto probe_fail;
+
 	return 0;
 
 probe_fail:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index ecd3da1..3bbd5e7 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -212,11 +212,13 @@
 
 		err = d->driver->probe(d);
 
-		if (err < 0)
-			return ERR_PTR(err);
+		if (err >= 0)
+			err = device_bind_driver(d);
 
-		device_bind_driver(d);
 		up_write(&d->bus->subsys.rwsem);
+
+		if (err)
+			return ERR_PTR(err);
 	}
 
 	if (phydev->attached_dev) {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7eeefa2..396e7df 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -50,19 +50,18 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.7"
+#define DRV_VERSION		"1.9"
 #define PFX			DRV_NAME " "
 
 /*
  * The Yukon II chipset takes 64 bit command blocks (called list elements)
  * that are organized into three (receive, transmit, status) different rings
- * similar to Tigon3. A transmit can require several elements;
- * a receive requires one (or two if using 64 bit dma).
+ * similar to Tigon3.
  */
 
-#define RX_LE_SIZE	    	512
+#define RX_LE_SIZE	    	1024
 #define RX_LE_BYTES		(RX_LE_SIZE*sizeof(struct sky2_rx_le))
-#define RX_MAX_PENDING		(RX_LE_SIZE/2 - 2)
+#define RX_MAX_PENDING		(RX_LE_SIZE/6 - 2)
 #define RX_DEF_PENDING		RX_MAX_PENDING
 #define RX_SKB_ALIGN		8
 #define RX_BUF_WRITE		16
@@ -74,7 +73,6 @@
 
 #define STATUS_RING_SIZE	2048	/* 2 ports * (TX + 2*RX) */
 #define STATUS_LE_BYTES		(STATUS_RING_SIZE*sizeof(struct sky2_status_le))
-#define ETH_JUMBO_MTU		9000
 #define TX_WATCHDOG		(5 * HZ)
 #define NAPI_WEIGHT		64
 #define PHY_RETRIES		1000
@@ -90,7 +88,7 @@
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
-static int copybreak __read_mostly = 256;
+static int copybreak __read_mostly = 128;
 module_param(copybreak, int, 0);
 MODULE_PARM_DESC(copybreak, "Receive copy threshold");
 
@@ -769,9 +767,16 @@
 	struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
 
 	sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
+	le->ctrl = 0;
 	return le;
 }
 
+static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
+					    struct sky2_tx_le *le)
+{
+	return sky2->tx_ring + (le - sky2->tx_le);
+}
+
 /* Update chip's next pointer */
 static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
 {
@@ -786,6 +791,7 @@
 {
 	struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
 	sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
+	le->ctrl = 0;
 	return le;
 }
 
@@ -795,17 +801,16 @@
 	return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
 }
 
-/* Build description to hardware about buffer */
-static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+/* Build description to hardware for one receive segment */
+static void sky2_rx_add(struct sky2_port *sky2,  u8 op,
+			dma_addr_t map, unsigned len)
 {
 	struct sky2_rx_le *le;
 	u32 hi = high32(map);
-	u16 len = sky2->rx_bufsize;
 
 	if (sky2->rx_addr64 != hi) {
 		le = sky2_next_rx(sky2);
 		le->addr = cpu_to_le32(hi);
-		le->ctrl = 0;
 		le->opcode = OP_ADDR64 | HW_OWNER;
 		sky2->rx_addr64 = high32(map + len);
 	}
@@ -813,10 +818,52 @@
 	le = sky2_next_rx(sky2);
 	le->addr = cpu_to_le32((u32) map);
 	le->length = cpu_to_le16(len);
-	le->ctrl = 0;
-	le->opcode = OP_PACKET | HW_OWNER;
+	le->opcode = op | HW_OWNER;
 }
 
+/* Build description to hardware for one possibly fragmented skb */
+static void sky2_rx_submit(struct sky2_port *sky2,
+			   const struct rx_ring_info *re)
+{
+	int i;
+
+	sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
+
+	for (i = 0; i < skb_shinfo(re->skb)->nr_frags; i++)
+		sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE);
+}
+
+
+static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+			    unsigned size)
+{
+	struct sk_buff *skb = re->skb;
+	int i;
+
+	re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+	pci_unmap_len_set(re, data_size, size);
+
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+		re->frag_addr[i] = pci_map_page(pdev,
+						skb_shinfo(skb)->frags[i].page,
+						skb_shinfo(skb)->frags[i].page_offset,
+						skb_shinfo(skb)->frags[i].size,
+						PCI_DMA_FROMDEVICE);
+}
+
+static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
+{
+	struct sk_buff *skb = re->skb;
+	int i;
+
+	pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size),
+			 PCI_DMA_FROMDEVICE);
+
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+		pci_unmap_page(pdev, re->frag_addr[i],
+			       skb_shinfo(skb)->frags[i].size,
+			       PCI_DMA_FROMDEVICE);
+}
 
 /* Tell chip where to start receive checksum.
  * Actually has two checksums, but set both same to avoid possible byte
@@ -877,12 +924,10 @@
 
 	memset(sky2->rx_le, 0, RX_LE_BYTES);
 	for (i = 0; i < sky2->rx_pending; i++) {
-		struct ring_info *re = sky2->rx_ring + i;
+		struct rx_ring_info *re = sky2->rx_ring + i;
 
 		if (re->skb) {
-			pci_unmap_single(sky2->hw->pdev,
-					 re->mapaddr, sky2->rx_bufsize,
-					 PCI_DMA_FROMDEVICE);
+			sky2_rx_unmap_skb(sky2->hw->pdev, re);
 			kfree_skb(re->skb);
 			re->skb = NULL;
 		}
@@ -936,13 +981,13 @@
 	struct sky2_hw *hw = sky2->hw;
 	u16 port = sky2->port;
 
-	spin_lock_bh(&sky2->tx_lock);
+	netif_tx_lock_bh(dev);
 
 	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
 	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
 	sky2->vlgrp = grp;
 
-	spin_unlock_bh(&sky2->tx_lock);
+	netif_tx_unlock_bh(dev);
 }
 
 static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -951,50 +996,69 @@
 	struct sky2_hw *hw = sky2->hw;
 	u16 port = sky2->port;
 
-	spin_lock_bh(&sky2->tx_lock);
+	netif_tx_lock_bh(dev);
 
 	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
 	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
 	if (sky2->vlgrp)
 		sky2->vlgrp->vlan_devices[vid] = NULL;
 
-	spin_unlock_bh(&sky2->tx_lock);
+	netif_tx_unlock_bh(dev);
 }
 #endif
 
 /*
+ * Allocate an skb for receiving. If the MTU is large enough
+ * make the skb non-linear with a fragment list of pages.
+ *
  * It appears the hardware has a bug in the FIFO logic that
  * cause it to hang if the FIFO gets overrun and the receive buffer
  * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is
  * aligned except if slab debugging is enabled.
  */
-static inline struct sk_buff *sky2_alloc_skb(struct net_device *dev,
-					     unsigned int length,
-					     gfp_t gfp_mask)
+static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
 {
 	struct sk_buff *skb;
+	unsigned long p;
+	int i;
 
-	skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask);
-	if (likely(skb)) {
-		unsigned long p	= (unsigned long) skb->data;
-		skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+	skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN);
+	if (!skb)
+		goto nomem;
+
+	p = (unsigned long) skb->data;
+	skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+
+	for (i = 0; i < sky2->rx_nfrags; i++) {
+		struct page *page = alloc_page(GFP_ATOMIC);
+
+		if (!page)
+			goto free_partial;
+		skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
 	}
 
 	return skb;
+free_partial:
+	kfree_skb(skb);
+nomem:
+	return NULL;
 }
 
 /*
  * Allocate and setup receiver buffer pool.
- * In case of 64 bit dma, there are 2X as many list elements
- * available as ring entries
- * and need to reserve one list element so we don't wrap around.
+ * Normal case this ends up creating one list element for skb
+ * in the receive ring. Worst case if using large MTU and each
+ * allocation falls on a different 64 bit region, that results
+ * in 6 list elements per ring entry.
+ * One element is used for checksum enable/disable, and one
+ * extra to avoid wrap.
  */
 static int sky2_rx_start(struct sky2_port *sky2)
 {
 	struct sky2_hw *hw = sky2->hw;
+	struct rx_ring_info *re;
 	unsigned rxq = rxqaddr[sky2->port];
-	int i;
-	unsigned thresh;
+	unsigned i, size, space, thresh;
 
 	sky2->rx_put = sky2->rx_next = 0;
 	sky2_qset(hw, rxq);
@@ -1007,27 +1071,56 @@
 	sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
 
 	rx_set_checksum(sky2);
-	for (i = 0; i < sky2->rx_pending; i++) {
-		struct ring_info *re = sky2->rx_ring + i;
 
-		re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize,
-					 GFP_KERNEL);
+	/* Space needed for frame data + headers rounded up */
+	size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8)
+		+ 8;
+
+	/* Stopping point for hardware truncation */
+	thresh = (size - 8) / sizeof(u32);
+
+	/* Account for overhead of skb - to avoid order > 0 allocation */
+	space = SKB_DATA_ALIGN(size) + NET_SKB_PAD
+		+ sizeof(struct skb_shared_info);
+
+	sky2->rx_nfrags = space >> PAGE_SHIFT;
+	BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
+
+	if (sky2->rx_nfrags != 0) {
+		/* Compute residue after pages */
+		space = sky2->rx_nfrags << PAGE_SHIFT;
+
+		if (space < size)
+			size -= space;
+		else
+			size = 0;
+
+		/* Optimize to handle small packets and headers */
+		if (size < copybreak)
+			size = copybreak;
+		if (size < ETH_HLEN)
+			size = ETH_HLEN;
+	}
+	sky2->rx_data_size = size;
+
+	/* Fill Rx ring */
+	for (i = 0; i < sky2->rx_pending; i++) {
+		re = sky2->rx_ring + i;
+
+		re->skb = sky2_rx_alloc(sky2);
 		if (!re->skb)
 			goto nomem;
 
-		re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
-					     sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-		sky2_rx_add(sky2, re->mapaddr);
+		sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size);
+		sky2_rx_submit(sky2, re);
 	}
 
-
 	/*
 	 * The receiver hangs if it receives frames larger than the
 	 * packet buffer. As a workaround, truncate oversize frames, but
 	 * the register is limited to 9 bits, so if you do frames > 2052
 	 * you better get the MTU right!
 	 */
-	thresh = (sky2->rx_bufsize - 8) / sizeof(u32);
 	if (thresh > 0x1ff)
 		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
 	else {
@@ -1035,7 +1128,6 @@
 		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
 	}
 
-
 	/* Tell chip about available buffers */
 	sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
 	return 0;
@@ -1094,7 +1186,7 @@
 		goto err_out;
 	memset(sky2->rx_le, 0, RX_LE_BYTES);
 
-	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
+	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
 				GFP_KERNEL);
 	if (!sky2->rx_ring)
 		goto err_out;
@@ -1124,7 +1216,8 @@
 	sky2_qset(hw, txqaddr[port]);
 
 	/* Set almost empty threshold */
-	if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1)
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U
+	    && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
 		sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
 
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
@@ -1195,8 +1288,6 @@
  * A single packet can generate multiple list elements, and
  * the number of ring elements will probably be less than the number
  * of list elements used.
- *
- * No BH disabling for tx_lock here (like tg3)
  */
 static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 {
@@ -1210,27 +1301,8 @@
 	u16 mss;
 	u8 ctrl;
 
-	/* No BH disabling for tx_lock here.  We are running in BH disabled
-	 * context and TX reclaim runs via poll inside of a software
-	 * interrupt, and no related locks in IRQ processing.
-	 */
-	if (!spin_trylock(&sky2->tx_lock))
-		return NETDEV_TX_LOCKED;
-
-	if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
-		/* There is a known but harmless race with lockless tx
-		 * and netif_stop_queue.
-		 */
-		if (!netif_queue_stopped(dev)) {
-			netif_stop_queue(dev);
-			if (net_ratelimit())
-				printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
-				       dev->name);
-		}
-		spin_unlock(&sky2->tx_lock);
-
-		return NETDEV_TX_BUSY;
-	}
+ 	if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
+  		return NETDEV_TX_BUSY;
 
 	if (unlikely(netif_msg_tx_queued(sky2)))
 		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
@@ -1240,13 +1312,10 @@
 	mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
 	addr64 = high32(mapping);
 
-	re = sky2->tx_ring + sky2->tx_prod;
-
 	/* Send high bits if changed or crosses boundary */
 	if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
 		le = get_tx_le(sky2);
 		le->addr = cpu_to_le32(addr64);
-		le->ctrl = 0;
 		le->opcode = OP_ADDR64 | HW_OWNER;
 		sky2->tx_addr64 = high32(mapping + len);
 	}
@@ -1262,7 +1331,6 @@
 			le = get_tx_le(sky2);
 			le->addr = cpu_to_le32(mss);
 			le->opcode = OP_LRGLEN | HW_OWNER;
-			le->ctrl = 0;
 			sky2->tx_last_mss = mss;
 		}
 	}
@@ -1275,7 +1343,6 @@
 			le = get_tx_le(sky2);
 			le->addr = 0;
 			le->opcode = OP_VLAN|HW_OWNER;
-			le->ctrl = 0;
 		} else
 			le->opcode |= OP_VLAN;
 		le->length = cpu_to_be16(vlan_tx_tag_get(skb));
@@ -1312,13 +1379,13 @@
 	le->ctrl = ctrl;
 	le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
 
-	/* Record the transmit mapping info */
+	re = tx_le_re(sky2, le);
 	re->skb = skb;
 	pci_unmap_addr_set(re, mapaddr, mapping);
+	pci_unmap_len_set(re, maplen, len);
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-		struct tx_ring_info *fre;
+		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
 				       frag->size, PCI_DMA_TODEVICE);
@@ -1337,12 +1404,12 @@
 		le->ctrl = ctrl;
 		le->opcode = OP_BUFFER | HW_OWNER;
 
-		fre = sky2->tx_ring
-			+ RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE);
-		pci_unmap_addr_set(fre, mapaddr, mapping);
+		re = tx_le_re(sky2, le);
+		re->skb = skb;
+		pci_unmap_addr_set(re, mapaddr, mapping);
+		pci_unmap_len_set(re, maplen, frag->size);
 	}
 
-	re->idx = sky2->tx_prod;
 	le->ctrl |= EOP;
 
 	if (tx_avail(sky2) <= MAX_SKB_TX_LE)
@@ -1350,8 +1417,6 @@
 
 	sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
 
-	spin_unlock(&sky2->tx_lock);
-
 	dev->trans_start = jiffies;
 	return NETDEV_TX_OK;
 }
@@ -1360,59 +1425,59 @@
  * Free ring elements from starting at tx_cons until "done"
  *
  * NB: the hardware will tell us about partial completion of multi-part
- *     buffers; these are deferred until completion.
+ *     buffers so make sure not to free skb to early.
  */
 static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 {
 	struct net_device *dev = sky2->netdev;
 	struct pci_dev *pdev = sky2->hw->pdev;
-	u16 nxt, put;
-	unsigned i;
+	unsigned idx;
 
 	BUG_ON(done >= TX_RING_SIZE);
 
-	if (unlikely(netif_msg_tx_done(sky2)))
-		printk(KERN_DEBUG "%s: tx done, up to %u\n",
-		       dev->name, done);
+	for (idx = sky2->tx_cons; idx != done;
+	     idx = RING_NEXT(idx, TX_RING_SIZE)) {
+		struct sky2_tx_le *le = sky2->tx_le + idx;
+		struct tx_ring_info *re = sky2->tx_ring + idx;
 
-	for (put = sky2->tx_cons; put != done; put = nxt) {
-		struct tx_ring_info *re = sky2->tx_ring + put;
-		struct sk_buff *skb = re->skb;
-
-		nxt = re->idx;
-		BUG_ON(nxt >= TX_RING_SIZE);
-		prefetch(sky2->tx_ring + nxt);
-
-		/* Check for partial status */
-		if (tx_dist(put, done) < tx_dist(put, nxt))
+		switch(le->opcode & ~HW_OWNER) {
+		case OP_LARGESEND:
+		case OP_PACKET:
+			pci_unmap_single(pdev,
+					 pci_unmap_addr(re, mapaddr),
+					 pci_unmap_len(re, maplen),
+					 PCI_DMA_TODEVICE);
 			break;
-
-		skb = re->skb;
-		pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
-				 skb_headlen(skb), PCI_DMA_TODEVICE);
-
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			struct tx_ring_info *fre;
-			fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
-			pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
-				       skb_shinfo(skb)->frags[i].size,
+		case OP_BUFFER:
+			pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
+				       pci_unmap_len(re, maplen),
 				       PCI_DMA_TODEVICE);
+			break;
 		}
 
-		dev_kfree_skb(skb);
+		if (le->ctrl & EOP) {
+			if (unlikely(netif_msg_tx_done(sky2)))
+				printk(KERN_DEBUG "%s: tx done %u\n",
+				       dev->name, idx);
+			dev_kfree_skb(re->skb);
+		}
+
+		le->opcode = 0;	/* paranoia */
 	}
 
-	sky2->tx_cons = put;
+	sky2->tx_cons = idx;
 	if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
 		netif_wake_queue(dev);
 }
 
 /* Cleanup all untransmitted buffers, assume transmitter not running */
-static void sky2_tx_clean(struct sky2_port *sky2)
+static void sky2_tx_clean(struct net_device *dev)
 {
-	spin_lock_bh(&sky2->tx_lock);
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	netif_tx_lock_bh(dev);
 	sky2_tx_complete(sky2, sky2->tx_prod);
-	spin_unlock_bh(&sky2->tx_lock);
+	netif_tx_unlock_bh(dev);
 }
 
 /* Network shutdown */
@@ -1443,6 +1508,13 @@
 	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
 		     RB_RST_SET | RB_DIS_OP_MD);
 
+	/* WA for dev. #4.209 */
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U
+	    && hw->chip_rev == CHIP_REV_YU_EC_U_A1)
+		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+			     sky2->speed != SPEED_1000 ?
+			     TX_STFW_ENA : TX_STFW_DIS);
+
 	ctrl = gma_read16(hw, port, GM_GP_CTRL);
 	ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
 	gma_write16(hw, port, GM_GP_CTRL, ctrl);
@@ -1489,7 +1561,7 @@
 
 	synchronize_irq(hw->pdev->irq);
 
-	sky2_tx_clean(sky2);
+	sky2_tx_clean(dev);
 	sky2_rx_clean(sky2);
 
 	pci_free_consistent(hw->pdev, RX_LE_BYTES,
@@ -1624,22 +1696,33 @@
 		return -1;
 	}
 
-	if (hw->chip_id != CHIP_ID_YUKON_FE &&
-	    gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
-		printk(KERN_ERR PFX "%s: master/slave fault",
-		       sky2->netdev->name);
-		return -1;
-	}
-
 	if (!(aux & PHY_M_PS_SPDUP_RES)) {
 		printk(KERN_ERR PFX "%s: speed/duplex mismatch",
 		       sky2->netdev->name);
 		return -1;
 	}
 
-	sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
-
 	sky2->speed = sky2_phy_speed(hw, aux);
+	if (sky2->speed == SPEED_1000) {
+		u16 ctl2 = gm_phy_read(hw, port, PHY_MARV_1000T_CTRL);
+		u16 lpa2 = gm_phy_read(hw, port, PHY_MARV_1000T_STAT);
+		if (lpa2  & PHY_B_1000S_MSF) {
+			printk(KERN_ERR PFX "%s: master/slave fault",
+			       sky2->netdev->name);
+			return -1;
+		}
+
+		if ((ctl2 & PHY_M_1000C_AFD) && (lpa2 & PHY_B_1000S_LP_FD))
+			sky2->duplex = DUPLEX_FULL;
+		else
+			sky2->duplex = DUPLEX_HALF;
+	} else {
+		u16 adv = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
+		if ((aux & adv) & PHY_AN_FULL)
+			sky2->duplex = DUPLEX_FULL;
+		else
+			sky2->duplex = DUPLEX_HALF;
+	}
 
 	/* Pause bits are offset (9..8) */
 	if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
@@ -1730,31 +1813,22 @@
 	} else if (report != sky2->tx_cons) {
 		printk(KERN_INFO PFX "status report lost?\n");
 
-		spin_lock_bh(&sky2->tx_lock);
+		netif_tx_lock_bh(dev);
 		sky2_tx_complete(sky2, report);
-		spin_unlock_bh(&sky2->tx_lock);
+		netif_tx_unlock_bh(dev);
 	} else {
 		printk(KERN_INFO PFX "hardware hung? flushing\n");
 
 		sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
 		sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
 
-		sky2_tx_clean(sky2);
+		sky2_tx_clean(dev);
 
 		sky2_qset(hw, txq);
 		sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
 	}
 }
 
-
-/* Want receive buffer size to be multiple of 64 bits
- * and incl room for vlan and truncation
- */
-static inline unsigned sky2_buf_size(int mtu)
-{
-	return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
-}
-
 static int sky2_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
@@ -1789,7 +1863,7 @@
 	sky2_rx_clean(sky2);
 
 	dev->mtu = new_mtu;
-	sky2->rx_bufsize = sky2_buf_size(new_mtu);
+
 	mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
 		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
 
@@ -1815,16 +1889,100 @@
 	return err;
 }
 
+/* For small just reuse existing skb for next receive */
+static struct sk_buff *receive_copy(struct sky2_port *sky2,
+				    const struct rx_ring_info *re,
+				    unsigned length)
+{
+	struct sk_buff *skb;
+
+	skb = netdev_alloc_skb(sky2->netdev, length + 2);
+	if (likely(skb)) {
+		skb_reserve(skb, 2);
+		pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr,
+					    length, PCI_DMA_FROMDEVICE);
+		memcpy(skb->data, re->skb->data, length);
+		skb->ip_summed = re->skb->ip_summed;
+		skb->csum = re->skb->csum;
+		pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
+					       length, PCI_DMA_FROMDEVICE);
+		re->skb->ip_summed = CHECKSUM_NONE;
+		__skb_put(skb, length);
+	}
+	return skb;
+}
+
+/* Adjust length of skb with fragments to match received data */
+static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
+			  unsigned int length)
+{
+	int i, num_frags;
+	unsigned int size;
+
+	/* put header into skb */
+	size = min(length, hdr_space);
+	skb->tail += size;
+	skb->len += size;
+	length -= size;
+
+	num_frags = skb_shinfo(skb)->nr_frags;
+	for (i = 0; i < num_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		if (length == 0) {
+			/* don't need this page */
+			__free_page(frag->page);
+			--skb_shinfo(skb)->nr_frags;
+		} else {
+			size = min(length, (unsigned) PAGE_SIZE);
+
+			frag->size = size;
+			skb->data_len += size;
+			skb->truesize += size;
+			skb->len += size;
+			length -= size;
+		}
+	}
+}
+
+/* Normal packet - take skb from ring element and put in a new one  */
+static struct sk_buff *receive_new(struct sky2_port *sky2,
+				   struct rx_ring_info *re,
+				   unsigned int length)
+{
+	struct sk_buff *skb, *nskb;
+	unsigned hdr_space = sky2->rx_data_size;
+
+	pr_debug(PFX "receive new length=%d\n", length);
+
+	/* Don't be tricky about reusing pages (yet) */
+	nskb = sky2_rx_alloc(sky2);
+	if (unlikely(!nskb))
+		return NULL;
+
+	skb = re->skb;
+	sky2_rx_unmap_skb(sky2->hw->pdev, re);
+
+	prefetch(skb->data);
+	re->skb = nskb;
+	sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
+
+	if (skb_shinfo(skb)->nr_frags)
+		skb_put_frags(skb, hdr_space, length);
+	else
+		skb_put(skb, hdr_space);
+	return skb;
+}
+
 /*
  * Receive one packet.
- * For small packets or errors, just reuse existing skb.
  * For larger packets, get new buffer.
  */
 static struct sk_buff *sky2_receive(struct net_device *dev,
 				    u16 length, u32 status)
 {
  	struct sky2_port *sky2 = netdev_priv(dev);
-	struct ring_info *re = sky2->rx_ring + sky2->rx_next;
+	struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
 	struct sk_buff *skb = NULL;
 
 	if (unlikely(netif_msg_rx_status(sky2)))
@@ -1843,40 +2001,12 @@
 	if (length > dev->mtu + ETH_HLEN)
 		goto oversize;
 
-	if (length < copybreak) {
-		skb = netdev_alloc_skb(dev, length + 2);
-		if (!skb)
-			goto resubmit;
-
-		skb_reserve(skb, 2);
-		pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
-					    length, PCI_DMA_FROMDEVICE);
-		memcpy(skb->data, re->skb->data, length);
-		skb->ip_summed = re->skb->ip_summed;
-		skb->csum = re->skb->csum;
-		pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
-					       length, PCI_DMA_FROMDEVICE);
-	} else {
-		struct sk_buff *nskb;
-
-		nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC);
-		if (!nskb)
-			goto resubmit;
-
-		skb = re->skb;
-		re->skb = nskb;
-		pci_unmap_single(sky2->hw->pdev, re->mapaddr,
-				 sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-		prefetch(skb->data);
-
-		re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
-					     sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-	}
-
-	skb_put(skb, length);
+	if (length < copybreak)
+		skb = receive_copy(sky2, re, length);
+	else
+		skb = receive_new(sky2, re, length);
 resubmit:
-	re->skb->ip_summed = CHECKSUM_NONE;
-	sky2_rx_add(sky2, re->mapaddr);
+	sky2_rx_submit(sky2, re);
 
 	return skb;
 
@@ -1909,9 +2039,9 @@
 	struct sky2_port *sky2 = netdev_priv(dev);
 
 	if (netif_running(dev)) {
-		spin_lock(&sky2->tx_lock);
+		netif_tx_lock(dev);
 		sky2_tx_complete(sky2, last);
-		spin_unlock(&sky2->tx_lock);
+		netif_tx_unlock(dev);
 	}
 }
 
@@ -2082,7 +2212,7 @@
 
 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 		sky2_pci_write16(hw, PCI_STATUS,
-				      pci_err | PCI_STATUS_ERROR_BITS);
+				 pci_err | PCI_STATUS_ERROR_BITS);
 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 	}
 
@@ -2090,7 +2220,8 @@
 		/* PCI-Express uncorrectable Error occurred */
 		u32 pex_err;
 
-		pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
+		pex_err = sky2_pci_read32(hw,
+					  hw->err_cap + PCI_ERR_UNCOR_STATUS);
 
 		if (net_ratelimit())
 			printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
@@ -2098,15 +2229,20 @@
 
 		/* clear the interrupt */
 		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-		sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
-				       0xffffffffUL);
+		sky2_pci_write32(hw,
+				 hw->err_cap + PCI_ERR_UNCOR_STATUS,
+				 0xffffffffUL);
 		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
-		if (pex_err & PEX_FATAL_ERRORS) {
+
+		/* In case of fatal error mask off to keep from getting stuck */
+		if (pex_err & (PCI_ERR_UNC_POISON_TLP | PCI_ERR_UNC_FCP
+			       | PCI_ERR_UNC_DLP)) {
 			u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
 			hwmsk &= ~Y2_IS_PCI_EXP;
 			sky2_write32(hw, B0_HWE_IMSK, hwmsk);
 		}
+
 	}
 
 	if (status & Y2_HWE_L1_MASK)
@@ -2287,6 +2423,7 @@
 	u16 status;
 	u8 t8;
 	int i;
+	u32 msk;
 
 	sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
@@ -2327,9 +2464,13 @@
 	sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
 	/* clear any PEX errors */
-	if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
-		sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
-
+	if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) {
+		hw->err_cap = pci_find_ext_capability(hw->pdev, PCI_EXT_CAP_ID_ERR);
+		if (hw->err_cap)
+			sky2_pci_write32(hw,
+					 hw->err_cap + PCI_ERR_UNCOR_STATUS,
+					 0xffffffffUL);
+	}
 
 	hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
 	hw->ports = 1;
@@ -2386,7 +2527,10 @@
 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
 	}
 
-	sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+	msk = Y2_HWE_ALL_MASK;
+	if (!hw->err_cap)
+		msk &= ~Y2_IS_PCI_EXP;
+	sky2_write32(hw, B0_HWE_IMSK, msk);
 
 	for (i = 0; i < hw->ports; i++)
 		sky2_gmac_reset(hw, i);
@@ -3102,7 +3246,6 @@
 	sky2->hw = hw;
 	sky2->msg_enable = netif_msg_init(debug, default_msg);
 
-	spin_lock_init(&sky2->tx_lock);
 	/* Auto speed and flow control */
 	sky2->autoneg = AUTONEG_ENABLE;
 	sky2->tx_pause = 1;
@@ -3115,13 +3258,11 @@
 	spin_lock_init(&sky2->phy_lock);
 	sky2->tx_pending = TX_DEF_PENDING;
 	sky2->rx_pending = RX_DEF_PENDING;
-	sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
 
 	hw->dev[port] = dev;
 
 	sky2->port = port;
 
-	dev->features |= NETIF_F_LLTX;
 	if (hw->chip_id != CHIP_ID_YUKON_EC_U)
 		dev->features |= NETIF_F_TSO;
 	if (highmem)
@@ -3316,6 +3457,14 @@
 	if (!dev)
 		goto err_out_free_pci;
 
+	if (!disable_msi && pci_enable_msi(pdev) == 0) {
+		err = sky2_test_msi(hw);
+		if (err == -EOPNOTSUPP)
+ 			pci_disable_msi(pdev);
+		else if (err)
+			goto err_out_free_netdev;
+ 	}
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR PFX "%s: cannot register net device\n",
@@ -3323,6 +3472,14 @@
 		goto err_out_free_netdev;
 	}
 
+	err = request_irq(pdev->irq,  sky2_intr, IRQF_SHARED, dev->name, hw);
+	if (err) {
+		printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+		       pci_name(pdev), pdev->irq);
+		goto err_out_unregister;
+	}
+	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+
 	sky2_show_addr(dev);
 
 	if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
@@ -3337,23 +3494,6 @@
 		}
 	}
 
-	if (!disable_msi && pci_enable_msi(pdev) == 0) {
-		err = sky2_test_msi(hw);
-		if (err == -EOPNOTSUPP)
- 			pci_disable_msi(pdev);
-		else if (err)
-			goto err_out_unregister;
- 	}
-
-	err = request_irq(pdev->irq,  sky2_intr, IRQF_SHARED, DRV_NAME, hw);
-	if (err) {
-		printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
-		       pci_name(pdev), pdev->irq);
-		goto err_out_unregister;
-	}
-
-	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
-
 	setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
 	sky2_idle_start(hw);
 
@@ -3363,10 +3503,6 @@
 
 err_out_unregister:
 	pci_disable_msi(pdev);
-	if (dev1) {
-		unregister_netdev(dev1);
-		free_netdev(dev1);
-	}
 	unregister_netdev(dev);
 err_out_free_netdev:
 	free_netdev(dev);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 4c13c37..f66109a 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -4,24 +4,17 @@
 #ifndef _SKY2_H
 #define _SKY2_H
 
-/* PCI config registers */
+#define ETH_JUMBO_MTU		9000	/* Maximum MTU supported */
+
+/* PCI device specific config registers */
 enum {
 	PCI_DEV_REG1	= 0x40,
 	PCI_DEV_REG2	= 0x44,
-	PCI_DEV_STATUS  = 0x7c,
 	PCI_DEV_REG3	= 0x80,
 	PCI_DEV_REG4	= 0x84,
 	PCI_DEV_REG5    = 0x88,
 };
 
-enum {
-	PEX_DEV_CAP	= 0xe4,
-	PEX_DEV_CTRL	= 0xe8,
-	PEX_DEV_STA	= 0xea,
-	PEX_LNK_STAT	= 0xf2,
-	PEX_UNC_ERR_STAT= 0x104,
-};
-
 /* Yukon-2 */
 enum pci_dev_reg_1 {
 	PCI_Y2_PIG_ENA	 = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
@@ -70,39 +63,6 @@
 			       PCI_STATUS_REC_MASTER_ABORT | \
 			       PCI_STATUS_REC_TARGET_ABORT | \
 			       PCI_STATUS_PARITY)
-
-enum pex_dev_ctrl {
-	PEX_DC_MAX_RRS_MSK	= 7<<12, /* Bit 14..12:	Max. Read Request Size */
-	PEX_DC_EN_NO_SNOOP	= 1<<11,/* Enable No Snoop */
-	PEX_DC_EN_AUX_POW	= 1<<10,/* Enable AUX Power */
-	PEX_DC_EN_PHANTOM	= 1<<9,	/* Enable Phantom Functions */
-	PEX_DC_EN_EXT_TAG	= 1<<8,	/* Enable Extended Tag Field */
-	PEX_DC_MAX_PLS_MSK	= 7<<5,	/* Bit  7.. 5:	Max. Payload Size Mask */
-	PEX_DC_EN_REL_ORD	= 1<<4,	/* Enable Relaxed Ordering */
-	PEX_DC_EN_UNS_RQ_RP	= 1<<3,	/* Enable Unsupported Request Reporting */
-	PEX_DC_EN_FAT_ER_RP	= 1<<2,	/* Enable Fatal Error Reporting */
-	PEX_DC_EN_NFA_ER_RP	= 1<<1,	/* Enable Non-Fatal Error Reporting */
-	PEX_DC_EN_COR_ER_RP	= 1<<0,	/* Enable Correctable Error Reporting */
-};
-#define  PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
-
-/* PEX_UNC_ERR_STAT	 PEX Uncorrectable Errors Status Register (Yukon-2) */
-enum pex_err {
-	PEX_UNSUP_REQ 	= 1<<20, /* Unsupported Request Error */
-
-	PEX_MALFOR_TLP	= 1<<18, /* Malformed TLP */
-
-	PEX_UNEXP_COMP	= 1<<16, /* Unexpected Completion */
-
-	PEX_COMP_TO	= 1<<14, /* Completion Timeout */
-	PEX_FLOW_CTRL_P	= 1<<13, /* Flow Control Protocol Error */
-	PEX_POIS_TLP	= 1<<12, /* Poisoned TLP */
-
-	PEX_DATA_LINK_P = 1<<4,	/* Data Link Protocol Error */
-	PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
-};
-
-
 enum csr_regs {
 	B0_RAP		= 0x0000,
 	B0_CTST		= 0x0004,
@@ -1816,12 +1776,14 @@
 struct tx_ring_info {
 	struct sk_buff	*skb;
 	DECLARE_PCI_UNMAP_ADDR(mapaddr);
-	u16		idx;
+	DECLARE_PCI_UNMAP_ADDR(maplen);
 };
 
-struct ring_info {
+struct rx_ring_info {
 	struct sk_buff	*skb;
-	dma_addr_t	mapaddr;
+	dma_addr_t	data_addr;
+	DECLARE_PCI_UNMAP_ADDR(data_size);
+	dma_addr_t	frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
 };
 
 struct sky2_port {
@@ -1831,7 +1793,6 @@
 	u32		     msg_enable;
 	spinlock_t	     phy_lock;
 
-	spinlock_t	     tx_lock  ____cacheline_aligned_in_smp;
 	struct tx_ring_info  *tx_ring;
 	struct sky2_tx_le    *tx_le;
 	u16		     tx_cons;		/* next le to check */
@@ -1841,13 +1802,15 @@
 	u16		     tx_last_mss;
 	u32		     tx_tcpsum;
 
-	struct ring_info     *rx_ring ____cacheline_aligned_in_smp;
+	struct rx_ring_info  *rx_ring ____cacheline_aligned_in_smp;
 	struct sky2_rx_le    *rx_le;
 	u32		     rx_addr64;
 	u16		     rx_next;		/* next re to check */
 	u16		     rx_put;		/* next le index to use */
 	u16		     rx_pending;
-	u16		     rx_bufsize;
+	u16		     rx_data_size;
+	u16		     rx_nfrags;
+
 #ifdef SKY2_VLAN_TAG_USED
 	u16		     rx_tag;
 	struct vlan_group    *vlgrp;
@@ -1873,6 +1836,7 @@
 	struct net_device    *dev[2];
 
 	int		     pm_cap;
+	int		     err_cap;
 	u8	     	     chip_id;
 	u8		     chip_rev;
 	u8		     pmd_type;
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index cc240ad..1397fc5 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -317,7 +317,7 @@
 				     SPIDER_NET_DESCR_SIZE,
 				     direction);
 
-		if (buf == DMA_ERROR_CODE)
+		if (pci_dma_mapping_error(buf))
 			goto iommu_error;
 
 		descr->bus_addr = buf;
@@ -420,7 +420,7 @@
 	buf = pci_map_single(card->pdev, descr->skb->data,
 			SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
 	descr->buf_addr = buf;
-	if (buf == DMA_ERROR_CODE) {
+	if (pci_dma_mapping_error(buf)) {
 		dev_kfree_skb_any(descr->skb);
 		if (netif_msg_rx_err(card) && net_ratelimit())
 			pr_err("Could not iommu-map rx buffer\n");
@@ -649,7 +649,7 @@
 	dma_addr_t buf;
 
 	buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
-	if (buf == DMA_ERROR_CODE) {
+	if (pci_dma_mapping_error(buf)) {
 		if (netif_msg_tx_err(card) && net_ratelimit())
 			pr_err("could not iommu-map packet (%p, %i). "
 				  "Dropping packet\n", skb->data, skb->len);
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
index 7d3e270..3b2f00b 100644
--- a/drivers/net/tokenring/tmspci.c
+++ b/drivers/net/tokenring/tmspci.c
@@ -224,8 +224,7 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
-	if (!dev)
-		BUG();
+	BUG_ON(!dev);
 	unregister_netdev(dev);
 	release_region(dev->base_addr, TMS_PCI_IO_EXTENT);
 	free_irq(dev->irq, dev);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index bc0face..151a2e1 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -697,7 +697,7 @@
 		return ret;
 
 	if (on) {
-		ret = f_setown(file, current->pid, 0);
+		ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
 		if (ret)
 			return ret;
 		tun->flags |= TUN_FASYNC;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index bd4a68c..ece3d9c 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -301,7 +301,7 @@
 	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
 	depends on NET_RADIO && (PPC_PMAC || PCI || PCMCIA)
 	---help---
-	  A driver for 802.11b wireless cards based based on the "Hermes" or
+	  A driver for 802.11b wireless cards based on the "Hermes" or
 	  Intersil HFA384x (Prism 2) MAC controller.  This includes the vast
 	  majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
 	  - except for the Cisco/Aironet cards.  Cards supported include the
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index ba737c6..39d0934 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5659,25 +5659,40 @@
 
 static int __init airo_init_module( void )
 {
-	int i, have_isa_dev = 0;
+	int i;
+#if 0
+	int have_isa_dev = 0;
+#endif
 
 	airo_entry = create_proc_entry("aironet",
 				       S_IFDIR | airo_perm,
 				       proc_root_driver);
-        airo_entry->uid = proc_uid;
-        airo_entry->gid = proc_gid;
+
+	if (airo_entry) {
+		airo_entry->uid = proc_uid;
+		airo_entry->gid = proc_gid;
+	}
 
 	for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
 		airo_print_info("", "Trying to configure ISA adapter at irq=%d "
 			"io=0x%x", irq[i], io[i] );
 		if (init_airo_card( irq[i], io[i], 0, NULL ))
+#if 0
 			have_isa_dev = 1;
+#else
+			/* do nothing */ ;
+#endif
 	}
 
 #ifdef CONFIG_PCI
 	airo_print_info("", "Probing for PCI adapters");
-	pci_register_driver(&airo_driver);
+	i = pci_register_driver(&airo_driver);
 	airo_print_info("", "Finished probing for PCI adapters");
+
+	if (i) {
+		remove_proc_entry("aironet", proc_root_driver);
+		return i;
+	}
 #endif
 
 	/* Always exit with success, as we are a library module
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 9793780..599e2fe 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -150,7 +150,6 @@
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#define __KERNEL_SYSCALLS__
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
@@ -6275,7 +6274,9 @@
 	IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
 
 	/* perform this after register_netdev so that dev->name is set */
-	sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+	err = sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+	if (err)
+		goto fail_unlock;
 
 	/* If the RF Kill switch is disabled, go ahead and complete the
 	 * startup sequence */
@@ -6541,14 +6542,17 @@
 	printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
 
 	ret = pci_register_driver(&ipw2100_pci_driver);
+	if (ret)
+		goto out;
 
 	set_acceptable_latency("ipw2100", INFINITE_LATENCY);
 #ifdef CONFIG_IPW2100_DEBUG
 	ipw2100_debug_level = debug;
-	driver_create_file(&ipw2100_pci_driver.driver,
-			   &driver_attr_debug_level);
+	ret = driver_create_file(&ipw2100_pci_driver.driver,
+				 &driver_attr_debug_level);
 #endif
 
+out:
 	return ret;
 }
 
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 1fbda77..c2949b4 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -146,7 +146,7 @@
 #include <asm/superio.h>
 #endif
 
-#include <asm/iosapic.h>
+#include <asm/ropes.h>
 #include "./iosapic_private.h"
 
 #define MODULE_NAME "iosapic"
@@ -692,6 +692,7 @@
 	DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
 			vi->eoi_addr, vi->eoi_data);
 	iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+	cpu_end_irq(irq);
 }
 
 static unsigned int iosapic_startup_irq(unsigned int irq)
@@ -728,7 +729,7 @@
 	.shutdown =	iosapic_disable_irq,
 	.enable =	iosapic_enable_irq,
 	.disable =	iosapic_disable_irq,
-	.ack =		no_ack_irq,
+	.ack =		cpu_ack_irq,
 	.end =		iosapic_end_irq,
 #ifdef CONFIG_SMP
 	.set_affinity =	iosapic_set_affinity_irq,
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 3fe4a77..ba67699 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -46,9 +46,9 @@
 #include <asm/page.h>
 #include <asm/system.h>
 
+#include <asm/ropes.h>
 #include <asm/hardware.h>	/* for register_parisc_driver() stuff */
 #include <asm/parisc-device.h>
-#include <asm/iosapic.h>	/* for iosapic_register() */
 #include <asm/io.h>		/* read/write stuff */
 
 #undef DEBUG_LBA	/* general stuff */
@@ -100,113 +100,10 @@
 
 #define MODULE_NAME "LBA"
 
-#define LBA_FUNC_ID	0x0000	/* function id */
-#define LBA_FCLASS	0x0008	/* function class, bist, header, rev... */
-#define LBA_CAPABLE	0x0030	/* capabilities register */
-
-#define LBA_PCI_CFG_ADDR	0x0040	/* poke CFG address here */
-#define LBA_PCI_CFG_DATA	0x0048	/* read or write data here */
-
-#define LBA_PMC_MTLT	0x0050	/* Firmware sets this - read only. */
-#define LBA_FW_SCRATCH	0x0058	/* Firmware writes the PCI bus number here. */
-#define LBA_ERROR_ADDR	0x0070	/* On error, address gets logged here */
-
-#define LBA_ARB_MASK	0x0080	/* bit 0 enable arbitration. PAT/PDC enables */
-#define LBA_ARB_PRI	0x0088	/* firmware sets this. */
-#define LBA_ARB_MODE	0x0090	/* firmware sets this. */
-#define LBA_ARB_MTLT	0x0098	/* firmware sets this. */
-
-#define LBA_MOD_ID	0x0100	/* Module ID. PDC_PAT_CELL reports 4 */
-
-#define LBA_STAT_CTL	0x0108	/* Status & Control */
-#define   LBA_BUS_RESET		0x01	/*  Deassert PCI Bus Reset Signal */
-#define   CLEAR_ERRLOG		0x10	/*  "Clear Error Log" cmd */
-#define   CLEAR_ERRLOG_ENABLE	0x20	/*  "Clear Error Log" Enable */
-#define   HF_ENABLE	0x40	/*    enable HF mode (default is -1 mode) */
-
-#define LBA_LMMIO_BASE	0x0200	/* < 4GB I/O address range */
-#define LBA_LMMIO_MASK	0x0208
-
-#define LBA_GMMIO_BASE	0x0210	/* > 4GB I/O address range */
-#define LBA_GMMIO_MASK	0x0218
-
-#define LBA_WLMMIO_BASE	0x0220	/* All < 4GB ranges under the same *SBA* */
-#define LBA_WLMMIO_MASK	0x0228
-
-#define LBA_WGMMIO_BASE	0x0230	/* All > 4GB ranges under the same *SBA* */
-#define LBA_WGMMIO_MASK	0x0238
-
-#define LBA_IOS_BASE	0x0240	/* I/O port space for this LBA */
-#define LBA_IOS_MASK	0x0248
-
-#define LBA_ELMMIO_BASE	0x0250	/* Extra LMMIO range */
-#define LBA_ELMMIO_MASK	0x0258
-
-#define LBA_EIOS_BASE	0x0260	/* Extra I/O port space */
-#define LBA_EIOS_MASK	0x0268
-
-#define LBA_GLOBAL_MASK	0x0270	/* Mercury only: Global Address Mask */
-#define LBA_DMA_CTL	0x0278	/* firmware sets this */
-
-#define LBA_IBASE	0x0300	/* SBA DMA support */
-#define LBA_IMASK	0x0308
-
-/* FIXME: ignore DMA Hint stuff until we can measure performance */
-#define LBA_HINT_CFG	0x0310
-#define LBA_HINT_BASE	0x0380	/* 14 registers at every 8 bytes. */
-
-#define LBA_BUS_MODE	0x0620
-
-/* ERROR regs are needed for config cycle kluges */
-#define LBA_ERROR_CONFIG 0x0680
-#define     LBA_SMART_MODE 0x20
-#define LBA_ERROR_STATUS 0x0688
-#define LBA_ROPE_CTL     0x06A0
-
-#define LBA_IOSAPIC_BASE	0x800 /* Offset of IRQ logic */
-
 /* non-postable I/O port space, densely packed */
 #define LBA_PORT_BASE	(PCI_F_EXTEND | 0xfee00000UL)
 static void __iomem *astro_iop_base __read_mostly;
 
-#define ELROY_HVERS	0x782
-#define MERCURY_HVERS	0x783
-#define QUICKSILVER_HVERS	0x784
-
-static inline int IS_ELROY(struct parisc_device *d)
-{
-	return (d->id.hversion == ELROY_HVERS);
-}
-
-static inline int IS_MERCURY(struct parisc_device *d)
-{
-	return (d->id.hversion == MERCURY_HVERS);
-}
-
-static inline int IS_QUICKSILVER(struct parisc_device *d)
-{
-	return (d->id.hversion == QUICKSILVER_HVERS);
-}
-
-
-/*
-** lba_device: Per instance Elroy data structure
-*/
-struct lba_device {
-	struct pci_hba_data hba;
-
-	spinlock_t	lba_lock;
-	void		*iosapic_obj;
-
-#ifdef CONFIG_64BIT
-	void __iomem *	iop_base;    /* PA_VIEW - for IO port accessor funcs */
-#endif
-
-	int		flags;       /* state/functionality enabled */
-	int		hw_rev;      /* HW revision of chip */
-};
-
-
 static u32 lba_t32;
 
 /* lba flags */
@@ -1542,8 +1439,8 @@
 		default: version = "TR4+";
 		}
 
-		printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
-			MODULE_NAME, version, func_class & 0xf, dev->hpa.start);
+		printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n",
+		       version, func_class & 0xf, dev->hpa.start);
 
 		if (func_class < 2) {
 			printk(KERN_WARNING "Can't support LBA older than "
@@ -1563,14 +1460,18 @@
 		}
 
 	} else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
+		int major, minor;
+
 		func_class &= 0xff;
-		version = kmalloc(6, GFP_KERNEL);
-		snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf));
+		major = func_class >> 4, minor = func_class & 0xf;
+
 		/* We could use one printk for both Elroy and Mercury,
                  * but for the mask for func_class.
                  */ 
-		printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
-		       MODULE_NAME, version, func_class & 0xff, dev->hpa.start);
+		printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n",
+		       IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major,
+		       minor, func_class, dev->hpa.start);
+
 		cfg_ops = &mercury_cfg_ops;
 	} else {
 		printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
@@ -1600,6 +1501,7 @@
 	lba_dev->hba.dev = dev;
 	lba_dev->iosapic_obj = tmp_obj;  /* save interrupt handle */
 	lba_dev->hba.iommu = sba_get_iommu(dev);  /* get iommu data */
+	parisc_set_drvdata(dev, lba_dev);
 
 	/* ------------ Second : initialize common stuff ---------- */
 	pci_bios = &lba_bios_ops;
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index bf00fa2..8dac2ba 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -684,7 +684,7 @@
 	int ret;
 
 	snprintf(lcd_text_default, sizeof(lcd_text_default),
-		"Linux %s", system_utsname.release);
+		"Linux %s", init_utsname()->release);
 
 	/* Work around the buggy PDC of KittyHawk-machines */
 	switch (CPU_HVERSION) {
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index fad5a33..2eb3577 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/parisc/kernel/power.c
+ * linux/drivers/parisc/power.c
  * HP PARISC soft power switch support driver
  *
  * Copyright (c) 2001-2005 Helge Deller <deller@gmx.de>
@@ -84,8 +84,7 @@
 
 static void deferred_poweroff(void *dummy)
 {
-	extern int cad_pid;	/* from kernel/sys.c */
-	if (kill_proc(cad_pid, SIGINT, 1)) {
+	if (kill_cad_pid(SIGINT, 1)) {
 		/* just in case killing init process failed */
 		machine_power_off();
 	}
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 8b47328..294c111 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -38,22 +38,15 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
+#include <asm/ropes.h>
+#include <asm/mckinley.h>	/* for proc_mckinley_root */
 #include <asm/runway.h>		/* for proc_runway_root */
 #include <asm/pdc.h>		/* for PDC_MODEL_* */
 #include <asm/pdcpat.h>		/* for is_pdc_pat() */
 #include <asm/parisc-device.h>
 
-
-/* declared in arch/parisc/kernel/setup.c */
-extern struct proc_dir_entry * proc_mckinley_root;
-
 #define MODULE_NAME "SBA"
 
-#ifdef CONFIG_PROC_FS
-/* depends on proc fs support. But costs CPU performance */
-#undef SBA_COLLECT_STATS
-#endif
-
 /*
 ** The number of debug flags is a clue - this code is fragile.
 ** Don't even think about messing with it unless you have
@@ -92,202 +85,12 @@
 #define DBG_RES(x...)
 #endif
 
-#if defined(CONFIG_64BIT)
-/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
-#define ZX1_SUPPORT
-#endif
-
 #define SBA_INLINE	__inline__
 
-
-/*
-** The number of pdir entries to "free" before issueing
-** a read to PCOM register to flush out PCOM writes.
-** Interacts with allocation granularity (ie 4 or 8 entries
-** allocated and free'd/purged at a time might make this
-** less interesting).
-*/
-#define DELAYED_RESOURCE_CNT	16
-
 #define DEFAULT_DMA_HINT_REG	0
 
-#define ASTRO_RUNWAY_PORT	0x582
-#define IKE_MERCED_PORT		0x803
-#define REO_MERCED_PORT		0x804
-#define REOG_MERCED_PORT	0x805
-#define PLUTO_MCKINLEY_PORT	0x880
-
-#define SBA_FUNC_ID	0x0000	/* function id */
-#define SBA_FCLASS	0x0008	/* function class, bist, header, rev... */
-
-#define IS_ASTRO(id)		((id)->hversion == ASTRO_RUNWAY_PORT)
-#define IS_IKE(id)		((id)->hversion == IKE_MERCED_PORT)
-#define IS_PLUTO(id)		((id)->hversion == PLUTO_MCKINLEY_PORT)
-
-#define SBA_FUNC_SIZE 4096   /* SBA configuration function reg set */
-
-#define ASTRO_IOC_OFFSET	(32 * SBA_FUNC_SIZE)
-#define PLUTO_IOC_OFFSET	(1 * SBA_FUNC_SIZE)
-/* Ike's IOC's occupy functions 2 and 3 */
-#define IKE_IOC_OFFSET(p)	((p+2) * SBA_FUNC_SIZE)
-
-#define IOC_CTRL          0x8	/* IOC_CTRL offset */
-#define IOC_CTRL_TC       (1 << 0) /* TOC Enable */
-#define IOC_CTRL_CE       (1 << 1) /* Coalesce Enable */
-#define IOC_CTRL_DE       (1 << 2) /* Dillon Enable */
-#define IOC_CTRL_RM       (1 << 8) /* Real Mode */
-#define IOC_CTRL_NC       (1 << 9) /* Non Coherent Mode */
-#define IOC_CTRL_D4       (1 << 11) /* Disable 4-byte coalescing */
-#define IOC_CTRL_DD       (1 << 13) /* Disable distr. LMMIO range coalescing */
-
-#define MAX_IOC		2	/* per Ike. Pluto/Astro only have 1. */
-
-#define ROPES_PER_IOC	8	/* per Ike half or Pluto/Astro */
-
-
-/*
-** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
-** Firmware programs this stuff. Don't touch it.
-*/
-#define LMMIO_DIRECT0_BASE  0x300
-#define LMMIO_DIRECT0_MASK  0x308
-#define LMMIO_DIRECT0_ROUTE 0x310
-
-#define LMMIO_DIST_BASE  0x360
-#define LMMIO_DIST_MASK  0x368
-#define LMMIO_DIST_ROUTE 0x370
-
-#define IOS_DIST_BASE	0x390
-#define IOS_DIST_MASK	0x398
-#define IOS_DIST_ROUTE	0x3A0
-
-#define IOS_DIRECT_BASE	0x3C0
-#define IOS_DIRECT_MASK	0x3C8
-#define IOS_DIRECT_ROUTE 0x3D0
-
-/*
-** Offsets into I/O TLB (Function 2 and 3 on Ike)
-*/
-#define ROPE0_CTL	0x200  /* "regbus pci0" */
-#define ROPE1_CTL	0x208
-#define ROPE2_CTL	0x210
-#define ROPE3_CTL	0x218
-#define ROPE4_CTL	0x220
-#define ROPE5_CTL	0x228
-#define ROPE6_CTL	0x230
-#define ROPE7_CTL	0x238
-
-#define IOC_ROPE0_CFG	0x500	/* pluto only */
-#define   IOC_ROPE_AO	  0x10	/* Allow "Relaxed Ordering" */
-
-
-
-#define HF_ENABLE	0x40
-
-
-#define IOC_IBASE	0x300	/* IO TLB */
-#define IOC_IMASK	0x308
-#define IOC_PCOM	0x310
-#define IOC_TCNFG	0x318
-#define IOC_PDIR_BASE	0x320
-
-/* AGP GART driver looks for this */
-#define SBA_IOMMU_COOKIE    0x0000badbadc0ffeeUL
-
-
-/*
-** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
-** It's safer (avoid memory corruption) to keep DMA page mappings
-** equivalently sized to VM PAGE_SIZE.
-**
-** We really can't avoid generating a new mapping for each
-** page since the Virtual Coherence Index has to be generated
-** and updated for each page.
-**
-** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
-*/
-#define IOVP_SIZE	PAGE_SIZE
-#define IOVP_SHIFT	PAGE_SHIFT
-#define IOVP_MASK	PAGE_MASK
-
-#define SBA_PERF_CFG	0x708	/* Performance Counter stuff */
-#define SBA_PERF_MASK1	0x718
-#define SBA_PERF_MASK2	0x730
-
-
-/*
-** Offsets into PCI Performance Counters (functions 12 and 13)
-** Controlled by PERF registers in function 2 & 3 respectively.
-*/
-#define SBA_PERF_CNT1	0x200
-#define SBA_PERF_CNT2	0x208
-#define SBA_PERF_CNT3	0x210
-
-
-struct ioc {
-	void __iomem	*ioc_hpa;	/* I/O MMU base address */
-	char		*res_map;	/* resource map, bit == pdir entry */
-	u64		*pdir_base;	/* physical base address */
-	unsigned long	ibase;	/* pdir IOV Space base - shared w/lba_pci */
-	unsigned long	imask;	/* pdir IOV Space mask - shared w/lba_pci */
-#ifdef ZX1_SUPPORT
-	unsigned long	iovp_mask;	/* help convert IOVA to IOVP */
-#endif
-	unsigned long	*res_hint;	/* next avail IOVP - circular search */
-	spinlock_t	res_lock;
-	unsigned int	res_bitshift;	/* from the LEFT! */
-	unsigned int	res_size;	/* size of resource map in bytes */
-#ifdef SBA_HINT_SUPPORT
-/* FIXME : DMA HINTs not used */
-	unsigned long	hint_mask_pdir;	/* bits used for DMA hints */
-	unsigned int	hint_shift_pdir;
-#endif
-#if DELAYED_RESOURCE_CNT > 0
-	int saved_cnt;
-	struct sba_dma_pair {
-		dma_addr_t	iova;
-		size_t		size;
-	} saved[DELAYED_RESOURCE_CNT];
-#endif
-
-#ifdef SBA_COLLECT_STATS
-#define SBA_SEARCH_SAMPLE	0x100
-	unsigned long avg_search[SBA_SEARCH_SAMPLE];
-	unsigned long avg_idx;	/* current index into avg_search */
-	unsigned long used_pages;
-	unsigned long msingle_calls;
-	unsigned long msingle_pages;
-	unsigned long msg_calls;
-	unsigned long msg_pages;
-	unsigned long usingle_calls;
-	unsigned long usingle_pages;
-	unsigned long usg_calls;
-	unsigned long usg_pages;
-#endif
-
-	/* STUFF We don't need in performance path */
-	unsigned int	pdir_size;	/* in bytes, determined by IOV Space size */
-};
-
-struct sba_device {
-	struct sba_device	*next;	/* list of SBA's in system */
-	struct parisc_device	*dev;	/* dev found in bus walk */
-	struct parisc_device_id	*iodc;	/* data about dev from firmware */
-	const char 		*name;
-	void __iomem		*sba_hpa; /* base address */
-	spinlock_t		sba_lock;
-	unsigned int		flags;  /* state/functionality enabled */
-	unsigned int		hw_rev;  /* HW revision of chip */
-
-	struct resource		chip_resv; /* MMIO reserved for chip */
-	struct resource		iommu_resv; /* MMIO reserved for iommu */
-
-	unsigned int		num_ioc;  /* number of on-board IOC's */
-	struct ioc		ioc[MAX_IOC];
-};
-
-
-static struct sba_device *sba_list;
+struct sba_device *sba_list;
+EXPORT_SYMBOL_GPL(sba_list);
 
 static unsigned long ioc_needs_fdc = 0;
 
@@ -300,8 +103,14 @@
 /* Looks nice and keeps the compiler happy */
 #define SBA_DEV(d) ((struct sba_device *) (d))
 
+#ifdef CONFIG_AGP_PARISC
+#define SBA_AGP_SUPPORT
+#endif /*CONFIG_AGP_PARISC*/
+
 #ifdef SBA_AGP_SUPPORT
-static int reserve_sba_gart = 1;
+static int sba_reserve_agpgart = 1;
+module_param(sba_reserve_agpgart, int, 1);
+MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART");
 #endif
 
 #define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
@@ -741,7 +550,7 @@
 	asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
 	pa |= (ci >> 12) & 0xff;  /* move CI (8 bits) into lowest byte */
 
-	pa |= 0x8000000000000000ULL;	/* set "valid" bit */
+	pa |= SBA_PDIR_VALID_BIT;	/* set "valid" bit */
 	*pdir_ptr = cpu_to_le64(pa);	/* swap and store into I/O Pdir */
 
 	/*
@@ -1498,6 +1307,10 @@
 	WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
 
 #ifdef SBA_AGP_SUPPORT
+{
+	struct klist_iter i;
+	struct device *dev = NULL;
+
 	/*
 	** If an AGP device is present, only use half of the IOV space
 	** for PCI DMA.  Unfortunately we can't know ahead of time
@@ -1506,20 +1319,22 @@
 	** We program the next pdir index after we stop w/ a key for
 	** the GART code to handshake on.
 	*/
-	device=NULL;
-	for (lba = sba->child; lba; lba = lba->sibling) {
+	klist_iter_init(&sba->dev.klist_children, &i);
+	while (dev = next_device(&i)) {
+		struct parisc_device *lba = to_parisc_device(dev);
 		if (IS_QUICKSILVER(lba))
-			break;
+			agp_found = 1;
 	}
+	klist_iter_exit(&sba->dev.klist_children, &i);
 
-	if (lba) {
-		DBG_INIT("%s: Reserving half of IOVA space for AGP GART support\n", __FUNCTION__);
+	if (agp_found && sba_reserve_agpgart) {
+		printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
+		       __FUNCTION__, (iova_space_size/2) >> 20);
 		ioc->pdir_size /= 2;
-		((u64 *)ioc->pdir_base)[PDIR_INDEX(iova_space_size/2)] = SBA_IOMMU_COOKIE;
-	} else {
-		DBG_INIT("%s: No GART needed - no AGP controller found\n", __FUNCTION__);
+		ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE;
 	}
-#endif /* 0 */
+}
+#endif /*SBA_AGP_SUPPORT*/
 
 }
 
@@ -1701,7 +1516,7 @@
 	}
 #endif
 
-	if (!IS_PLUTO(sba_dev->iodc)) {
+	if (!IS_PLUTO(sba_dev->dev)) {
 		ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
 		DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
 			__FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
@@ -1718,9 +1533,8 @@
 #endif
 	} /* if !PLUTO */
 
-	if (IS_ASTRO(sba_dev->iodc)) {
+	if (IS_ASTRO(sba_dev->dev)) {
 		int err;
-		/* PAT_PDC (L-class) also reports the same goofy base */
 		sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET);
 		num_ioc = 1;
 
@@ -1730,13 +1544,9 @@
 		err = request_resource(&iomem_resource, &(sba_dev->chip_resv));
 		BUG_ON(err < 0);
 
-	} else if (IS_PLUTO(sba_dev->iodc)) {
+	} else if (IS_PLUTO(sba_dev->dev)) {
 		int err;
 
-		/* We use a negative value for IOC HPA so it gets 
-                 * corrected when we add it with IKE's IOC offset.
-		 * Doesnt look clean, but fewer code. 
-                 */
 		sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET);
 		num_ioc = 1;
 
@@ -1752,14 +1562,14 @@
 		err = request_resource(&iomem_resource, &(sba_dev->iommu_resv));
 		WARN_ON(err < 0);
 	} else {
-		/* IS_IKE (ie N-class, L3000, L1500) */
+		/* IKE, REO */
 		sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0));
 		sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1));
 		num_ioc = 2;
 
 		/* TODO - LOOKUP Ike/Stretch chipset mem map */
 	}
-	/* XXX: What about Reo? */
+	/* XXX: What about Reo Grande? */
 
 	sba_dev->num_ioc = num_ioc;
 	for (i = 0; i < num_ioc; i++) {
@@ -1774,7 +1584,7 @@
 			 * Overrides bit 1 in DMA Hint Sets.
 			 * Improves netperf UDP_STREAM by ~10% for bcm5701.
 			 */
-			if (IS_PLUTO(sba_dev->iodc)) {
+			if (IS_PLUTO(sba_dev->dev)) {
 				void __iomem *rope_cfg;
 				unsigned long cfg_val;
 
@@ -1803,7 +1613,7 @@
 				READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400)
 			);
 
-		if (IS_PLUTO(sba_dev->iodc)) {
+		if (IS_PLUTO(sba_dev->dev)) {
 			sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i);
 		} else {
 			sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
@@ -2067,7 +1877,7 @@
 	/* Read HW Rev First */
 	func_class = READ_REG(sba_addr + SBA_FCLASS);
 
-	if (IS_ASTRO(&dev->id)) {
+	if (IS_ASTRO(dev)) {
 		unsigned long fclass;
 		static char astro_rev[]="Astro ?.?";
 
@@ -2078,11 +1888,11 @@
 		astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
 		version = astro_rev;
 
-	} else if (IS_IKE(&dev->id)) {
+	} else if (IS_IKE(dev)) {
 		static char ike_rev[] = "Ike rev ?";
 		ike_rev[8] = '0' + (char) (func_class & 0xff);
 		version = ike_rev;
-	} else if (IS_PLUTO(&dev->id)) {
+	} else if (IS_PLUTO(dev)) {
 		static char pluto_rev[]="Pluto ?.?";
 		pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4); 
 		pluto_rev[8] = '0' + (char) (func_class & 0x0f); 
@@ -2097,7 +1907,7 @@
 		global_ioc_cnt = count_parisc_driver(&sba_driver);
 
 		/* Astro and Pluto have one IOC per SBA */
-		if ((!IS_ASTRO(&dev->id)) || (!IS_PLUTO(&dev->id)))
+		if ((!IS_ASTRO(dev)) || (!IS_PLUTO(dev)))
 			global_ioc_cnt *= 2;
 	}
 
@@ -2117,7 +1927,6 @@
 
 	sba_dev->dev = dev;
 	sba_dev->hw_rev = func_class;
-	sba_dev->iodc = &dev->id;
 	sba_dev->name = dev->name;
 	sba_dev->sba_hpa = sba_addr;
 
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c
index fd41e28..83ee095 100644
--- a/drivers/parport/daisy.c
+++ b/drivers/parport/daisy.c
@@ -30,7 +30,7 @@
 #undef DEBUG
 
 #ifdef DEBUG
-#define DPRINTK(stuff...) printk (stuff)
+#define DPRINTK(stuff...) printk(stuff)
 #else
 #define DPRINTK(stuff...)
 #endif
@@ -46,16 +46,16 @@
 static int numdevs = 0;
 
 /* Forward-declaration of lower-level functions. */
-static int mux_present (struct parport *port);
-static int num_mux_ports (struct parport *port);
-static int select_port (struct parport *port);
-static int assign_addrs (struct parport *port);
+static int mux_present(struct parport *port);
+static int num_mux_ports(struct parport *port);
+static int select_port(struct parport *port);
+static int assign_addrs(struct parport *port);
 
 /* Add a device to the discovered topology. */
-static void add_dev (int devnum, struct parport *port, int daisy)
+static void add_dev(int devnum, struct parport *port, int daisy)
 {
 	struct daisydev *newdev, **p;
-	newdev = kmalloc (sizeof (struct daisydev), GFP_KERNEL);
+	newdev = kmalloc(sizeof(struct daisydev), GFP_KERNEL);
 	if (newdev) {
 		newdev->port = port;
 		newdev->daisy = daisy;
@@ -70,9 +70,9 @@
 }
 
 /* Clone a parport (actually, make an alias). */
-static struct parport *clone_parport (struct parport *real, int muxport)
+static struct parport *clone_parport(struct parport *real, int muxport)
 {
-	struct parport *extra = parport_register_port (real->base,
+	struct parport *extra = parport_register_port(real->base,
 						       real->irq,
 						       real->dma,
 						       real->ops);
@@ -88,7 +88,7 @@
 
 /* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains.
  * Return value is number of devices actually detected. */
-int parport_daisy_init (struct parport *port)
+int parport_daisy_init(struct parport *port)
 {
 	int detected = 0;
 	char *deviceid;
@@ -103,26 +103,26 @@
 
 	/* If mux present on normal port, need to create new
 	 * parports for each extra port. */
-	if (port->muxport < 0 && mux_present (port) &&
+	if (port->muxport < 0 && mux_present(port) &&
 	    /* don't be fooled: a mux must have 2 or 4 ports. */
-	    ((num_ports = num_mux_ports (port)) == 2 || num_ports == 4)) {
+	    ((num_ports = num_mux_ports(port)) == 2 || num_ports == 4)) {
 		/* Leave original as port zero. */
 		port->muxport = 0;
-		printk (KERN_INFO
+		printk(KERN_INFO
 			"%s: 1st (default) port of %d-way multiplexor\n",
 			port->name, num_ports);
 		for (i = 1; i < num_ports; i++) {
 			/* Clone the port. */
-			struct parport *extra = clone_parport (port, i);
+			struct parport *extra = clone_parport(port, i);
 			if (!extra) {
-				if (signal_pending (current))
+				if (signal_pending(current))
 					break;
 
-				schedule ();
+				schedule();
 				continue;
 			}
 
-			printk (KERN_INFO
+			printk(KERN_INFO
 				"%s: %d%s port of %d-way multiplexor on %s\n",
 				extra->name, i + 1, th[i + 1], num_ports,
 				port->name);
@@ -135,34 +135,34 @@
 	}
 
 	if (port->muxport >= 0)
-		select_port (port);
+		select_port(port);
 
-	parport_daisy_deselect_all (port);
-	detected += assign_addrs (port);
+	parport_daisy_deselect_all(port);
+	detected += assign_addrs(port);
 
 	/* Count the potential legacy device at the end. */
-	add_dev (numdevs++, port, -1);
+	add_dev(numdevs++, port, -1);
 
 	/* Find out the legacy device's IEEE 1284 device ID. */
-	deviceid = kmalloc (1024, GFP_KERNEL);
+	deviceid = kmalloc(1024, GFP_KERNEL);
 	if (deviceid) {
-		if (parport_device_id (numdevs - 1, deviceid, 1024) > 2)
+		if (parport_device_id(numdevs - 1, deviceid, 1024) > 2)
 			detected++;
 
-		kfree (deviceid);
+		kfree(deviceid);
 	}
 
 	if (!detected && !last_try) {
 		/* No devices were detected.  Perhaps they are in some
                    funny state; let's try to reset them and see if
                    they wake up. */
-		parport_daisy_fini (port);
-		parport_write_control (port, PARPORT_CONTROL_SELECT);
-		udelay (50);
-		parport_write_control (port,
+		parport_daisy_fini(port);
+		parport_write_control(port, PARPORT_CONTROL_SELECT);
+		udelay(50);
+		parport_write_control(port,
 				       PARPORT_CONTROL_SELECT |
 				       PARPORT_CONTROL_INIT);
-		udelay (50);
+		udelay(50);
 		last_try = 1;
 		goto again;
 	}
@@ -171,7 +171,7 @@
 }
 
 /* Forget about devices on a physical port. */
-void parport_daisy_fini (struct parport *port)
+void parport_daisy_fini(struct parport *port)
 {
 	struct daisydev **p;
 
@@ -214,7 +214,7 @@
  *	for parport_register_device().
  **/
 
-struct pardevice *parport_open (int devnum, const char *name,
+struct pardevice *parport_open(int devnum, const char *name,
 				int (*pf) (void *), void (*kf) (void *),
 				void (*irqf) (int, void *, struct pt_regs *),
 				int flags, void *handle)
@@ -237,7 +237,7 @@
 	port = parport_get_port(p->port);
 	spin_unlock(&topology_lock);
 
-	dev = parport_register_device (port, name, pf, kf,
+	dev = parport_register_device(port, name, pf, kf,
 				       irqf, flags, handle);
 	parport_put_port(port);
 	if (!dev)
@@ -248,13 +248,13 @@
 	/* Check that there really is a device to select. */
 	if (daisy >= 0) {
 		int selected;
-		parport_claim_or_block (dev);
+		parport_claim_or_block(dev);
 		selected = port->daisy;
-		parport_release (dev);
+		parport_release(dev);
 
 		if (selected != daisy) {
 			/* No corresponding device. */
-			parport_unregister_device (dev);
+			parport_unregister_device(dev);
 			return NULL;
 		}
 	}
@@ -270,9 +270,9 @@
  *	parport_register_device().
  **/
 
-void parport_close (struct pardevice *dev)
+void parport_close(struct pardevice *dev)
 {
-	parport_unregister_device (dev);
+	parport_unregister_device(dev);
 }
 
 /**
@@ -287,7 +287,7 @@
  *	exists.
  **/
 
-int parport_device_num (int parport, int mux, int daisy)
+int parport_device_num(int parport, int mux, int daisy)
 {
 	int res = -ENXIO;
 	struct daisydev *dev;
@@ -305,16 +305,16 @@
 }
 
 /* Send a daisy-chain-style CPP command packet. */
-static int cpp_daisy (struct parport *port, int cmd)
+static int cpp_daisy(struct parport *port, int cmd)
 {
 	unsigned char s;
 
-	parport_data_forward (port);
-	parport_write_data (port, 0xaa); udelay (2);
-	parport_write_data (port, 0x55); udelay (2);
-	parport_write_data (port, 0x00); udelay (2);
-	parport_write_data (port, 0xff); udelay (2);
-	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+	parport_data_forward(port);
+	parport_write_data(port, 0xaa); udelay(2);
+	parport_write_data(port, 0x55); udelay(2);
+	parport_write_data(port, 0x00); udelay(2);
+	parport_write_data(port, 0xff); udelay(2);
+	s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 					  | PARPORT_STATUS_PAPEROUT
 					  | PARPORT_STATUS_SELECT
 					  | PARPORT_STATUS_ERROR);
@@ -322,54 +322,54 @@
 		  | PARPORT_STATUS_PAPEROUT
 		  | PARPORT_STATUS_SELECT
 		  | PARPORT_STATUS_ERROR)) {
-		DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
+		DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
 			 port->name, s);
 		return -ENXIO;
 	}
 
-	parport_write_data (port, 0x87); udelay (2);
-	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+	parport_write_data(port, 0x87); udelay(2);
+	s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 					  | PARPORT_STATUS_PAPEROUT
 					  | PARPORT_STATUS_SELECT
 					  | PARPORT_STATUS_ERROR);
 	if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
-		DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
+		DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
 			 port->name, s);
 		return -ENXIO;
 	}
 
-	parport_write_data (port, 0x78); udelay (2);
-	parport_write_data (port, cmd); udelay (2);
-	parport_frob_control (port,
+	parport_write_data(port, 0x78); udelay(2);
+	parport_write_data(port, cmd); udelay(2);
+	parport_frob_control(port,
 			      PARPORT_CONTROL_STROBE,
 			      PARPORT_CONTROL_STROBE);
-	udelay (1);
-	s = parport_read_status (port);
-	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
-	udelay (1);
-	parport_write_data (port, 0xff); udelay (2);
+	udelay(1);
+	s = parport_read_status(port);
+	parport_frob_control(port, PARPORT_CONTROL_STROBE, 0);
+	udelay(1);
+	parport_write_data(port, 0xff); udelay(2);
 
 	return s;
 }
 
 /* Send a mux-style CPP command packet. */
-static int cpp_mux (struct parport *port, int cmd)
+static int cpp_mux(struct parport *port, int cmd)
 {
 	unsigned char s;
 	int rc;
 
-	parport_data_forward (port);
-	parport_write_data (port, 0xaa); udelay (2);
-	parport_write_data (port, 0x55); udelay (2);
-	parport_write_data (port, 0xf0); udelay (2);
-	parport_write_data (port, 0x0f); udelay (2);
-	parport_write_data (port, 0x52); udelay (2);
-	parport_write_data (port, 0xad); udelay (2);
-	parport_write_data (port, cmd); udelay (2);
+	parport_data_forward(port);
+	parport_write_data(port, 0xaa); udelay(2);
+	parport_write_data(port, 0x55); udelay(2);
+	parport_write_data(port, 0xf0); udelay(2);
+	parport_write_data(port, 0x0f); udelay(2);
+	parport_write_data(port, 0x52); udelay(2);
+	parport_write_data(port, 0xad); udelay(2);
+	parport_write_data(port, cmd); udelay(2);
 
-	s = parport_read_status (port);
+	s = parport_read_status(port);
 	if (!(s & PARPORT_STATUS_ACK)) {
-		DPRINTK (KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
+		DPRINTK(KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
 			 port->name, cmd, s);
 		return -EIO;
 	}
@@ -382,12 +382,12 @@
 	return rc;
 }
 
-void parport_daisy_deselect_all (struct parport *port)
+void parport_daisy_deselect_all(struct parport *port)
 {
-	cpp_daisy (port, 0x30);
+	cpp_daisy(port, 0x30);
 }
 
-int parport_daisy_select (struct parport *port, int daisy, int mode)
+int parport_daisy_select(struct parport *port, int daisy, int mode)
 {
 	switch (mode)
 	{
@@ -395,14 +395,14 @@
 		case IEEE1284_MODE_EPP:
 		case IEEE1284_MODE_EPPSL:
 		case IEEE1284_MODE_EPPSWE:
-			return !(cpp_daisy (port, 0x20 + daisy) &
+			return !(cpp_daisy(port, 0x20 + daisy) &
 				 PARPORT_STATUS_ERROR);
 
 		// For these modes we should switch to ECP mode:
 		case IEEE1284_MODE_ECP:
 		case IEEE1284_MODE_ECPRLE:
 		case IEEE1284_MODE_ECPSWE: 
-			return !(cpp_daisy (port, 0xd0 + daisy) &
+			return !(cpp_daisy(port, 0xd0 + daisy) &
 				 PARPORT_STATUS_ERROR);
 
 		// Nothing was told for BECP in Daisy chain specification.
@@ -413,28 +413,28 @@
 		case IEEE1284_MODE_BYTE:
 		case IEEE1284_MODE_COMPAT:
 		default:
-			return !(cpp_daisy (port, 0xe0 + daisy) &
+			return !(cpp_daisy(port, 0xe0 + daisy) &
 				 PARPORT_STATUS_ERROR);
 	}
 }
 
-static int mux_present (struct parport *port)
+static int mux_present(struct parport *port)
 {
-	return cpp_mux (port, 0x51) == 3;
+	return cpp_mux(port, 0x51) == 3;
 }
 
-static int num_mux_ports (struct parport *port)
+static int num_mux_ports(struct parport *port)
 {
-	return cpp_mux (port, 0x58);
+	return cpp_mux(port, 0x58);
 }
 
-static int select_port (struct parport *port)
+static int select_port(struct parport *port)
 {
 	int muxport = port->muxport;
-	return cpp_mux (port, 0x60 + muxport) == muxport;
+	return cpp_mux(port, 0x60 + muxport) == muxport;
 }
 
-static int assign_addrs (struct parport *port)
+static int assign_addrs(struct parport *port)
 {
 	unsigned char s;
 	unsigned char daisy;
@@ -442,12 +442,12 @@
 	int detected;
 	char *deviceid;
 
-	parport_data_forward (port);
-	parport_write_data (port, 0xaa); udelay (2);
-	parport_write_data (port, 0x55); udelay (2);
-	parport_write_data (port, 0x00); udelay (2);
-	parport_write_data (port, 0xff); udelay (2);
-	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+	parport_data_forward(port);
+	parport_write_data(port, 0xaa); udelay(2);
+	parport_write_data(port, 0x55); udelay(2);
+	parport_write_data(port, 0x00); udelay(2);
+	parport_write_data(port, 0xff); udelay(2);
+	s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 					  | PARPORT_STATUS_PAPEROUT
 					  | PARPORT_STATUS_SELECT
 					  | PARPORT_STATUS_ERROR);
@@ -455,40 +455,40 @@
 		  | PARPORT_STATUS_PAPEROUT
 		  | PARPORT_STATUS_SELECT
 		  | PARPORT_STATUS_ERROR)) {
-		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
+		DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
 			 port->name, s);
 		return 0;
 	}
 
-	parport_write_data (port, 0x87); udelay (2);
-	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+	parport_write_data(port, 0x87); udelay(2);
+	s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 					  | PARPORT_STATUS_PAPEROUT
 					  | PARPORT_STATUS_SELECT
 					  | PARPORT_STATUS_ERROR);
 	if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
-		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
+		DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
 			 port->name, s);
 		return 0;
 	}
 
-	parport_write_data (port, 0x78); udelay (2);
-	s = parport_read_status (port);
+	parport_write_data(port, 0x78); udelay(2);
+	s = parport_read_status(port);
 
 	for (daisy = 0;
 	     (s & (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT))
 		     == (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT)
 		     && daisy < 4;
 	     ++daisy) {
-		parport_write_data (port, daisy);
-		udelay (2);
-		parport_frob_control (port,
+		parport_write_data(port, daisy);
+		udelay(2);
+		parport_frob_control(port,
 				      PARPORT_CONTROL_STROBE,
 				      PARPORT_CONTROL_STROBE);
-		udelay (1);
-		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
-		udelay (1);
+		udelay(1);
+		parport_frob_control(port, PARPORT_CONTROL_STROBE, 0);
+		udelay(1);
 
-		add_dev (numdevs++, port, daisy);
+		add_dev(numdevs++, port, daisy);
 
 		/* See if this device thought it was the last in the
 		 * chain. */
@@ -499,21 +499,21 @@
 		   last_dev from next device or if last_dev does not
 		   work status lines from some non-daisy chain
 		   device. */
-		s = parport_read_status (port);
+		s = parport_read_status(port);
 	}
 
-	parport_write_data (port, 0xff); udelay (2);
+	parport_write_data(port, 0xff); udelay(2);
 	detected = numdevs - thisdev;
-	DPRINTK (KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name,
+	DPRINTK(KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name,
 		 detected);
 
 	/* Ask the new devices to introduce themselves. */
-	deviceid = kmalloc (1024, GFP_KERNEL);
+	deviceid = kmalloc(1024, GFP_KERNEL);
 	if (!deviceid) return 0;
 
 	for (daisy = 0; thisdev < numdevs; thisdev++, daisy++)
-		parport_device_id (thisdev, deviceid, 1024);
+		parport_device_id(thisdev, deviceid, 1024);
 
-	kfree (deviceid);
+	kfree(deviceid);
 	return detected;
 }
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 43894dde..fe800dc 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -3374,10 +3374,6 @@
 
 static int __init parport_pc_init(void)
 {
-#if defined(CONFIG_PPC_MERGE)
-	if (check_legacy_ioport(PARALLEL_BASE))
-		return -ENODEV;
-#endif
 	if (parse_parport_params())
 		return -EINVAL;
 
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index c27e782..3029412 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -52,3 +52,11 @@
 
 	  When in doubt, say N.
 
+config HT_IRQ
+	bool "Interrupts on hypertransport devices"
+	default y
+	depends on X86_LOCAL_APIC && X86_IO_APIC
+	help
+	   This allows native hypertransport devices to use interrupts.
+
+	   If unsure say Y.
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index f2d152b..e3beb78 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -14,6 +14,12 @@
 # Build the PCI Hotplug drivers if we were asked to
 obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
 
+# Build the PCI MSI interrupt support
+obj-$(CONFIG_PCI_MSI) += msi.o
+
+# Build the Hypertransport interrupt support
+obj-$(CONFIG_HT_IRQ) += htirq.o
+
 #
 # Some architectures use the generic PCI setup functions
 #
@@ -27,11 +33,6 @@
 obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
 obj-$(CONFIG_X86_VISWS) += setup-irq.o
 
-msiobj-y := msi.o msi-apic.o
-msiobj-$(CONFIG_IA64_GENERIC) += msi-altix.o
-msiobj-$(CONFIG_IA64_SGI_SN2) += msi-altix.o
-obj-$(CONFIG_PCI_MSI) += $(msiobj-y)
-
 #
 # ACPI Related PCI FW Functions
 #
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 8a60f39..6e780db 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -157,7 +157,7 @@
 	tristate "RPA PCI Hotplug driver"
 	depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
 	help
-	  Say Y here if you have a a RPA system that supports PCI Hotplug.
+	  Say Y here if you have a RPA system that supports PCI Hotplug.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rpaphp.
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
new file mode 100644
index 0000000..0e27f24
--- /dev/null
+++ b/drivers/pci/htirq.c
@@ -0,0 +1,190 @@
+/*
+ * File:	htirq.c
+ * Purpose:	Hypertransport Interrupt Capability
+ *
+ * Copyright (C) 2006 Linux Networx
+ * Copyright (C) Eric Biederman <ebiederman@lnxi.com>
+ */
+
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/gfp.h>
+#include <linux/htirq.h>
+
+/* Global ht irq lock.
+ *
+ * This is needed to serialize access to the data port in hypertransport
+ * irq capability.
+ *
+ * With multiple simultaneous hypertransport irq devices it might pay
+ * to make this more fine grained.  But start with simple, stupid, and correct.
+ */
+static DEFINE_SPINLOCK(ht_irq_lock);
+
+struct ht_irq_cfg {
+	struct pci_dev *dev;
+	unsigned pos;
+	unsigned idx;
+};
+
+void write_ht_irq_low(unsigned int irq, u32 data)
+{
+	struct ht_irq_cfg *cfg = get_irq_data(irq);
+	unsigned long flags;
+	spin_lock_irqsave(&ht_irq_lock, flags);
+	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+	spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+void write_ht_irq_high(unsigned int irq, u32 data)
+{
+	struct ht_irq_cfg *cfg = get_irq_data(irq);
+	unsigned long flags;
+	spin_lock_irqsave(&ht_irq_lock, flags);
+	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
+	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+	spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+u32 read_ht_irq_low(unsigned int irq)
+{
+	struct ht_irq_cfg *cfg = get_irq_data(irq);
+	unsigned long flags;
+	u32 data;
+	spin_lock_irqsave(&ht_irq_lock, flags);
+	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+	spin_unlock_irqrestore(&ht_irq_lock, flags);
+	return data;
+}
+
+u32 read_ht_irq_high(unsigned int irq)
+{
+	struct ht_irq_cfg *cfg = get_irq_data(irq);
+	unsigned long flags;
+	u32 data;
+	spin_lock_irqsave(&ht_irq_lock, flags);
+	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
+	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+	spin_unlock_irqrestore(&ht_irq_lock, flags);
+	return data;
+}
+
+void mask_ht_irq(unsigned int irq)
+{
+	struct ht_irq_cfg *cfg;
+	unsigned long flags;
+	u32 data;
+
+	cfg = get_irq_data(irq);
+
+	spin_lock_irqsave(&ht_irq_lock, flags);
+	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+	data |= 1;
+	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+	spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+void unmask_ht_irq(unsigned int irq)
+{
+	struct ht_irq_cfg *cfg;
+	unsigned long flags;
+	u32 data;
+
+	cfg = get_irq_data(irq);
+
+	spin_lock_irqsave(&ht_irq_lock, flags);
+	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+	data &= ~1;
+	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+	spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+/**
+ * ht_create_irq - create an irq and attach it to a device.
+ * @dev: The hypertransport device to find the irq capability on.
+ * @idx: Which of the possible irqs to attach to.
+ *
+ * ht_create_irq is needs to be called for all hypertransport devices
+ * that generate irqs.
+ *
+ * The irq number of the new irq or a negative error value is returned.
+ */
+int ht_create_irq(struct pci_dev *dev, int idx)
+{
+	struct ht_irq_cfg *cfg;
+	unsigned long flags;
+	u32 data;
+	int max_irq;
+	int pos;
+	int irq;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_HT);
+	while (pos) {
+		u8 subtype;
+		pci_read_config_byte(dev, pos + 3, &subtype);
+		if (subtype == HT_CAPTYPE_IRQ)
+			break;
+		pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT);
+	}
+	if (!pos)
+		return -EINVAL;
+
+	/* Verify the idx I want to use is in range */
+	spin_lock_irqsave(&ht_irq_lock, flags);
+	pci_write_config_byte(dev, pos + 2, 1);
+	pci_read_config_dword(dev, pos + 4, &data);
+	spin_unlock_irqrestore(&ht_irq_lock, flags);
+
+	max_irq = (data >> 16) & 0xff;
+	if ( idx > max_irq)
+		return -EINVAL;
+
+	cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	cfg->dev = dev;
+	cfg->pos = pos;
+	cfg->idx = 0x10 + (idx * 2);
+
+	irq = create_irq();
+	if (irq < 0) {
+		kfree(cfg);
+		return -EBUSY;
+	}
+	set_irq_data(irq, cfg);
+
+	if (arch_setup_ht_irq(irq, dev) < 0) {
+		ht_destroy_irq(irq);
+		return -EBUSY;
+	}
+
+	return irq;
+}
+
+/**
+ * ht_destroy_irq - destroy an irq created with ht_create_irq
+ *
+ * This reverses ht_create_irq removing the specified irq from
+ * existence.  The irq should be free before this happens.
+ */
+void ht_destroy_irq(unsigned int irq)
+{
+	struct ht_irq_cfg *cfg;
+
+	cfg = get_irq_data(irq);
+	set_irq_chip(irq, NULL);
+	set_irq_data(irq, NULL);
+	destroy_irq(irq);
+
+	kfree(cfg);
+}
+
+EXPORT_SYMBOL(ht_create_irq);
+EXPORT_SYMBOL(ht_destroy_irq);
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c
deleted file mode 100644
index 5ed798b3..0000000
--- a/drivers/pci/msi-apic.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * MSI hooks for standard x86 apic
- */
-
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <asm/smp.h>
-
-#include "msi.h"
-
-/*
- * Shifts for APIC-based data
- */
-
-#define MSI_DATA_VECTOR_SHIFT		0
-#define	    MSI_DATA_VECTOR(v)		(((u8)v) << MSI_DATA_VECTOR_SHIFT)
-
-#define MSI_DATA_DELIVERY_SHIFT		8
-#define     MSI_DATA_DELIVERY_FIXED	(0 << MSI_DATA_DELIVERY_SHIFT)
-#define     MSI_DATA_DELIVERY_LOWPRI	(1 << MSI_DATA_DELIVERY_SHIFT)
-
-#define MSI_DATA_LEVEL_SHIFT		14
-#define     MSI_DATA_LEVEL_DEASSERT	(0 << MSI_DATA_LEVEL_SHIFT)
-#define     MSI_DATA_LEVEL_ASSERT	(1 << MSI_DATA_LEVEL_SHIFT)
-
-#define MSI_DATA_TRIGGER_SHIFT		15
-#define     MSI_DATA_TRIGGER_EDGE	(0 << MSI_DATA_TRIGGER_SHIFT)
-#define     MSI_DATA_TRIGGER_LEVEL	(1 << MSI_DATA_TRIGGER_SHIFT)
-
-/*
- * Shift/mask fields for APIC-based bus address
- */
-
-#define MSI_ADDR_HEADER			0xfee00000
-
-#define MSI_ADDR_DESTID_MASK		0xfff0000f
-#define     MSI_ADDR_DESTID_CPU(cpu)	((cpu) << MSI_TARGET_CPU_SHIFT)
-
-#define MSI_ADDR_DESTMODE_SHIFT		2
-#define     MSI_ADDR_DESTMODE_PHYS	(0 << MSI_ADDR_DESTMODE_SHIFT)
-#define	    MSI_ADDR_DESTMODE_LOGIC	(1 << MSI_ADDR_DESTMODE_SHIFT)
-
-#define MSI_ADDR_REDIRECTION_SHIFT	3
-#define     MSI_ADDR_REDIRECTION_CPU	(0 << MSI_ADDR_REDIRECTION_SHIFT)
-#define     MSI_ADDR_REDIRECTION_LOWPRI	(1 << MSI_ADDR_REDIRECTION_SHIFT)
-
-
-static void
-msi_target_apic(unsigned int vector,
-		unsigned int dest_cpu,
-		u32 *address_hi,	/* in/out */
-		u32 *address_lo)	/* in/out */
-{
-	u32 addr = *address_lo;
-
-	addr &= MSI_ADDR_DESTID_MASK;
-	addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu));
-
-	*address_lo = addr;
-}
-
-static int
-msi_setup_apic(struct pci_dev *pdev,	/* unused in generic */
-		unsigned int vector,
-		u32 *address_hi,
-		u32 *address_lo,
-		u32 *data)
-{
-	unsigned long	dest_phys_id;
-
-	dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
-
-	*address_hi = 0;
-	*address_lo =	MSI_ADDR_HEADER |
-			MSI_ADDR_DESTMODE_PHYS |
-			MSI_ADDR_REDIRECTION_CPU |
-			MSI_ADDR_DESTID_CPU(dest_phys_id);
-
-	*data = MSI_DATA_TRIGGER_EDGE |
-		MSI_DATA_LEVEL_ASSERT |
-		MSI_DATA_DELIVERY_FIXED |
-		MSI_DATA_VECTOR(vector);
-
-	return 0;
-}
-
-static void
-msi_teardown_apic(unsigned int vector)
-{
-	return;		/* no-op */
-}
-
-/*
- * Generic ops used on most IA archs/platforms.  Set with msi_register()
- */
-
-struct msi_ops msi_apic_ops = {
-	.setup = msi_setup_apic,
-	.teardown = msi_teardown_apic,
-	.target = msi_target_apic,
-};
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 27a0574..f9fdc54 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -6,6 +6,7 @@
  * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
  */
 
+#include <linux/err.h>
 #include <linux/mm.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -14,6 +15,7 @@
 #include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
+#include <linux/msi.h>
 
 #include <asm/errno.h>
 #include <asm/io.h>
@@ -27,23 +29,6 @@
 static kmem_cache_t* msi_cachep;
 
 static int pci_msi_enable = 1;
-static int last_alloc_vector;
-static int nr_released_vectors;
-static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
-static int nr_msix_devices;
-
-#ifndef CONFIG_X86_IO_APIC
-int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
-#endif
-
-static struct msi_ops *msi_ops;
-
-int
-msi_register(struct msi_ops *ops)
-{
-	msi_ops = ops;
-	return 0;
-}
 
 static int msi_cache_init(void)
 {
@@ -55,26 +40,25 @@
 	return 0;
 }
 
-static void msi_set_mask_bit(unsigned int vector, int flag)
+static void msi_set_mask_bit(unsigned int irq, int flag)
 {
 	struct msi_desc *entry;
 
-	entry = (struct msi_desc *)msi_desc[vector];
-	if (!entry || !entry->dev || !entry->mask_base)
-		return;
+	entry = msi_desc[irq];
+	BUG_ON(!entry || !entry->dev);
 	switch (entry->msi_attrib.type) {
 	case PCI_CAP_ID_MSI:
-	{
-		int		pos;
-		u32		mask_bits;
+		if (entry->msi_attrib.maskbit) {
+			int		pos;
+			u32		mask_bits;
 
-		pos = (long)entry->mask_base;
-		pci_read_config_dword(entry->dev, pos, &mask_bits);
-		mask_bits &= ~(1);
-		mask_bits |= flag;
-		pci_write_config_dword(entry->dev, pos, mask_bits);
+			pos = (long)entry->mask_base;
+			pci_read_config_dword(entry->dev, pos, &mask_bits);
+			mask_bits &= ~(1);
+			mask_bits |= flag;
+			pci_write_config_dword(entry->dev, pos, mask_bits);
+		}
 		break;
-	}
 	case PCI_CAP_ID_MSIX:
 	{
 		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -83,261 +67,101 @@
 		break;
 	}
 	default:
+		BUG();
 		break;
 	}
 }
 
-#ifdef CONFIG_SMP
-static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
+void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-	struct msi_desc *entry;
-	u32 address_hi, address_lo;
-	unsigned int irq = vector;
-	unsigned int dest_cpu = first_cpu(cpu_mask);
-
-	entry = (struct msi_desc *)msi_desc[vector];
-	if (!entry || !entry->dev)
-		return;
-
-	switch (entry->msi_attrib.type) {
+	struct msi_desc *entry = get_irq_data(irq);
+	switch(entry->msi_attrib.type) {
 	case PCI_CAP_ID_MSI:
 	{
-		int pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI);
+		struct pci_dev *dev = entry->dev;
+		int pos = entry->msi_attrib.pos;
+		u16 data;
 
-		if (!pos)
-			return;
-
-		pci_read_config_dword(entry->dev, msi_upper_address_reg(pos),
-			&address_hi);
-		pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
-			&address_lo);
-
-		msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
-
-		pci_write_config_dword(entry->dev, msi_upper_address_reg(pos),
-			address_hi);
-		pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
-			address_lo);
-		set_native_irq_info(irq, cpu_mask);
+		pci_read_config_dword(dev, msi_lower_address_reg(pos),
+					&msg->address_lo);
+		if (entry->msi_attrib.is_64) {
+			pci_read_config_dword(dev, msi_upper_address_reg(pos),
+						&msg->address_hi);
+			pci_read_config_word(dev, msi_data_reg(pos, 1), &data);
+		} else {
+			msg->address_hi = 0;
+			pci_read_config_word(dev, msi_data_reg(pos, 1), &data);
+		}
+		msg->data = data;
 		break;
 	}
 	case PCI_CAP_ID_MSIX:
 	{
-		int offset_hi =
-			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET;
-		int offset_lo =
-			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
+		void __iomem *base;
+		base = entry->mask_base +
+			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
 
-		address_hi = readl(entry->mask_base + offset_hi);
-		address_lo = readl(entry->mask_base + offset_lo);
+		msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+		msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+		msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
+ 		break;
+ 	}
+ 	default:
+		BUG();
+	}
+}
 
-		msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
+void write_msi_msg(unsigned int irq, struct msi_msg *msg)
+{
+	struct msi_desc *entry = get_irq_data(irq);
+	switch (entry->msi_attrib.type) {
+	case PCI_CAP_ID_MSI:
+	{
+		struct pci_dev *dev = entry->dev;
+		int pos = entry->msi_attrib.pos;
 
-		writel(address_hi, entry->mask_base + offset_hi);
-		writel(address_lo, entry->mask_base + offset_lo);
-		set_native_irq_info(irq, cpu_mask);
+		pci_write_config_dword(dev, msi_lower_address_reg(pos),
+					msg->address_lo);
+		if (entry->msi_attrib.is_64) {
+			pci_write_config_dword(dev, msi_upper_address_reg(pos),
+						msg->address_hi);
+			pci_write_config_word(dev, msi_data_reg(pos, 1),
+						msg->data);
+		} else {
+			pci_write_config_word(dev, msi_data_reg(pos, 0),
+						msg->data);
+		}
+		break;
+	}
+	case PCI_CAP_ID_MSIX:
+	{
+		void __iomem *base;
+		base = entry->mask_base +
+			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+		writel(msg->address_lo,
+			base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+		writel(msg->address_hi,
+			base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+		writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
 		break;
 	}
 	default:
-		break;
+		BUG();
 	}
 }
-#else
-#define set_msi_affinity NULL
-#endif /* CONFIG_SMP */
 
-static void mask_MSI_irq(unsigned int vector)
+void mask_msi_irq(unsigned int irq)
 {
-	msi_set_mask_bit(vector, 1);
+	msi_set_mask_bit(irq, 1);
 }
 
-static void unmask_MSI_irq(unsigned int vector)
+void unmask_msi_irq(unsigned int irq)
 {
-	msi_set_mask_bit(vector, 0);
+	msi_set_mask_bit(irq, 0);
 }
 
-static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
-{
-	struct msi_desc *entry;
-	unsigned long flags;
-
-	spin_lock_irqsave(&msi_lock, flags);
-	entry = msi_desc[vector];
-	if (!entry || !entry->dev) {
-		spin_unlock_irqrestore(&msi_lock, flags);
-		return 0;
-	}
-	entry->msi_attrib.state = 1;	/* Mark it active */
-	spin_unlock_irqrestore(&msi_lock, flags);
-
-	return 0;	/* never anything pending */
-}
-
-static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
-{
-	startup_msi_irq_wo_maskbit(vector);
-	unmask_MSI_irq(vector);
-	return 0;	/* never anything pending */
-}
-
-static void shutdown_msi_irq(unsigned int vector)
-{
-	struct msi_desc *entry;
-	unsigned long flags;
-
-	spin_lock_irqsave(&msi_lock, flags);
-	entry = msi_desc[vector];
-	if (entry && entry->dev)
-		entry->msi_attrib.state = 0;	/* Mark it not active */
-	spin_unlock_irqrestore(&msi_lock, flags);
-}
-
-static void end_msi_irq_wo_maskbit(unsigned int vector)
-{
-	move_native_irq(vector);
-	ack_APIC_irq();
-}
-
-static void end_msi_irq_w_maskbit(unsigned int vector)
-{
-	move_native_irq(vector);
-	unmask_MSI_irq(vector);
-	ack_APIC_irq();
-}
-
-static void do_nothing(unsigned int vector)
-{
-}
-
-/*
- * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI-X Capability Structure.
- */
-static struct hw_interrupt_type msix_irq_type = {
-	.typename	= "PCI-MSI-X",
-	.startup	= startup_msi_irq_w_maskbit,
-	.shutdown	= shutdown_msi_irq,
-	.enable		= unmask_MSI_irq,
-	.disable	= mask_MSI_irq,
-	.ack		= mask_MSI_irq,
-	.end		= end_msi_irq_w_maskbit,
-	.set_affinity	= set_msi_affinity
-};
-
-/*
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI Capability Structure with
- * Mask-and-Pending Bits.
- */
-static struct hw_interrupt_type msi_irq_w_maskbit_type = {
-	.typename	= "PCI-MSI",
-	.startup	= startup_msi_irq_w_maskbit,
-	.shutdown	= shutdown_msi_irq,
-	.enable		= unmask_MSI_irq,
-	.disable	= mask_MSI_irq,
-	.ack		= mask_MSI_irq,
-	.end		= end_msi_irq_w_maskbit,
-	.set_affinity	= set_msi_affinity
-};
-
-/*
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI Capability Structure without
- * Mask-and-Pending Bits.
- */
-static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
-	.typename	= "PCI-MSI",
-	.startup	= startup_msi_irq_wo_maskbit,
-	.shutdown	= shutdown_msi_irq,
-	.enable		= do_nothing,
-	.disable	= do_nothing,
-	.ack		= do_nothing,
-	.end		= end_msi_irq_wo_maskbit,
-	.set_affinity	= set_msi_affinity
-};
-
-static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
-static int assign_msi_vector(void)
-{
-	static int new_vector_avail = 1;
-	int vector;
-	unsigned long flags;
-
-	/*
-	 * msi_lock is provided to ensure that successful allocation of MSI
-	 * vector is assigned unique among drivers.
-	 */
-	spin_lock_irqsave(&msi_lock, flags);
-
-	if (!new_vector_avail) {
-		int free_vector = 0;
-
-		/*
-	 	 * vector_irq[] = -1 indicates that this specific vector is:
-	 	 * - assigned for MSI (since MSI have no associated IRQ) or
-	 	 * - assigned for legacy if less than 16, or
-	 	 * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping
-	 	 * vector_irq[] = 0 indicates that this vector, previously
-		 * assigned for MSI, is freed by hotplug removed operations.
-		 * This vector will be reused for any subsequent hotplug added
-		 * operations.
-	 	 * vector_irq[] > 0 indicates that this vector is assigned for
-		 * IOxAPIC IRQs. This vector and its value provides a 1-to-1
-		 * vector-to-IOxAPIC IRQ mapping.
-	 	 */
-		for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
-			if (vector_irq[vector] != 0)
-				continue;
-			free_vector = vector;
-			if (!msi_desc[vector])
-			      	break;
-			else
-				continue;
-		}
-		if (!free_vector) {
-			spin_unlock_irqrestore(&msi_lock, flags);
-			return -EBUSY;
-		}
-		vector_irq[free_vector] = -1;
-		nr_released_vectors--;
-		spin_unlock_irqrestore(&msi_lock, flags);
-		if (msi_desc[free_vector] != NULL) {
-			struct pci_dev *dev;
-			int tail;
-
-			/* free all linked vectors before re-assign */
-			do {
-				spin_lock_irqsave(&msi_lock, flags);
-				dev = msi_desc[free_vector]->dev;
-				tail = msi_desc[free_vector]->link.tail;
-				spin_unlock_irqrestore(&msi_lock, flags);
-				msi_free_vector(dev, tail, 1);
-			} while (free_vector != tail);
-		}
-
-		return free_vector;
-	}
-	vector = assign_irq_vector(AUTO_ASSIGN);
-	last_alloc_vector = vector;
-	if (vector  == LAST_DEVICE_VECTOR)
-		new_vector_avail = 0;
-
-	spin_unlock_irqrestore(&msi_lock, flags);
-	return vector;
-}
-
-static int get_new_vector(void)
-{
-	int vector = assign_msi_vector();
-
-	if (vector > 0)
-		set_intr_gate(vector, interrupt[vector]);
-
-	return vector;
-}
-
+static int msi_free_irq(struct pci_dev* dev, int irq);
 static int msi_init(void)
 {
 	static int status = -ENOMEM;
@@ -352,22 +176,6 @@
 		return status;
 	}
 
-	status = msi_arch_init();
-	if (status < 0) {
-		pci_msi_enable = 0;
-		printk(KERN_WARNING
-		       "PCI: MSI arch init failed.  MSI disabled.\n");
-		return status;
-	}
-
-	if (! msi_ops) {
-		printk(KERN_WARNING
-		       "PCI: MSI ops not registered. MSI disabled.\n");
-		status = -EINVAL;
-		return status;
-	}
-
-	last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
 	status = msi_cache_init();
 	if (status < 0) {
 		pci_msi_enable = 0;
@@ -375,23 +183,9 @@
 		return status;
 	}
 
-	if (last_alloc_vector < 0) {
-		pci_msi_enable = 0;
-		printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
-		status = -EBUSY;
-		return status;
-	}
-	vector_irq[last_alloc_vector] = 0;
-	nr_released_vectors++;
-
 	return status;
 }
 
-static int get_msi_vector(struct pci_dev *dev)
-{
-	return get_new_vector();
-}
-
 static struct msi_desc* alloc_msi_entry(void)
 {
 	struct msi_desc *entry;
@@ -406,29 +200,44 @@
 	return entry;
 }
 
-static void attach_msi_entry(struct msi_desc *entry, int vector)
+static void attach_msi_entry(struct msi_desc *entry, int irq)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
-	msi_desc[vector] = entry;
+	msi_desc[irq] = entry;
 	spin_unlock_irqrestore(&msi_lock, flags);
 }
 
-static void irq_handler_init(int cap_id, int pos, int mask)
+static int create_msi_irq(void)
 {
-	unsigned long flags;
+	struct msi_desc *entry;
+	int irq;
 
-	spin_lock_irqsave(&irq_desc[pos].lock, flags);
-	if (cap_id == PCI_CAP_ID_MSIX)
-		irq_desc[pos].chip = &msix_irq_type;
-	else {
-		if (!mask)
-			irq_desc[pos].chip = &msi_irq_wo_maskbit_type;
-		else
-			irq_desc[pos].chip = &msi_irq_w_maskbit_type;
+	entry = alloc_msi_entry();
+	if (!entry)
+		return -ENOMEM;
+
+	irq = create_irq();
+	if (irq < 0) {
+		kmem_cache_free(msi_cachep, entry);
+		return -EBUSY;
 	}
-	spin_unlock_irqrestore(&irq_desc[pos].lock, flags);
+
+	set_irq_data(irq, entry);
+
+	return irq;
+}
+
+static void destroy_msi_irq(unsigned int irq)
+{
+	struct msi_desc *entry;
+
+	entry = get_irq_data(irq);
+	set_irq_chip(irq, NULL);
+	set_irq_data(irq, NULL);
+	destroy_irq(irq);
+	kmem_cache_free(msi_cachep, entry);
 }
 
 static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
@@ -473,21 +282,21 @@
 	}
 }
 
-static int msi_lookup_vector(struct pci_dev *dev, int type)
+static int msi_lookup_irq(struct pci_dev *dev, int type)
 {
-	int vector;
+	int irq;
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
-	for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
-		if (!msi_desc[vector] || msi_desc[vector]->dev != dev ||
-			msi_desc[vector]->msi_attrib.type != type ||
-			msi_desc[vector]->msi_attrib.default_vector != dev->irq)
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		if (!msi_desc[irq] || msi_desc[irq]->dev != dev ||
+			msi_desc[irq]->msi_attrib.type != type ||
+			msi_desc[irq]->msi_attrib.default_irq != dev->irq)
 			continue;
 		spin_unlock_irqrestore(&msi_lock, flags);
-		/* This pre-assigned MSI vector for this device
-		   already exits. Override dev->irq with this vector */
-		dev->irq = vector;
+		/* This pre-assigned MSI irq for this device
+		   already exits. Override dev->irq with this irq */
+		dev->irq = irq;
 		return 0;
 	}
 	spin_unlock_irqrestore(&msi_lock, flags);
@@ -499,11 +308,6 @@
 {
 	if (!dev)
 		return;
-
-   	if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0)
-		nr_msix_devices++;
-	else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0)
-		nr_reserved_vectors++;
 }
 
 #ifdef CONFIG_PM
@@ -577,7 +381,7 @@
 {
 	int pos;
 	int temp;
-	int vector, head, tail = 0;
+	int irq, head, tail = 0;
 	u16 control;
 	struct pci_cap_saved_state *save_state;
 
@@ -599,33 +403,20 @@
 
 	/* save the table */
 	temp = dev->irq;
-	if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
+	if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
 		kfree(save_state);
 		return -EINVAL;
 	}
 
-	vector = head = dev->irq;
+	irq = head = dev->irq;
 	while (head != tail) {
-		int j;
-		void __iomem *base;
 		struct msi_desc *entry;
 
-		entry = msi_desc[vector];
-		base = entry->mask_base;
-		j = entry->msi_attrib.entry_nr;
+		entry = msi_desc[irq];
+		read_msi_msg(irq, &entry->msg_save);
 
-		entry->address_lo_save =
-			readl(base + j * PCI_MSIX_ENTRY_SIZE +
-			      PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-		entry->address_hi_save =
-			readl(base + j * PCI_MSIX_ENTRY_SIZE +
-			      PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-		entry->data_save =
-			readl(base + j * PCI_MSIX_ENTRY_SIZE +
-			      PCI_MSIX_ENTRY_DATA_OFFSET);
-
-		tail = msi_desc[vector]->link.tail;
-		vector = tail;
+		tail = msi_desc[irq]->link.tail;
+		irq = tail;
 	}
 	dev->irq = temp;
 
@@ -638,9 +429,7 @@
 {
 	u16 save;
 	int pos;
-	int vector, head, tail = 0;
-	void __iomem *base;
-	int j;
+	int irq, head, tail = 0;
 	struct msi_desc *entry;
 	int temp;
 	struct pci_cap_saved_state *save_state;
@@ -658,26 +447,15 @@
 
 	/* route the table */
 	temp = dev->irq;
-	if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX))
+	if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX))
 		return;
-	vector = head = dev->irq;
+	irq = head = dev->irq;
 	while (head != tail) {
-		entry = msi_desc[vector];
-		base = entry->mask_base;
-		j = entry->msi_attrib.entry_nr;
+		entry = msi_desc[irq];
+		write_msi_msg(irq, &entry->msg_save);
 
-		writel(entry->address_lo_save,
-			base + j * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-		writel(entry->address_hi_save,
-			base + j * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-		writel(entry->data_save,
-			base + j * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_DATA_OFFSET);
-
-		tail = msi_desc[vector]->link.tail;
-		vector = tail;
+		tail = msi_desc[irq]->link.tail;
+		irq = tail;
 	}
 	dev->irq = temp;
 
@@ -686,32 +464,43 @@
 }
 #endif
 
-static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
+/**
+ * msi_capability_init - configure device's MSI capability structure
+ * @dev: pointer to the pci_dev data structure of MSI device function
+ *
+ * Setup the MSI capability structure of device function with a single
+ * MSI irq, regardless of device function is capable of handling
+ * multiple messages. A return of zero indicates the successful setup
+ * of an entry zero with the new MSI irq or non-zero for otherwise.
+ **/
+static int msi_capability_init(struct pci_dev *dev)
 {
 	int status;
-	u32 address_hi;
-	u32 address_lo;
-	u32 data;
-	int pos, vector = dev->irq;
+	struct msi_desc *entry;
+	int pos, irq;
 	u16 control;
 
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
 	pci_read_config_word(dev, msi_control_reg(pos), &control);
+	/* MSI Entry Initialization */
+	irq = create_msi_irq();
+	if (irq < 0)
+		return irq;
 
-	/* Configure MSI capability structure */
-	status = msi_ops->setup(dev, vector, &address_hi, &address_lo, &data);
-	if (status < 0)
-		return status;
-
-	pci_write_config_dword(dev, msi_lower_address_reg(pos), address_lo);
-	if (is_64bit_address(control)) {
-		pci_write_config_dword(dev,
-			msi_upper_address_reg(pos), address_hi);
-		pci_write_config_word(dev,
-			msi_data_reg(pos, 1), data);
-	} else
-		pci_write_config_word(dev,
-			msi_data_reg(pos, 0), data);
+	entry = get_irq_data(irq);
+	entry->link.head = irq;
+	entry->link.tail = irq;
+	entry->msi_attrib.type = PCI_CAP_ID_MSI;
+	entry->msi_attrib.is_64 = is_64bit_address(control);
+	entry->msi_attrib.entry_nr = 0;
+	entry->msi_attrib.maskbit = is_mask_bit_support(control);
+	entry->msi_attrib.default_irq = dev->irq;	/* Save IOAPIC IRQ */
+	entry->msi_attrib.pos = pos;
+	if (is_mask_bit_support(control)) {
+		entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
+				is_64bit_address(control));
+	}
+	entry->dev = dev;
 	if (entry->msi_attrib.maskbit) {
 		unsigned int maskbits, temp;
 		/* All MSIs are unmasked by default, Mask them all */
@@ -725,65 +514,18 @@
 			msi_mask_bits_reg(pos, is_64bit_address(control)),
 			maskbits);
 	}
-
-	return 0;
-}
-
-/**
- * msi_capability_init - configure device's MSI capability structure
- * @dev: pointer to the pci_dev data structure of MSI device function
- *
- * Setup the MSI capability structure of device function with a single
- * MSI vector, regardless of device function is capable of handling
- * multiple messages. A return of zero indicates the successful setup
- * of an entry zero with the new MSI vector or non-zero for otherwise.
- **/
-static int msi_capability_init(struct pci_dev *dev)
-{
-	int status;
-	struct msi_desc *entry;
-	int pos, vector;
-	u16 control;
-
-   	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-	pci_read_config_word(dev, msi_control_reg(pos), &control);
-	/* MSI Entry Initialization */
-	entry = alloc_msi_entry();
-	if (!entry)
-		return -ENOMEM;
-
-	vector = get_msi_vector(dev);
-	if (vector < 0) {
-		kmem_cache_free(msi_cachep, entry);
-		return -EBUSY;
-	}
-	entry->link.head = vector;
-	entry->link.tail = vector;
-	entry->msi_attrib.type = PCI_CAP_ID_MSI;
-	entry->msi_attrib.state = 0;			/* Mark it not active */
-	entry->msi_attrib.entry_nr = 0;
-	entry->msi_attrib.maskbit = is_mask_bit_support(control);
-	entry->msi_attrib.default_vector = dev->irq;	/* Save IOAPIC IRQ */
-	dev->irq = vector;
-	entry->dev = dev;
-	if (is_mask_bit_support(control)) {
-		entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
-				is_64bit_address(control));
-	}
-	/* Replace with MSI handler */
-	irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
 	/* Configure MSI capability structure */
-	status = msi_register_init(dev, entry);
-	if (status != 0) {
-		dev->irq = entry->msi_attrib.default_vector;
-		kmem_cache_free(msi_cachep, entry);
+	status = arch_setup_msi_irq(irq, dev);
+	if (status < 0) {
+		destroy_msi_irq(irq);
 		return status;
 	}
 
-	attach_msi_entry(entry, vector);
+	attach_msi_entry(entry, irq);
 	/* Set MSI enabled bits	 */
 	enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
+	dev->irq = irq;
 	return 0;
 }
 
@@ -794,18 +536,15 @@
  * @nvec: number of @entries
  *
  * Setup the MSI-X capability structure of device function with a
- * single MSI-X vector. A return of zero indicates the successful setup of
- * requested MSI-X entries with allocated vectors or non-zero for otherwise.
+ * single MSI-X irq. A return of zero indicates the successful setup of
+ * requested MSI-X entries with allocated irqs or non-zero for otherwise.
  **/
 static int msix_capability_init(struct pci_dev *dev,
 				struct msix_entry *entries, int nvec)
 {
 	struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
-	u32 address_hi;
-	u32 address_lo;
-	u32 data;
 	int status;
-	int vector, pos, i, j, nr_entries, temp = 0;
+	int irq, pos, i, j, nr_entries, temp = 0;
 	unsigned long phys_addr;
 	u32 table_offset;
  	u16 control;
@@ -827,65 +566,56 @@
 
 	/* MSI-X Table Initialization */
 	for (i = 0; i < nvec; i++) {
-		entry = alloc_msi_entry();
-		if (!entry)
+		irq = create_msi_irq();
+		if (irq < 0)
 			break;
-		vector = get_msi_vector(dev);
-		if (vector < 0) {
-			kmem_cache_free(msi_cachep, entry);
-			break;
-		}
 
+		entry = get_irq_data(irq);
  		j = entries[i].entry;
- 		entries[i].vector = vector;
+ 		entries[i].vector = irq;
 		entry->msi_attrib.type = PCI_CAP_ID_MSIX;
- 		entry->msi_attrib.state = 0;		/* Mark it not active */
+		entry->msi_attrib.is_64 = 1;
 		entry->msi_attrib.entry_nr = j;
 		entry->msi_attrib.maskbit = 1;
-		entry->msi_attrib.default_vector = dev->irq;
+		entry->msi_attrib.default_irq = dev->irq;
+		entry->msi_attrib.pos = pos;
 		entry->dev = dev;
 		entry->mask_base = base;
 		if (!head) {
-			entry->link.head = vector;
-			entry->link.tail = vector;
+			entry->link.head = irq;
+			entry->link.tail = irq;
 			head = entry;
 		} else {
 			entry->link.head = temp;
 			entry->link.tail = tail->link.tail;
-			tail->link.tail = vector;
-			head->link.head = vector;
+			tail->link.tail = irq;
+			head->link.head = irq;
 		}
-		temp = vector;
+		temp = irq;
 		tail = entry;
-		/* Replace with MSI-X handler */
-		irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
 		/* Configure MSI-X capability structure */
-		status = msi_ops->setup(dev, vector,
-					&address_hi,
-					&address_lo,
-					&data);
-		if (status < 0)
+		status = arch_setup_msi_irq(irq, dev);
+		if (status < 0) {
+			destroy_msi_irq(irq);
 			break;
+		}
 
-		writel(address_lo,
-			base + j * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-		writel(address_hi,
-			base + j * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-		writel(data,
-			base + j * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_DATA_OFFSET);
-		attach_msi_entry(entry, vector);
+		attach_msi_entry(entry, irq);
 	}
 	if (i != nvec) {
+		int avail = i - 1;
 		i--;
 		for (; i >= 0; i--) {
-			vector = (entries + i)->vector;
-			msi_free_vector(dev, vector, 0);
+			irq = (entries + i)->vector;
+			msi_free_irq(dev, irq);
 			(entries + i)->vector = 0;
 		}
-		return -EBUSY;
+		/* If we had some success report the number of irqs
+		 * we succeeded in setting up.
+		 */
+		if (avail <= 0)
+			avail = -EBUSY;
+		return avail;
 	}
 	/* Set MSI-X enabled bits */
 	enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
@@ -925,15 +655,14 @@
  * @dev: pointer to the pci_dev data structure of MSI device function
  *
  * Setup the MSI capability structure of device function with
- * a single MSI vector upon its software driver call to request for
+ * a single MSI irq upon its software driver call to request for
  * MSI mode enabled on its hardware device function. A return of zero
  * indicates the successful setup of an entry zero with the new MSI
- * vector or non-zero for otherwise.
+ * irq or non-zero for otherwise.
  **/
 int pci_enable_msi(struct pci_dev* dev)
 {
 	int pos, temp, status;
-	u16 control;
 
 	if (pci_msi_supported(dev) < 0)
 		return -EINVAL;
@@ -948,52 +677,25 @@
 	if (!pos)
 		return -EINVAL;
 
-	if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
-		/* Lookup Sucess */
-		unsigned long flags;
+	WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI));
 
-		pci_read_config_word(dev, msi_control_reg(pos), &control);
-		if (control & PCI_MSI_FLAGS_ENABLE)
-			return 0;	/* Already in MSI mode */
-		spin_lock_irqsave(&msi_lock, flags);
-		if (!vector_irq[dev->irq]) {
-			msi_desc[dev->irq]->msi_attrib.state = 0;
-			vector_irq[dev->irq] = -1;
-			nr_released_vectors--;
-			spin_unlock_irqrestore(&msi_lock, flags);
-			status = msi_register_init(dev, msi_desc[dev->irq]);
-			if (status == 0)
-				enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
-			return status;
-		}
-		spin_unlock_irqrestore(&msi_lock, flags);
-		dev->irq = temp;
-	}
-	/* Check whether driver already requested for MSI-X vectors */
+	/* Check whether driver already requested for MSI-X irqs */
 	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
+	if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
 			printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
-			       "Device already has MSI-X vectors assigned\n",
+			       "Device already has MSI-X irq assigned\n",
 			       pci_name(dev));
 			dev->irq = temp;
 			return -EINVAL;
 	}
 	status = msi_capability_init(dev);
-	if (!status) {
-   		if (!pos)
-			nr_reserved_vectors--;	/* Only MSI capable */
-		else if (nr_msix_devices > 0)
-			nr_msix_devices--;	/* Both MSI and MSI-X capable,
-						   but choose enabling MSI */
-	}
-
 	return status;
 }
 
 void pci_disable_msi(struct pci_dev* dev)
 {
 	struct msi_desc *entry;
-	int pos, default_vector;
+	int pos, default_irq;
 	u16 control;
 	unsigned long flags;
 
@@ -1010,41 +712,41 @@
 	if (!(control & PCI_MSI_FLAGS_ENABLE))
 		return;
 
+	disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
+
 	spin_lock_irqsave(&msi_lock, flags);
 	entry = msi_desc[dev->irq];
 	if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
 		spin_unlock_irqrestore(&msi_lock, flags);
 		return;
 	}
-	if (entry->msi_attrib.state) {
+	if (irq_has_action(dev->irq)) {
 		spin_unlock_irqrestore(&msi_lock, flags);
 		printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
-		       "free_irq() on MSI vector %d\n",
+		       "free_irq() on MSI irq %d\n",
 		       pci_name(dev), dev->irq);
-		BUG_ON(entry->msi_attrib.state > 0);
+		BUG_ON(irq_has_action(dev->irq));
 	} else {
-		vector_irq[dev->irq] = 0; /* free it */
-		nr_released_vectors++;
-		default_vector = entry->msi_attrib.default_vector;
+		default_irq = entry->msi_attrib.default_irq;
 		spin_unlock_irqrestore(&msi_lock, flags);
-		/* Restore dev->irq to its default pin-assertion vector */
-		dev->irq = default_vector;
-		disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
-					PCI_CAP_ID_MSI);
+		msi_free_irq(dev, dev->irq);
+
+		/* Restore dev->irq to its default pin-assertion irq */
+		dev->irq = default_irq;
 	}
 }
 
-static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
+static int msi_free_irq(struct pci_dev* dev, int irq)
 {
 	struct msi_desc *entry;
 	int head, entry_nr, type;
 	void __iomem *base;
 	unsigned long flags;
 
-	msi_ops->teardown(vector);
+	arch_teardown_msi_irq(irq);
 
 	spin_lock_irqsave(&msi_lock, flags);
-	entry = msi_desc[vector];
+	entry = msi_desc[irq];
 	if (!entry || entry->dev != dev) {
 		spin_unlock_irqrestore(&msi_lock, flags);
 		return -EINVAL;
@@ -1056,100 +758,42 @@
 	msi_desc[entry->link.head]->link.tail = entry->link.tail;
 	msi_desc[entry->link.tail]->link.head = entry->link.head;
 	entry->dev = NULL;
-	if (!reassign) {
-		vector_irq[vector] = 0;
-		nr_released_vectors++;
-	}
-	msi_desc[vector] = NULL;
+	msi_desc[irq] = NULL;
 	spin_unlock_irqrestore(&msi_lock, flags);
 
-	kmem_cache_free(msi_cachep, entry);
+	destroy_msi_irq(irq);
 
 	if (type == PCI_CAP_ID_MSIX) {
-		if (!reassign)
-			writel(1, base +
-				entry_nr * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+		writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
+			PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
 
-		if (head == vector)
+		if (head == irq)
 			iounmap(base);
 	}
 
 	return 0;
 }
 
-static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
-{
-	int vector = head, tail = 0;
-	int i, j = 0, nr_entries = 0;
-	void __iomem *base;
-	unsigned long flags;
-
-	spin_lock_irqsave(&msi_lock, flags);
-	while (head != tail) {
-		nr_entries++;
-		tail = msi_desc[vector]->link.tail;
-		if (entries[0].entry == msi_desc[vector]->msi_attrib.entry_nr)
-			j = vector;
-		vector = tail;
-	}
-	if (*nvec > nr_entries) {
-		spin_unlock_irqrestore(&msi_lock, flags);
-		*nvec = nr_entries;
-		return -EINVAL;
-	}
-	vector = ((j > 0) ? j : head);
-	for (i = 0; i < *nvec; i++) {
-		j = msi_desc[vector]->msi_attrib.entry_nr;
-		msi_desc[vector]->msi_attrib.state = 0;	/* Mark it not active */
-		vector_irq[vector] = -1;		/* Mark it busy */
-		nr_released_vectors--;
-		entries[i].vector = vector;
-		if (j != (entries + i)->entry) {
-			base = msi_desc[vector]->mask_base;
-			msi_desc[vector]->msi_attrib.entry_nr =
-				(entries + i)->entry;
-			writel( readl(base + j * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET), base +
-				(entries + i)->entry * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-			writel(	readl(base + j * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET), base +
-				(entries + i)->entry * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-			writel( (readl(base + j * PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_DATA_OFFSET) & 0xff00) | vector,
-				base + (entries+i)->entry*PCI_MSIX_ENTRY_SIZE +
-				PCI_MSIX_ENTRY_DATA_OFFSET);
-		}
-		vector = msi_desc[vector]->link.tail;
-	}
-	spin_unlock_irqrestore(&msi_lock, flags);
-
-	return 0;
-}
-
 /**
  * pci_enable_msix - configure device's MSI-X capability structure
  * @dev: pointer to the pci_dev data structure of MSI-X device function
  * @entries: pointer to an array of MSI-X entries
- * @nvec: number of MSI-X vectors requested for allocation by device driver
+ * @nvec: number of MSI-X irqs requested for allocation by device driver
  *
  * Setup the MSI-X capability structure of device function with the number
- * of requested vectors upon its software driver call to request for
+ * of requested irqs upon its software driver call to request for
  * MSI-X mode enabled on its hardware device function. A return of zero
  * indicates the successful configuration of MSI-X capability structure
- * with new allocated MSI-X vectors. A return of < 0 indicates a failure.
+ * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
  * Or a return of > 0 indicates that driver request is exceeding the number
- * of vectors available. Driver should use the returned value to re-send
+ * of irqs available. Driver should use the returned value to re-send
  * its request.
  **/
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 {
-	int status, pos, nr_entries, free_vectors;
+	int status, pos, nr_entries;
 	int i, j, temp;
 	u16 control;
-	unsigned long flags;
 
 	if (!entries || pci_msi_supported(dev) < 0)
  		return -EINVAL;
@@ -1163,9 +807,6 @@
  		return -EINVAL;
 
 	pci_read_config_word(dev, msi_control_reg(pos), &control);
-	if (control & PCI_MSIX_FLAGS_ENABLE)
-		return -EINVAL;			/* Already in MSI-X mode */
-
 	nr_entries = multi_msix_capable(control);
 	if (nvec > nr_entries)
 		return -EINVAL;
@@ -1180,56 +821,18 @@
 		}
 	}
 	temp = dev->irq;
-	if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-		/* Lookup Sucess */
-		nr_entries = nvec;
-		/* Reroute MSI-X table */
-		if (reroute_msix_table(dev->irq, entries, &nr_entries)) {
-			/* #requested > #previous-assigned */
-			dev->irq = temp;
-			return nr_entries;
-		}
-		dev->irq = temp;
-		enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
-		return 0;
-	}
-	/* Check whether driver already requested for MSI vector */
+	WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX));
+
+	/* Check whether driver already requested for MSI irq */
    	if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
-		!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
+		!msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
 		printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
-		       "Device already has an MSI vector assigned\n",
+		       "Device already has an MSI irq assigned\n",
 		       pci_name(dev));
 		dev->irq = temp;
 		return -EINVAL;
 	}
-
-	spin_lock_irqsave(&msi_lock, flags);
-	/*
-	 * msi_lock is provided to ensure that enough vectors resources are
-	 * available before granting.
-	 */
-	free_vectors = pci_vector_resources(last_alloc_vector,
-				nr_released_vectors);
-	/* Ensure that each MSI/MSI-X device has one vector reserved by
-	   default to avoid any MSI-X driver to take all available
- 	   resources */
-	free_vectors -= nr_reserved_vectors;
-	/* Find the average of free vectors among MSI-X devices */
-	if (nr_msix_devices > 0)
-		free_vectors /= nr_msix_devices;
-	spin_unlock_irqrestore(&msi_lock, flags);
-
-	if (nvec > free_vectors) {
-		if (free_vectors > 0)
-			return free_vectors;
-		else
-			return -EBUSY;
-	}
-
 	status = msix_capability_init(dev, entries, nvec);
-	if (!status && nr_msix_devices > 0)
-		nr_msix_devices--;
-
 	return status;
 }
 
@@ -1251,53 +854,47 @@
 	if (!(control & PCI_MSIX_FLAGS_ENABLE))
 		return;
 
+	disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
+
 	temp = dev->irq;
-	if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-		int state, vector, head, tail = 0, warning = 0;
+	if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
+		int irq, head, tail = 0, warning = 0;
 		unsigned long flags;
 
-		vector = head = dev->irq;
-		spin_lock_irqsave(&msi_lock, flags);
+		irq = head = dev->irq;
+		dev->irq = temp;			/* Restore pin IRQ */
 		while (head != tail) {
-			state = msi_desc[vector]->msi_attrib.state;
-			if (state)
+			spin_lock_irqsave(&msi_lock, flags);
+			tail = msi_desc[irq]->link.tail;
+			spin_unlock_irqrestore(&msi_lock, flags);
+			if (irq_has_action(irq))
 				warning = 1;
-			else {
-				vector_irq[vector] = 0; /* free it */
-				nr_released_vectors++;
-			}
-			tail = msi_desc[vector]->link.tail;
-			vector = tail;
+			else if (irq != head)	/* Release MSI-X irq */
+				msi_free_irq(dev, irq);
+			irq = tail;
 		}
-		spin_unlock_irqrestore(&msi_lock, flags);
+		msi_free_irq(dev, irq);
 		if (warning) {
-			dev->irq = temp;
 			printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
-			       "free_irq() on all MSI-X vectors\n",
+			       "free_irq() on all MSI-X irqs\n",
 			       pci_name(dev));
 			BUG_ON(warning > 0);
-		} else {
-			dev->irq = temp;
-			disable_msi_mode(dev,
-				pci_find_capability(dev, PCI_CAP_ID_MSIX),
-				PCI_CAP_ID_MSIX);
-
 		}
 	}
 }
 
 /**
- * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
+ * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state
  * @dev: pointer to the pci_dev data structure of MSI(X) device function
  *
  * Being called during hotplug remove, from which the device function
- * is hot-removed. All previous assigned MSI/MSI-X vectors, if
+ * is hot-removed. All previous assigned MSI/MSI-X irqs, if
  * allocated for this device function, are reclaimed to unused state,
  * which may be used later on.
  **/
 void msi_remove_pci_irq_vectors(struct pci_dev* dev)
 {
-	int state, pos, temp;
+	int pos, temp;
 	unsigned long flags;
 
 	if (!pci_msi_enable || !dev)
@@ -1305,42 +902,38 @@
 
 	temp = dev->irq;		/* Save IOAPIC IRQ */
 	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-	if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
-		spin_lock_irqsave(&msi_lock, flags);
-		state = msi_desc[dev->irq]->msi_attrib.state;
-		spin_unlock_irqrestore(&msi_lock, flags);
-		if (state) {
+	if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
+		if (irq_has_action(dev->irq)) {
 			printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
-			       "called without free_irq() on MSI vector %d\n",
+			       "called without free_irq() on MSI irq %d\n",
 			       pci_name(dev), dev->irq);
-			BUG_ON(state > 0);
-		} else /* Release MSI vector assigned to this device */
-			msi_free_vector(dev, dev->irq, 0);
+			BUG_ON(irq_has_action(dev->irq));
+		} else /* Release MSI irq assigned to this device */
+			msi_free_irq(dev, dev->irq);
 		dev->irq = temp;		/* Restore IOAPIC IRQ */
 	}
 	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-		int vector, head, tail = 0, warning = 0;
+	if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
+		int irq, head, tail = 0, warning = 0;
 		void __iomem *base = NULL;
 
-		vector = head = dev->irq;
+		irq = head = dev->irq;
 		while (head != tail) {
 			spin_lock_irqsave(&msi_lock, flags);
-			state = msi_desc[vector]->msi_attrib.state;
-			tail = msi_desc[vector]->link.tail;
-			base = msi_desc[vector]->mask_base;
+			tail = msi_desc[irq]->link.tail;
+			base = msi_desc[irq]->mask_base;
 			spin_unlock_irqrestore(&msi_lock, flags);
-			if (state)
+			if (irq_has_action(irq))
 				warning = 1;
-			else if (vector != head) /* Release MSI-X vector */
-				msi_free_vector(dev, vector, 0);
-			vector = tail;
+			else if (irq != head) /* Release MSI-X irq */
+				msi_free_irq(dev, irq);
+			irq = tail;
 		}
-		msi_free_vector(dev, vector, 0);
+		msi_free_irq(dev, irq);
 		if (warning) {
 			iounmap(base);
 			printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
-			       "called without free_irq() on all MSI-X vectors\n",
+			       "called without free_irq() on all MSI-X irqs\n",
 			       pci_name(dev));
 			BUG_ON(warning > 0);
 		}
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 56951c3..f0cca17 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -7,84 +7,6 @@
 #define MSI_H
 
 /*
- * MSI operation vector.  Used by the msi core code (drivers/pci/msi.c)
- * to abstract platform-specific tasks relating to MSI address generation
- * and resource management.
- */
-struct msi_ops {
-	/**
-	 * setup - generate an MSI bus address and data for a given vector
-	 * @pdev: PCI device context (in)
-	 * @vector: vector allocated by the msi core (in)
-	 * @addr_hi: upper 32 bits of PCI bus MSI address (out)
-	 * @addr_lo: lower 32 bits of PCI bus MSI address (out)
-	 * @data: MSI data payload (out)
-	 *
-	 * Description: The setup op is used to generate a PCI bus addres and
-	 * data which the msi core will program into the card MSI capability
-	 * registers.  The setup routine is responsible for picking an initial
-	 * cpu to target the MSI at.  The setup routine is responsible for
-	 * examining pdev to determine the MSI capabilities of the card and
-	 * generating a suitable address/data.  The setup routine is
-	 * responsible for allocating and tracking any system resources it
-	 * needs to route the MSI to the cpu it picks, and for associating
-	 * those resources with the passed in vector.
-	 *
-	 * Returns 0 if the MSI address/data was successfully setup.
-	 **/
-
-	int	(*setup)    (struct pci_dev *pdev, unsigned int vector,
-			     u32 *addr_hi, u32 *addr_lo, u32 *data);
-
-	/**
-	 * teardown - release resources allocated by setup
-	 * @vector: vector context for resources (in)
-	 *
-	 * Description:  The teardown op is used to release any resources
-	 * that were allocated in the setup routine associated with the passed
-	 * in vector.
-	 **/
-
-	void	(*teardown) (unsigned int vector);
-
-	/**
-	 * target - retarget an MSI at a different cpu
-	 * @vector: vector context for resources (in)
-	 * @cpu:  new cpu to direct vector at (in)
-	 * @addr_hi: new value of PCI bus upper 32 bits (in/out)
-	 * @addr_lo: new value of PCI bus lower 32 bits (in/out)
-	 *
-	 * Description:  The target op is used to redirect an MSI vector
-	 * at a different cpu.  addr_hi/addr_lo coming in are the existing
-	 * values that the MSI core has programmed into the card.  The
-	 * target code is responsible for freeing any resources (if any)
-	 * associated with the old address, and generating a new PCI bus
-	 * addr_hi/addr_lo that will redirect the vector at the indicated cpu.
-	 **/
-
-	void	(*target)   (unsigned int vector, unsigned int cpu,
-			     u32 *addr_hi, u32 *addr_lo);
-};
-
-extern int msi_register(struct msi_ops *ops);
-
-#include <asm/msi.h>
-
-/*
- * Assume the maximum number of hot plug slots supported by the system is about
- * ten. The worstcase is that each of these slots is hot-added with a device,
- * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which
- * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined
- * as below to ensure at least one message is assigned to each detected MSI/
- * MSI-X device function.
- */
-#define NR_HP_RESERVED_VECTORS 	20
-
-extern int vector_irq[NR_VECTORS];
-extern void (*interrupt[NR_IRQS])(void);
-extern int pci_vector_resources(int last, int nr_released);
-
-/*
  * MSI-X Address Register
  */
 #define PCI_MSIX_FLAGS_QSIZE		0x7FF
@@ -110,8 +32,8 @@
 	(1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
 #define multi_msi_enable(control, num) \
 	control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
-#define is_64bit_address(control)	(control & PCI_MSI_FLAGS_64BIT)
-#define is_mask_bit_support(control)	(control & PCI_MSI_FLAGS_MASKBIT)
+#define is_64bit_address(control)	(!!(control & PCI_MSI_FLAGS_64BIT))
+#define is_mask_bit_support(control)	(!!(control & PCI_MSI_FLAGS_MASKBIT))
 #define msi_enable(control, num) multi_msi_enable(control, num); \
 	control |= PCI_MSI_FLAGS_ENABLE
 
@@ -125,32 +47,4 @@
 #define msix_mask(address)		(address | PCI_MSIX_FLAGS_BITMASK)
 #define msix_is_pending(address) 	(address & PCI_MSIX_FLAGS_PENDMASK)
 
-struct msi_desc {
-	struct {
-		__u8	type	: 5; 	/* {0: unused, 5h:MSI, 11h:MSI-X} */
-		__u8	maskbit	: 1; 	/* mask-pending bit supported ?   */
-		__u8	state	: 1; 	/* {0: free, 1: busy}		  */
-		__u8	reserved: 1; 	/* reserved			  */
-		__u8	entry_nr;    	/* specific enabled entry 	  */
-		__u8	default_vector; /* default pre-assigned vector    */
-		__u8	unused; 	/* formerly unused destination cpu*/
-	}msi_attrib;
-
-	struct {
-		__u16	head;
-		__u16	tail;
-	}link;
-
-	void __iomem *mask_base;
-	struct pci_dev *dev;
-
-#ifdef CONFIG_PM
-	/* PM save area for MSIX address/data */
-
-	u32	address_hi_save;
-	u32	address_lo_save;
-	u32	data_save;
-#endif
-};
-
 #endif /* MSI_H */
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 5440491..8f7bcf5 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -55,16 +55,16 @@
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u16 class = dev->class >> 8;
 
-		/* Don't touch classless devices or host bridges. */
+		/* Don't touch classless devices or host bridges or ioapics.  */
 		if (class == PCI_CLASS_NOT_DEFINED ||
 		    class == PCI_CLASS_BRIDGE_HOST)
 			continue;
 
-		/* Don't touch ioapics if it has the assigned resources. */
+		/* Don't touch ioapic devices already enabled by firmware */
 		if (class == PCI_CLASS_SYSTEM_PIC) {
-			res = &dev->resource[0];
-			if (res[0].start || res[1].start || res[2].start ||
-			    res[3].start || res[4].start || res[5].start)
+			u16 command;
+			pci_read_config_word(dev, PCI_COMMAND, &command);
+			if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
 				continue;
 		}
 
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index f2e0179..3ac5b12 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -1049,6 +1049,10 @@
 		printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
 		return 0;
 	}
+#ifdef CONFIG_PPC_MERGE
+	if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
+		return -EINVAL;
+#endif
 #ifdef ISAPNP_REGION_OK
 	if (!request_region(_PIDXR, 1, "isapnp index")) {
 		printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR);
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 0b2d2c3..4142115 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -15,4 +15,4 @@
 	default "30"
 	---help---
 	  Amount of time a discovery node waits for a host to complete
-	  enumeration beforing giving up.
+	  enumeration before giving up.
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index cc5032b..3f0f7b8 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -141,9 +141,9 @@
 
 	dev_dbg(dev, "%s secs=%d, mins=%d, "
 		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
-		"write", dt->tm_sec, dt->tm_min,
-		dt->tm_hour, dt->tm_mday,
-		dt->tm_mon, dt->tm_year, dt->tm_wday);
+		"write", t->tm_sec, t->tm_min,
+		t->tm_hour, t->tm_mday,
+		t->tm_mon, t->tm_year, t->tm_wday);
 
 	*buf++ = 0;		/* first register addr */
 	buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec);
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 9c68ec9..67e816a 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -55,7 +55,7 @@
 	}
 
 	dev_dbg(&client->dev,
-		"%s: raw read data - counters=%02x,%02x,%02x,%02x\n"
+		"%s: raw read data - counters=%02x,%02x,%02x,%02x\n",
 		__FUNCTION__, buf[0], buf[1], buf[2], buf[3]);
 
 	time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
@@ -96,7 +96,7 @@
 	unsigned long secs;
 
 	dev_dbg(&client->dev,
-		"%s: secs=%d, mins=%d, hours=%d, ",
+		"%s: secs=%d, mins=%d, hours=%d, "
 		"mday=%d, mon=%d, year=%d, wday=%d\n",
 		__FUNCTION__,
 		tm->tm_sec, tm->tm_min, tm->tm_hour,
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 9eeef96..2f0b777 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -1,4 +1,4 @@
-/* drivers/char/max6902.c
+/* drivers/rtc/rtc-max6902.c
  *
  * Copyright (C) 2006 8D Technologies inc.
  * Copyright (C) 2004 Compulab Ltd.
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index bbdad09..2a86632 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -91,7 +91,7 @@
 	unsigned char buf[8] = { RS5C372_REG_BASE };
 
 	dev_dbg(&client->dev,
-		"%s: secs=%d, mins=%d, hours=%d ",
+		"%s: secs=%d, mins=%d, hours=%d "
 		"mday=%d, mon=%d, year=%d, wday=%d\n",
 		__FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour,
 		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
@@ -126,7 +126,7 @@
 		return -EIO;
 	}
 
-	dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, trim);
+	dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim);
 
 	if (osc)
 		*osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768;
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 2fa566f..d7de175d 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -1103,7 +1103,7 @@
 	}
 }
 
-static struct tty_operations tty3215_ops = {
+static const struct tty_operations tty3215_ops = {
 	.open = tty3215_open,
 	.close = tty3215_close,
 	.write = tty3215_write,
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index b4557fa..78f8bda 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -27,7 +27,7 @@
 
 struct fs3270 {
 	struct raw3270_view view;
-	pid_t fs_pid;			/* Pid of controlling program. */
+	struct pid *fs_pid;		/* Pid of controlling program. */
 	int read_command;		/* ccw command to use for reads. */
 	int write_command;		/* ccw command to use for writes. */
 	int attention;			/* Got attention. */
@@ -102,7 +102,7 @@
 	fp = (struct fs3270 *) rq->view;
 	if (rq->rc != 0 || rq->rescnt != 0) {
 		if (fp->fs_pid)
-			kill_proc(fp->fs_pid, SIGHUP, 1);
+			kill_pid(fp->fs_pid, SIGHUP, 1);
 	}
 	fp->rdbuf_size = 0;
 	raw3270_request_reset(rq);
@@ -173,7 +173,7 @@
 	 */
 	if (rq->rc != 0 || rq->rescnt == 0) {
 		if (fp->fs_pid)
-			kill_proc(fp->fs_pid, SIGHUP, 1);
+			kill_pid(fp->fs_pid, SIGHUP, 1);
 		fp->rdbuf_size = 0;
 	} else
 		fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
@@ -442,7 +442,7 @@
 		return PTR_ERR(fp);
 
 	init_waitqueue_head(&fp->wait);
-	fp->fs_pid = current->pid;
+	fp->fs_pid = get_pid(task_pid(current));
 	rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
 	if (rc) {
 		fs3270_free_view(&fp->view);
@@ -480,7 +480,8 @@
 	fp = filp->private_data;
 	filp->private_data = NULL;
 	if (fp) {
-		fp->fs_pid = 0;
+		put_pid(fp->fs_pid);
+		fp->fs_pid = NULL;
 		raw3270_reset(&fp->view);
 		raw3270_put_view(&fp->view);
 		raw3270_del_view(&fp->view);
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index f6cf902..6f43e04d 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -711,7 +711,7 @@
 	.receiver_fn = sclp_tty_receiver
 };
 
-static struct tty_operations sclp_ops = {
+static const struct tty_operations sclp_ops = {
 	.open = sclp_tty_open,
 	.close = sclp_tty_close,
 	.write = sclp_tty_write,
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 54fba6f..723bf41 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -655,7 +655,7 @@
 	return 0;
 }
 
-static struct tty_operations sclp_vt220_ops = {
+static const struct tty_operations sclp_vt220_ops = {
 	.open = sclp_vt220_open,
 	.close = sclp_vt220_close,
 	.write = sclp_vt220_write,
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 06e2eee..4717c36 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1737,7 +1737,7 @@
 	return kbd_ioctl(tp->kbd, file, cmd, arg);
 }
 
-static struct tty_operations tty3270_ops = {
+static const struct tty_operations tty3270_ops = {
 	.open = tty3270_open,
 	.close = tty3270_close,
 	.write = tty3270_write,
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 479364d..e088b5e 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -208,7 +208,7 @@
 		 */
 		__ctl_clear_bit(14, 24);	/* Disable WARNING MCH */
 		if (xchg(&mchchk_wng_posted, 1) == 0)
-			kill_proc(1, SIGPWR, 1);
+			kill_cad_pid(SIGPWR, 1);
 	}
 #endif
 
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index 4fdb2c9..a305d40 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -2187,7 +2187,7 @@
 #endif
 }
 
-static struct tty_operations aurora_ops = {
+static const struct tty_operations aurora_ops = {
 	.open  = aurora_open,
 	.close = aurora_close,
 	.write = aurora_write,
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index 1cc706e..d27e4f6 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -4,9 +4,6 @@
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
  */
 
-#define __KERNEL_SYSCALLS__
-static int errno;
-
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/sched.h>
@@ -200,7 +197,7 @@
 	printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n");
 
 	shutting_down = 1;
-	if (execve("/sbin/shutdown", argv, envp) < 0)
+	if (kernel_execve("/sbin/shutdown", argv, envp) < 0)
 		printk(KERN_CRIT "envctrl: shutdown execution failed\n");
 }
 
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index 836a58b..40b6fc86 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -10,8 +10,6 @@
  * 			timer interrupts.  We use a timer to periodically 
  * 			reset 'stopped' watchdogs on affected platforms.
  *
- * TODO:	DevFS support (/dev/watchdogs/0 ... /dev/watchdogs/2)
- *
  * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
  */
 
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 063e676..728a133 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -19,9 +19,6 @@
  *              Daniele Bellucci <bellucda@tiscali.it>
  */
 
-#define __KERNEL_SYSCALLS__
-static int errno;
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
@@ -976,13 +973,15 @@
 		"HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
 	char *argv[] = { 
 		"/sbin/shutdown", "-h", "now", NULL };	
+	int ret;
 
 	if (inprog != 0)
 		return;
 
 	inprog = 1;
 	printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n");
-	if (0 > execve("/sbin/shutdown", argv, envp)) {
+	ret = kernel_execve("/sbin/shutdown", argv, envp);
+	if (ret < 0) {
 		printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); 
 		inprog = 0;  /* unlikely to succeed, but we could try again */
 	}
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index dab0820..c6dfb6fa 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -40,10 +40,10 @@
 	default y
 	---help---
 	  This option enables support for the various files in
-	  /proc/scsi.  In Linux 2.6 this has been superceeded by
+	  /proc/scsi.  In Linux 2.6 this has been superseded by
 	  files in sysfs but many legacy applications rely on this.
 
-	  If unusure say Y.
+	  If unsure say Y.
 
 comment "SCSI support type (disk, tape, CD-ROM)"
 	depends on SCSI
@@ -85,7 +85,7 @@
 	tristate "SCSI OnStream SC-x0 tape support"
 	depends on SCSI
 	---help---
-	  The OnStream SC-x0 SCSI tape drives can not be driven by the
+	  The OnStream SC-x0 SCSI tape drives cannot be driven by the
 	  standard st driver, but instead need this special osst driver and
 	  use the  /dev/osstX char device nodes (major 206).  Via usb-storage
 	  and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx
index 7955ebe..911ea17 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic79xx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx
@@ -22,12 +22,12 @@
 	to be used for any device.  The aic7xxx driver will automatically
 	vary this number based on device behavior.  For devices with a
 	fixed maximum, the driver will eventually lock to this maximum
-	and display a console message inidicating this value.
+	and display a console message indicating this value.
 
 	Due to resource allocation issues in the Linux SCSI mid-layer, using
 	a high number of commands per device may result in memory allocation
 	failures when many devices are attached to the system.  For this reason,
-	the default is set to 32.  Higher values may result in higer performance
+	the default is set to 32.  Higher values may result in higher performance
 	on some devices.  The upper bound is 253.  0 disables tagged queueing.
 
 	Per device tag depth can be controlled via the kernel command line
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
index 5517da5..cd93f9a 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
@@ -27,12 +27,12 @@
 	to be used for any device.  The aic7xxx driver will automatically
 	vary this number based on device behavior.  For devices with a
 	fixed maximum, the driver will eventually lock to this maximum
-	and display a console message inidicating this value.
+	and display a console message indicating this value.
 
 	Due to resource allocation issues in the Linux SCSI mid-layer, using
 	a high number of commands per device may result in memory allocation
 	failures when many devices are attached to the system.  For this reason,
-	the default is set to 32.  Higher values may result in higer performance
+	the default is set to 32.  Higher values may result in higher performance
 	on some devices.  The upper bound is 253.  0 disables tagged queueing.
 
 	Per device tag depth can be controlled via the kernel command line
diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c
index a289401..4385e9e 100644
--- a/drivers/scsi/arm/arxescsi.c
+++ b/drivers/scsi/arm/arxescsi.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/drivers/scsi/arxescsi.c
+ * linux/drivers/scsi/arm/arxescsi.c
  *
  * Copyright (C) 1997-2000 Russell King, Stefan Hanske
  *
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index ae41064..1b53afb 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -933,8 +933,8 @@
 			ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
 			ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION);
 			sprintf(ae->un.OsNameVersion, "%s %s %s",
-				system_utsname.sysname, system_utsname.release,
-				system_utsname.version);
+				init_utsname()->sysname, init_utsname()->release,
+				init_utsname()->version);
 			len = strlen(ae->un.OsNameVersion);
 			len += (len & 3) ? (4 - (len & 3)) : 4;
 			ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
@@ -1052,7 +1052,7 @@
 							  size);
 				ae->ad.bits.AttrType = be16_to_cpu(HOST_NAME);
 				sprintf(ae->un.HostName, "%s",
-					system_utsname.nodename);
+					init_utsname()->nodename);
 				len = strlen(ae->un.HostName);
 				len += (len & 3) ? (4 - (len & 3)) : 4;
 				ae->ad.bits.AttrLen =
@@ -1140,7 +1140,7 @@
 
 	ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
 	if (ndlp) {
-		if (system_utsname.nodename[0] != '\0') {
+		if (init_utsname()->nodename[0] != '\0') {
 			lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);
 		} else {
 			mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 5743832..76d83ad 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/char/21285.c
+ * linux/drivers/serial/21285.c
  *
  * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
  *
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 993a702..bac853c 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -1378,7 +1378,7 @@
 #endif /* CONFIG_PM_LEGACY */
 
 
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index e80e70e..1b299e8 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -2424,7 +2424,7 @@
 */
 static	int	baud_idx;
 
-static struct tty_operations rs_360_ops = {
+static const struct tty_operations rs_360_ops = {
 	.owner = THIS_MODULE,
 	.open = rs_360_open,
 	.close = rs_360_close,
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0ae9ced..cc2a205 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -320,8 +320,8 @@
 
 	case UPIO_TSI:
 		if (offset == UART_IIR) {
-			tmp = readl((u32 *)(up->port.membase + UART_RX));
-			return (cpu_to_le32(tmp) >> 8) & 0xff;
+			tmp = readl(up->port.membase + (UART_IIR & ~3));
+			return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
 		} else
 			return readb(up->port.membase + offset);
 
@@ -1896,6 +1896,17 @@
 		serial_outp(up, UART_EFR, efr);
 	}
 
+#ifdef CONFIG_ARCH_OMAP15XX
+	/* Workaround to enable 115200 baud on OMAP1510 internal ports */
+	if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
+		if (baud == 115200) {
+			quot = 1;
+			serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
+		} else
+			serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
+	}
+#endif
+
 	if (up->capabilities & UART_NATSEMI) {
 		/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
 		serial_outp(up, UART_LCR, 0xe0);
@@ -1949,6 +1960,8 @@
 	case UPIO_AU:
 		size = 0x100000;
 		/* fall thru */
+	case UPIO_TSI:
+	case UPIO_MEM32:
 	case UPIO_MEM:
 		if (!up->port.mapbase)
 			break;
@@ -1984,6 +1997,8 @@
 	case UPIO_AU:
 		size = 0x100000;
 		/* fall thru */
+	case UPIO_TSI:
+	case UPIO_MEM32:
 	case UPIO_MEM:
 		if (!up->port.mapbase)
 			break;
@@ -2007,17 +2022,15 @@
 {
 	unsigned long start = UART_RSA_BASE << up->port.regshift;
 	unsigned int size = 8 << up->port.regshift;
-	int ret = 0;
+	int ret = -EINVAL;
 
 	switch (up->port.iotype) {
-	case UPIO_MEM:
-		ret = -EINVAL;
-		break;
-
 	case UPIO_HUB6:
 	case UPIO_PORT:
 		start += up->port.iobase;
-		if (!request_region(start, size, "serial-rsa"))
+		if (request_region(start, size, "serial-rsa"))
+			ret = 0;
+		else
 			ret = -EBUSY;
 		break;
 	}
@@ -2031,9 +2044,6 @@
 	unsigned int size = 8 << up->port.regshift;
 
 	switch (up->port.iotype) {
-	case UPIO_MEM:
-		break;
-
 	case UPIO_HUB6:
 	case UPIO_PORT:
 		release_region(up->port.iobase + offset, size);
@@ -2222,9 +2232,10 @@
 	/* Wait up to 1s for flow control if necessary */
 	if (up->port.flags & UPF_CONS_FLOW) {
 		tmout = 1000000;
-		while (--tmout &&
-		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+		while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
 			udelay(1);
+			touch_nmi_watchdog();
+		}
 	}
 }
 
@@ -2397,7 +2408,6 @@
 /**
  *	serial8250_suspend_port - suspend one serial port
  *	@line:  serial line number
- *      @level: the level of port suspension, as per uart_suspend_port
  *
  *	Suspend one serial port.
  */
@@ -2409,7 +2419,6 @@
 /**
  *	serial8250_resume_port - resume one serial port
  *	@line:  serial line number
- *      @level: the level of port resumption, as per uart_resume_port
  *
  *	Resume one serial port.
  */
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 1ebe6b5..c5d0add 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -22,7 +22,6 @@
 #include <asm/hardware.h>
 #include <asm/parisc-device.h>
 #include <asm/io.h>
-#include <asm/serial.h> /* for LASI_BASE_BAUD */
 
 #include "8250.h"
 
@@ -54,7 +53,8 @@
 
 	memset(&port, 0, sizeof(port));
 	port.iotype	= UPIO_MEM;
-	port.uartclk	= LASI_BASE_BAUD * 16;
+	/* 7.272727MHz on Lasi.  Assumed the same for Dino, Wax and Timi. */
+	port.uartclk	= 7272727;
 	port.mapbase	= address;
 	port.membase	= ioremap_nocache(address, 16);
 	port.irq	= dev->irq;
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 851e483..4d0ff8f 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1789,6 +1789,7 @@
 	pci_disable_device(dev);
 }
 
+#ifdef CONFIG_PM
 static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
 {
 	struct serial_private *priv = pci_get_drvdata(dev);
@@ -1818,6 +1819,7 @@
 	}
 	return 0;
 }
+#endif
 
 static struct pci_device_id serial_pci_tbl[] = {
 	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
@@ -2375,8 +2377,10 @@
 	.name		= "serial",
 	.probe		= pciserial_init_one,
 	.remove		= __devexit_p(pciserial_remove_one),
+#ifdef CONFIG_PM
 	.suspend	= pciserial_suspend_one,
 	.resume		= pciserial_resume_one,
+#endif
 	.id_table	= serial_pci_tbl,
 };
 
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 632f62d..71d907c 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -327,6 +327,19 @@
 	{	"WACF004",		0	},
 	{	"WACF005",		0	},
 	{       "WACF006",              0       },
+	/* Compaq touchscreen */
+	{       "FPI2002",              0 },
+	/* Fujitsu Stylistic touchscreens */
+	{       "FUJ02B2",              0 },
+	{       "FUJ02B3",              0 },
+	/* Fujitsu Stylistic LT touchscreens */
+	{       "FUJ02B4",              0 },
+	/* Passive Fujitsu Stylistic touchscreens */
+	{       "FUJ02B6",              0 },
+	{       "FUJ02B7",              0 },
+	{       "FUJ02B8",              0 },
+	{       "FUJ02B9",              0 },
+	{       "FUJ02BC",              0 },
 	/* Rockwell's (PORALiNK) 33600 INT PNP */
 	{	"WCI0003",		0	},
 	/* Unkown PnP modems */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d926272..8edee74 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -121,7 +121,7 @@
 	default "4"
 	help
 	  Set this to the maximum number of serial ports you want
-	  the kernel to register at boot time.  This can be overriden
+	  the kernel to register at boot time.  This can be overridden
 	  with the module parameter "nr_uarts", or boot-time parameter
 	  8250.nr_uarts
 
@@ -205,7 +205,7 @@
 	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
 	help
 	  Say Y here if you have a Boca serial board.  Please read the Boca
-	  mini-HOWTO, avaialble from <http://www.tldp.org/docs.html#howto>
+	  mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called 8250_boca.
@@ -556,10 +556,11 @@
 	default y
 	---help---
 	  Saying Y here will enable the hardware MUX serial driver for
-	  the Nova and K class systems.  The hardware MUX is not 8250/16550 
-	  compatible therefore the /dev/ttyB0 device is shared between the 
-	  Serial MUX and the PDC software console.  The following steps 
-	  need to be completed to use the Serial MUX:
+	  the Nova, K class systems and D class with a 'remote control card'.
+	  The hardware MUX is not 8250/16550 compatible therefore the
+	  /dev/ttyB0 device is shared between the Serial MUX and the PDC
+	  software console. The following steps need to be completed to use
+	  the Serial MUX:
 
 	    1. create the device entry (mknod /dev/ttyB0 c 11 0)
 	    2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
@@ -667,7 +668,7 @@
 	depends on M68328 || M68EZ328 || M68VZ328
 	help
 	  This driver supports the built-in serial port of the Motorola 68328
-	  (standard, EZ and VZ varities).
+	  (standard, EZ and VZ varieties).
 
 config SERIAL_68328_RTS_CTS
 	bool "Support RTS/CTS on 68328 serial port"
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 90ff96e..a0d6136 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -46,6 +46,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/delay.h>
+#include <asm/fs_pd.h>
 
 #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -1022,15 +1023,17 @@
 {
 	struct resource *r;
 	struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
-	int idx = pdata->fs_no;	/* It is UART_SMCx or UART_SCCx index */
+	int idx;	/* It is UART_SMCx or UART_SCCx index */
 	struct uart_cpm_port *pinfo;
 	int line;
 	u32 mem, pram;
 
+        idx = pdata->fs_no = fs_uart_get_id(pdata);
+
 	line = cpm_uart_id2nr(idx);
 	if(line < 0) {
 		printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
-		return -1;
+		return -EINVAL;
 	}
 
 	pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
@@ -1044,11 +1047,11 @@
 
 	if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
 		return -EINVAL;
-	mem = r->start;
+	mem = (u32)ioremap(r->start, r->end - r->start + 1);
 
 	if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
 		return -EINVAL;
-	pram = r->start;
+	pram = (u32)ioremap(r->start, r->end - r->start + 1);
 
 	if(idx > fsid_smc2_uart) {
 		pinfo->sccp = (scc_t *)mem;
@@ -1179,7 +1182,7 @@
 		pdata = pdev->dev.platform_data;
 		if (pdata)
 			if (pdata->init_ioports)
-    	                	pdata->init_ioports();
+    	                	pdata->init_ioports(pdata);
 
 		cpm_uart_drv_get_platform_data(pdev, 1);
 	}
@@ -1189,11 +1192,7 @@
 	if (options) {
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 	} else {
-		bd_t *bd = (bd_t *) __res;
-
-		if (bd->bi_baudrate)
-			baud = bd->bi_baudrate;
-		else
+		if ((baud = uart_baudrate()) == -1)
 			baud = 9600;
 	}
 
@@ -1266,13 +1265,14 @@
 	}
 
 	pdata = pdev->dev.platform_data;
-	pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
 
 	if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
 		return ret;
 
+	pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
+
 	if (pdata->init_ioports)
-                pdata->init_ioports();
+                pdata->init_ioports(pdata);
 
 	ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
 
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
index 5d867ab..5eb49ea 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/serial/cpm_uart_cpm1.h
+ * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h
  *
  * Driver for CPM (SCC/SMC) serial ports
  * 
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index ef3bb47..b691d3e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -40,6 +40,7 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/fs_pd.h>
 
 #include <linux/serial_core.h>
 #include <linux/kernel.h>
@@ -50,8 +51,9 @@
 
 void cpm_line_cr_cmd(int line, int cmd)
 {
-	volatile cpm_cpm2_t *cp = cpmp;
 	ulong val;
+	volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);
+
 
 	switch (line) {
 	case UART_SMC1:
@@ -84,11 +86,14 @@
 	}
 	cp->cp_cpcr = val;
 	while (cp->cp_cpcr & CPM_CR_FLG) ;
+
+	cpm2_unmap(cp);
 }
 
 void smc1_lineif(struct uart_cpm_port *pinfo)
 {
-	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+	volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
 	/* SMC1 is only on port D */
 	io->iop_ppard |= 0x00c00000;
@@ -97,13 +102,17 @@
 	io->iop_psord &= ~0x00c00000;
 
 	/* Wire BRG1 to SMC1 */
-	cpm2_immr->im_cpmux.cmx_smr &= 0x0f;
+	cpmux->cmx_smr &= 0x0f;
 	pinfo->brg = 1;
+
+	cpm2_unmap(cpmux);
+	cpm2_unmap(io);
 }
 
 void smc2_lineif(struct uart_cpm_port *pinfo)
 {
-	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+	volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
 	/* SMC2 is only on port A */
 	io->iop_ppara |= 0x00c00000;
@@ -112,13 +121,17 @@
 	io->iop_psora &= ~0x00c00000;
 
 	/* Wire BRG2 to SMC2 */
-	cpm2_immr->im_cpmux.cmx_smr &= 0xf0;
+	cpmux->cmx_smr &= 0xf0;
 	pinfo->brg = 2;
+
+	cpm2_unmap(cpmux);
+	cpm2_unmap(io);
 }
 
 void scc1_lineif(struct uart_cpm_port *pinfo)
 {
-	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+	volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
 	/* Use Port D for SCC1 instead of other functions.  */
 	io->iop_ppard |= 0x00000003;
@@ -128,9 +141,12 @@
 	io->iop_pdird |= 0x00000002;	/* Tx */
 
 	/* Wire BRG1 to SCC1 */
-	cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
-	cpm2_immr->im_cpmux.cmx_scr |= 0x00000000;
+	cpmux->cmx_scr &= 0x00ffffff;
+	cpmux->cmx_scr |= 0x00000000;
 	pinfo->brg = 1;
+
+	cpm2_unmap(cpmux);
+	cpm2_unmap(io);
 }
 
 void scc2_lineif(struct uart_cpm_port *pinfo)
@@ -143,43 +159,57 @@
 	 * be supported in a sane fashion.
 	 */
 #ifndef CONFIG_STX_GP3
-	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+	volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
 	io->iop_pparb |= 0x008b0000;
 	io->iop_pdirb |= 0x00880000;
 	io->iop_psorb |= 0x00880000;
 	io->iop_pdirb &= ~0x00030000;
 	io->iop_psorb &= ~0x00030000;
 #endif
-	cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
-	cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
+	cpmux->cmx_scr &= 0xff00ffff;
+	cpmux->cmx_scr |= 0x00090000;
 	pinfo->brg = 2;
+
+	cpm2_unmap(cpmux);
+	cpm2_unmap(io);
 }
 
 void scc3_lineif(struct uart_cpm_port *pinfo)
 {
-	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+	volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
 	io->iop_pparb |= 0x008b0000;
 	io->iop_pdirb |= 0x00880000;
 	io->iop_psorb |= 0x00880000;
 	io->iop_pdirb &= ~0x00030000;
 	io->iop_psorb &= ~0x00030000;
-	cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
-	cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
+	cpmux->cmx_scr &= 0xffff00ff;
+	cpmux->cmx_scr |= 0x00001200;
 	pinfo->brg = 3;
+
+	cpm2_unmap(cpmux);
+	cpm2_unmap(io);
 }
 
 void scc4_lineif(struct uart_cpm_port *pinfo)
 {
-	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+	volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
 	io->iop_ppard |= 0x00000600;
 	io->iop_psord &= ~0x00000600;	/* Tx/Rx */
 	io->iop_pdird &= ~0x00000200;	/* Rx */
 	io->iop_pdird |= 0x00000400;	/* Tx */
 
-	cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
-	cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
+	cpmux->cmx_scr &= 0xffffff00;
+	cpmux->cmx_scr |= 0x0000001b;
 	pinfo->brg = 4;
+
+	cpm2_unmap(cpmux);
+	cpm2_unmap(io);
 }
 
 /*
@@ -254,88 +284,103 @@
 /* Setup any dynamic params in the uart desc */
 int cpm_uart_init_portdesc(void)
 {
+#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
+	u32 addr;
+#endif
 	pr_debug("CPM uart[-]:init portdesc\n");
 
 	cpm_uart_nr = 0;
 #ifdef CONFIG_SERIAL_CPM_SMC1
-	cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0];
-	cpm_uart_ports[UART_SMC1].smcup =
-	    (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1];
-	*(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+	cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
 	cpm_uart_ports[UART_SMC1].port.mapbase =
-	    (unsigned long)&cpm2_immr->im_smc[0];
+	    (unsigned long)cpm_uart_ports[UART_SMC1].smcp;
+
+	cpm_uart_ports[UART_SMC1].smcup =
+	    (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE);
+	addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2);
+	*addr = PROFF_SMC1;
+	cpm2_unmap(addr);
+
 	cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
 	cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-	cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+	cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
 	cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SMC2
-	cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1];
-	cpm_uart_ports[UART_SMC2].smcup =
-	    (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2];
-	*(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
+	cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]);
 	cpm_uart_ports[UART_SMC2].port.mapbase =
-	    (unsigned long)&cpm2_immr->im_smc[1];
+	    (unsigned long)cpm_uart_ports[UART_SMC2].smcp;
+
+	cpm_uart_ports[UART_SMC2].smcup =
+	    (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE);
+	addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2);
+	*addr = PROFF_SMC2;
+	cpm2_unmap(addr);
+
 	cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
 	cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-	cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+	cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
 	cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC1
-	cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0];
-	cpm_uart_ports[UART_SCC1].sccup =
-	    (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1];
+	cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]);
 	cpm_uart_ports[UART_SCC1].port.mapbase =
-	    (unsigned long)&cpm2_immr->im_scc[0];
+	    (unsigned long)cpm_uart_ports[UART_SCC1].sccp;
+	cpm_uart_ports[UART_SCC1].sccup =
+	    (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE);
+
 	cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
 	    ~(UART_SCCM_TX | UART_SCCM_RX);
 	cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
 	    ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-	cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+	cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
 	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC2
-	cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1];
-	cpm_uart_ports[UART_SCC2].sccup =
-	    (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2];
+	cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]);
 	cpm_uart_ports[UART_SCC2].port.mapbase =
-	    (unsigned long)&cpm2_immr->im_scc[1];
+	    (unsigned long)cpm_uart_ports[UART_SCC2].sccp;
+	cpm_uart_ports[UART_SCC2].sccup =
+	    (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE);
+
 	cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
 	    ~(UART_SCCM_TX | UART_SCCM_RX);
 	cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
 	    ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-	cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+	cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
 	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC3
-	cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2];
-	cpm_uart_ports[UART_SCC3].sccup =
-	    (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3];
+	cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]);
 	cpm_uart_ports[UART_SCC3].port.mapbase =
-	    (unsigned long)&cpm2_immr->im_scc[2];
+	    (unsigned long)cpm_uart_ports[UART_SCC3].sccp;
+	cpm_uart_ports[UART_SCC3].sccup =
+	    (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE);
+
 	cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
 	    ~(UART_SCCM_TX | UART_SCCM_RX);
 	cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
 	    ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-	cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+	cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
 	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC4
-	cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3];
-	cpm_uart_ports[UART_SCC4].sccup =
-	    (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4];
+	cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]);
 	cpm_uart_ports[UART_SCC4].port.mapbase =
-	    (unsigned long)&cpm2_immr->im_scc[3];
+	    (unsigned long)cpm_uart_ports[UART_SCC4].sccp;
+	cpm_uart_ports[UART_SCC4].sccup =
+	    (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE);
+
 	cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
 	    ~(UART_SCCM_TX | UART_SCCM_RX);
 	cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
 	    ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-	cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+	cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
 	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
 #endif
 
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
index 4793fec..4b77911 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/serial/cpm_uart_cpm2.h
+ * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h
  *
  * Driver for CPM (SCC/SMC) serial ports
  * 
@@ -40,6 +40,6 @@
 	up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB;
 }
 
-#define DPRAM_BASE	((unsigned char *)&cpm2_immr->im_dprambase[0])
+#define DPRAM_BASE	((unsigned char *)cpm_dpram_addr(0))
 
 #endif
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index cabd048..9851d9e 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -4825,7 +4825,7 @@
 
 /* rs_init inits the driver at boot (using the module_init chain) */
 
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index e7fe4bb..28c9ce6 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -76,7 +76,7 @@
  */
 #define is_real_interrupt(irq)	((irq) != 0)
 
-#include <asm/serial.h>
+#define BASE_BAUD	115200
 
 /* Standard COM flags */
 #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
@@ -86,7 +86,6 @@
  * standard enumeration mechanism.   Platforms that can find all
  * serial ports via mechanisms like ACPI or PCI need not supply it.
  */
-#undef SERIAL_PORT_DFNS
 #if defined(CONFIG_PLAT_USRV)
 
 #define SERIAL_PORT_DFNS						\
@@ -109,7 +108,7 @@
 #endif /* !CONFIG_PLAT_USRV */
 
 static struct old_serial_port old_serial_port[] = {
-	SERIAL_PORT_DFNS	/* defined in asm/serial.h */
+	SERIAL_PORT_DFNS
 };
 
 #define UART_NR	ARRAY_SIZE(old_serial_port)
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 832abd3..00d7859 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -1666,7 +1666,7 @@
 	printk(mcfrs_drivername);
 }
 
-static struct tty_operations mcfrs_ops = {
+static const struct tty_operations mcfrs_ops = {
 	.open = mcfrs_open,
 	.close = mcfrs_close,
 	.write = mcfrs_write,
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 5f7ba1ad..c67b05e 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -792,6 +792,7 @@
 			 * We failed anyway.
 			 */
 			retval = -EBUSY;
+			goto exit;  // Added to return the correct error -Ram Gupta
 		}
 	}
 
@@ -1662,16 +1663,16 @@
 	struct uart_port *port = state->port;
 	char stat_buf[32];
 	unsigned int status;
-	int ret;
+	int mmio, ret;
 
 	if (!port)
 		return 0;
 
+	mmio = port->iotype >= UPIO_MEM;
 	ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d",
 			port->line, uart_type(port),
-			port->iotype == UPIO_MEM ? "mmio:0x" : "port:",
-			port->iotype == UPIO_MEM ? port->mapbase :
-						(unsigned long) port->iobase,
+			mmio ? "mmio:0x" : "port:",
+			mmio ? port->mapbase : (unsigned long) port->iobase,
 			port->irq);
 
 	if (port->type == PORT_UNKNOWN) {
@@ -1939,6 +1940,9 @@
 	if (state->info && state->info->flags & UIF_INITIALIZED) {
 		const struct uart_ops *ops = port->ops;
 
+		state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
+				     | UIF_SUSPENDED;
+
 		spin_lock_irq(&port->lock);
 		ops->stop_tx(port);
 		ops->set_mctrl(port, 0);
@@ -2005,7 +2009,7 @@
 		console_start(port->cons);
 	}
 
-	if (state->info && state->info->flags & UIF_INITIALIZED) {
+	if (state->info && state->info->flags & UIF_SUSPENDED) {
 		const struct uart_ops *ops = port->ops;
 		int ret;
 
@@ -2017,15 +2021,17 @@
 			ops->set_mctrl(port, port->mctrl);
 			ops->start_tx(port);
 			spin_unlock_irq(&port->lock);
+			state->info->flags |= UIF_INITIALIZED;
 		} else {
 			/*
 			 * Failed to resume - maybe hardware went away?
 			 * Clear the "initialized" flag so we won't try
 			 * to call the low level drivers shutdown method.
 			 */
-			state->info->flags &= ~UIF_INITIALIZED;
 			uart_shutdown(state);
 		}
+
+		state->info->flags &= ~UIF_SUSPENDED;
 	}
 
 	mutex_unlock(&state->mutex);
@@ -2111,7 +2117,7 @@
 	}
 }
 
-static struct tty_operations uart_ops = {
+static const struct tty_operations uart_ops = {
 	.open		= uart_open,
 	.close		= uart_close,
 	.write		= uart_write,
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index cbf260b..00f9ffd 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -80,23 +80,16 @@
 
 /* Table of multi-port card ID's */
 
-struct multi_id {
-	u_short manfid;
-	u_short prodid;
+struct serial_quirk {
+	unsigned int manfid;
+	unsigned int prodid;
 	int multi;		/* 1 = multifunction, > 1 = # ports */
+	void (*config)(struct pcmcia_device *);
+	void (*setup)(struct pcmcia_device *, struct uart_port *);
+	void (*wakeup)(struct pcmcia_device *);
+	int (*post)(struct pcmcia_device *);
 };
 
-static const struct multi_id multi_id[] = {
-	{ MANFID_OMEGA,   PRODID_OMEGA_QSP_100,         4 },
-	{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232,    2 },
-	{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
-	{ MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232,    4 },
-	{ MANFID_SOCKET,  PRODID_SOCKET_DUAL_RS232,     2 },
-	{ MANFID_INTEL,   PRODID_INTEL_DUAL_RS232,      2 },
-	{ MANFID_NATINST, PRODID_NATINST_QUAD_RS232,    4 }
-};
-#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
-
 struct serial_info {
 	struct pcmcia_device	*p_dev;
 	int			ndev;
@@ -107,6 +100,7 @@
 	int			c950ctrl;
 	dev_node_t		node[4];
 	int			line[4];
+	const struct serial_quirk *quirk;
 };
 
 struct serial_cfg_mem {
@@ -115,37 +109,165 @@
 	u_char buf[256];
 };
 
+/*
+ * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
+ * manfid 0x0160, 0x0104
+ * This card appears to have a 14.7456MHz clock.
+ */
+static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
+{
+	port->uartclk = 14745600;
+}
+
+static int quirk_post_ibm(struct pcmcia_device *link)
+{
+	conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
+	int last_ret, last_fn;
+
+	last_ret = pcmcia_access_configuration_register(link, &reg);
+	if (last_ret) {
+		last_fn = AccessConfigurationRegister;
+		goto cs_failed;
+	}
+	reg.Action = CS_WRITE;
+	reg.Value = reg.Value | 1;
+	last_ret = pcmcia_access_configuration_register(link, &reg);
+	if (last_ret) {
+		last_fn = AccessConfigurationRegister;
+		goto cs_failed;
+	}
+	return 0;
+
+ cs_failed:
+	cs_error(link, last_fn, last_ret);
+	return -ENODEV;
+}
+
+/*
+ * Nokia cards are not really multiport cards.  Shouldn't this
+ * be handled by setting the quirk entry .multi = 0 | 1 ?
+ */
+static void quirk_config_nokia(struct pcmcia_device *link)
+{
+	struct serial_info *info = link->priv;
+
+	if (info->multi > 1)
+		info->multi = 1;
+}
+
+static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
+{
+	struct serial_info *info = link->priv;
+
+	outb(12, info->c950ctrl + 1);
+}
+
+/* request_region? oxsemi branch does no request_region too... */
+/*
+ * This sequence is needed to properly initialize MC45 attached to OXCF950.
+ * I tried decreasing these msleep()s, but it worked properly (survived
+ * 1000 stop/start operations) with these timeouts (or bigger).
+ */
+static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
+{
+	struct serial_info *info = link->priv;
+	unsigned int ctrl = info->c950ctrl;
+
+	outb(0xA, ctrl + 1);
+	msleep(100);
+	outb(0xE, ctrl + 1);
+	msleep(300);
+	outb(0xC, ctrl + 1);
+	msleep(100);
+	outb(0xE, ctrl + 1);
+	msleep(200);
+	outb(0xF, ctrl + 1);
+	msleep(100);
+	outb(0xE, ctrl + 1);
+	msleep(100);
+	outb(0xC, ctrl + 1);
+}
+
+/*
+ * Socket Dual IO: this enables irq's for second port
+ */
+static void quirk_config_socket(struct pcmcia_device *link)
+{
+	struct serial_info *info = link->priv;
+
+	if (info->multi) {
+		link->conf.Present |= PRESENT_EXT_STATUS;
+		link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
+	}
+}
+
+static const struct serial_quirk quirks[] = {
+	{
+		.manfid	= 0x0160,
+		.prodid	= 0x0104,
+		.multi	= -1,
+		.setup	= quirk_setup_brainboxes_0104,
+	}, {
+		.manfid	= MANFID_IBM,
+		.prodid	= ~0,
+		.multi	= -1,
+		.post	= quirk_post_ibm,
+	}, {
+		.manfid	= MANFID_INTEL,
+		.prodid	= PRODID_INTEL_DUAL_RS232,
+		.multi	= 2,
+	}, {
+		.manfid	= MANFID_NATINST,
+		.prodid	= PRODID_NATINST_QUAD_RS232,
+		.multi	= 4,
+	}, {
+		.manfid	= MANFID_NOKIA,
+		.prodid	= ~0,
+		.multi	= -1,
+		.config	= quirk_config_nokia,
+	}, {
+		.manfid	= MANFID_OMEGA,
+		.prodid	= PRODID_OMEGA_QSP_100,
+		.multi	= 4,
+	}, {
+		.manfid	= MANFID_OXSEMI,
+		.prodid	= ~0,
+		.multi	= -1,
+		.wakeup	= quirk_wakeup_oxsemi,
+	}, {
+		.manfid	= MANFID_POSSIO,
+		.prodid	= PRODID_POSSIO_GCC,
+		.multi	= -1,
+		.wakeup	= quirk_wakeup_possio_gcc,
+	}, {
+		.manfid	= MANFID_QUATECH,
+		.prodid	= PRODID_QUATECH_DUAL_RS232,
+		.multi	= 2,
+	}, {
+		.manfid	= MANFID_QUATECH,
+		.prodid	= PRODID_QUATECH_DUAL_RS232_D1,
+		.multi	= 2,
+	}, {
+		.manfid	= MANFID_QUATECH,
+		.prodid	= PRODID_QUATECH_QUAD_RS232,
+		.multi	= 4,
+	}, {
+		.manfid	= MANFID_SOCKET,
+		.prodid	= PRODID_SOCKET_DUAL_RS232,
+		.multi	= 2,
+		.config	= quirk_config_socket,
+	}, {
+		.manfid	= MANFID_SOCKET,
+		.prodid	= ~0,
+		.multi	= -1,
+		.config	= quirk_config_socket,
+	}
+};
+
 
 static int serial_config(struct pcmcia_device * link);
 
 
-static void wakeup_card(struct serial_info *info)
-{
-	int ctrl = info->c950ctrl;
-
-	if (info->manfid == MANFID_OXSEMI) {
-		outb(12, ctrl + 1);
-	} else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
-		/* request_region? oxsemi branch does no request_region too... */
-		/* This sequence is needed to properly initialize MC45 attached to OXCF950.
-		 * I tried decreasing these msleep()s, but it worked properly (survived
-		 * 1000 stop/start operations) with these timeouts (or bigger). */
-		outb(0xA, ctrl + 1);
-		msleep(100);
-		outb(0xE, ctrl + 1);
-		msleep(300);
-		outb(0xC, ctrl + 1);
-		msleep(100);
-		outb(0xE, ctrl + 1);
-		msleep(200);
-		outb(0xF, ctrl + 1);
-		msleep(100);
-		outb(0xE, ctrl + 1);
-		msleep(100);
-		outb(0xC, ctrl + 1);
-	}
-}
-
 /*======================================================================
 
     After a card is removed, serial_remove() will unregister
@@ -185,14 +307,14 @@
 
 static int serial_resume(struct pcmcia_device *link)
 {
-	if (pcmcia_dev_present(link)) {
-		struct serial_info *info = link->priv;
-		int i;
+	struct serial_info *info = link->priv;
+	int i;
 
-		for (i = 0; i < info->ndev; i++)
-			serial8250_resume_port(info->line[i]);
-		wakeup_card(info);
-	}
+	for (i = 0; i < info->ndev; i++)
+		serial8250_resume_port(info->line[i]);
+
+	if (info->quirk && info->quirk->wakeup)
+		info->quirk->wakeup(link);
 
 	return 0;
 }
@@ -278,6 +400,10 @@
 	port.dev = &handle_to_dev(handle);
 	if (buggy_uart)
 		port.flags |= UPF_BUGGY_UART;
+
+	if (info->quirk && info->quirk->setup)
+		info->quirk->setup(handle, &port);
+
 	line = serial8250_register_port(&port);
 	if (line < 0) {
 		printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
@@ -433,6 +559,13 @@
 	}
 	if (info->multi && (info->manfid == MANFID_3COM))
 		link->conf.ConfigIndex &= ~(0x08);
+
+	/*
+	 * Apply any configuration quirks.
+	 */
+	if (info->quirk && info->quirk->config)
+		info->quirk->config(link);
+
 	i = pcmcia_request_configuration(link, &link->conf);
 	if (i != CS_SUCCESS) {
 		cs_error(link, RequestConfiguration, i);
@@ -521,11 +654,13 @@
 		cs_error(link, RequestIRQ, i);
 		link->irq.AssignedIRQ = 0;
 	}
-	/* Socket Dual IO: this enables irq's for second port */
-	if (info->multi && (info->manfid == MANFID_SOCKET)) {
-		link->conf.Present |= PRESENT_EXT_STATUS;
-		link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
-	}
+
+	/*
+	 * Apply any configuration quirks.
+	 */
+	if (info->quirk && info->quirk->config)
+		info->quirk->config(link);
+
 	i = pcmcia_request_configuration(link, &link->conf);
 	if (i != CS_SUCCESS) {
 		cs_error(link, RequestConfiguration, i);
@@ -550,17 +685,19 @@
 					link->irq.AssignedIRQ);
 		}
 		info->c950ctrl = base2;
-		wakeup_card(info);
+
+		/*
+		 * FIXME: We really should wake up the port prior to
+		 * handing it over to the serial layer.
+		 */
+		if (info->quirk && info->quirk->wakeup)
+			info->quirk->wakeup(link);
+
 		rc = 0;
 		goto free_cfg_mem;
 	}
 
 	setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
-	/* The Nokia cards are not really multiport cards */
-	if (info->manfid == MANFID_NOKIA) {
-		rc = 0;
-		goto free_cfg_mem;
-	}
 	for (i = 0; i < info->multi - 1; i++)
 		setup_serial(link, info, base2 + (8 * i),
 				link->irq.AssignedIRQ);
@@ -622,13 +759,16 @@
 	tuple->DesiredTuple = CISTPL_MANFID;
 	if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
 		info->manfid = parse->manfid.manf;
-		info->prodid = le16_to_cpu(buf[1]);
-		for (i = 0; i < MULTI_COUNT; i++)
-			if ((info->manfid == multi_id[i].manfid) &&
-			    (parse->manfid.card == multi_id[i].prodid))
+		info->prodid = parse->manfid.card;
+
+		for (i = 0; i < ARRAY_SIZE(quirks); i++)
+			if ((quirks[i].manfid == ~0 ||
+			     quirks[i].manfid == info->manfid) &&
+			    (quirks[i].prodid == ~0 ||
+			     quirks[i].prodid == info->prodid)) {
+				info->quirk = &quirks[i];
 				break;
-		if (i < MULTI_COUNT)
-			info->multi = multi_id[i].multi;
+			}
 	}
 
 	/* Another check for dual-serial cards: look for either serial or
@@ -648,6 +788,12 @@
 		}
 	}
 
+	/*
+	 * Apply any multi-port quirk.
+	 */
+	if (info->quirk && info->quirk->multi != -1)
+		info->multi = info->quirk->multi;
+
 	if (info->multi > 1)
 		multi_config(link);
 	else
@@ -656,21 +802,13 @@
 	if (info->ndev == 0)
 		goto failed;
 
-	if (info->manfid == MANFID_IBM) {
-		conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
-		last_ret = pcmcia_access_configuration_register(link, &reg);
-		if (last_ret) {
-			last_fn = AccessConfigurationRegister;
-			goto cs_failed;
-		}
-		reg.Action = CS_WRITE;
-		reg.Value = reg.Value | 1;
-		last_ret = pcmcia_access_configuration_register(link, &reg);
-		if (last_ret) {
-			last_fn = AccessConfigurationRegister;
-			goto cs_failed;
-		}
-	}
+	/*
+	 * Apply any post-init quirk.  FIXME: This should really happen
+	 * before we register the port, since it might already be in use.
+	 */
+	if (info->quirk && info->quirk->post)
+		if (info->quirk->post(link))
+			goto failed;
 
 	link->dev_node = &info->node[0];
 	kfree(cfg_mem);
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index b361669..ebd8d2b 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -990,7 +990,6 @@
 /**
  *	serial_txx9_suspend_port - suspend one serial port
  *	@line:  serial line number
- *      @level: the level of port suspension, as per uart_suspend_port
  *
  *	Suspend one serial port.
  */
@@ -1002,7 +1001,6 @@
 /**
  *	serial_txx9_resume_port - resume one serial port
  *	@line:  serial line number
- *      @level: the level of port resumption, as per uart_resume_port
  *
  *	Resume one serial port.
  */
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 5e8a276..622881f 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -1701,7 +1701,7 @@
 	spin_unlock_irqrestore(&zs_lock, flags);
 }
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig
index 550ddfa..b450cba 100644
--- a/drivers/usb/atm/Kconfig
+++ b/drivers/usb/atm/Kconfig
@@ -64,7 +64,7 @@
 	  Say Y here if you have a DSL USB modem not explicitly supported by
 	  another USB DSL drivers.  In order to use your modem you will need to
 	  pass the vendor ID, product ID, and endpoint numbers for transmission
-	  and reception as module parameters.  You may need to initialize the
+	  and reception as module parameters.  You may need to initialize
 	  the modem using a user space utility (a firmware loader for example).
 
 	  To compile this driver as a module, choose M here: the
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index ca90326..7128829 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1120,7 +1120,7 @@
  * TTY driver structures.
  */
 
-static struct tty_operations acm_ops = {
+static const struct tty_operations acm_ops = {
 	.open =			acm_tty_open,
 	.close =		acm_tty_close,
 	.write =		acm_tty_write,
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index a94c63b..3f509be 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -65,7 +65,7 @@
 struct async {
 	struct list_head asynclist;
 	struct dev_state *ps;
-	pid_t pid;
+	struct pid *pid;
 	uid_t uid, euid;
 	unsigned int signr;
 	unsigned int ifnum;
@@ -225,6 +225,7 @@
 
 static void free_async(struct async *as)
 {
+	put_pid(as->pid);
 	kfree(as->urb->transfer_buffer);
 	kfree(as->urb->setup_packet);
 	usb_free_urb(as->urb);
@@ -317,7 +318,7 @@
 		sinfo.si_errno = as->urb->status;
 		sinfo.si_code = SI_ASYNCIO;
 		sinfo.si_addr = as->userurb;
-		kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, 
+		kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
 				      as->euid, as->secid);
 	}
 	snoop(&urb->dev->dev, "urb complete\n");
@@ -573,7 +574,7 @@
 	INIT_LIST_HEAD(&ps->async_completed);
 	init_waitqueue_head(&ps->wait);
 	ps->discsignr = 0;
-	ps->disc_pid = current->pid;
+	ps->disc_pid = get_pid(task_pid(current));
 	ps->disc_uid = current->uid;
 	ps->disc_euid = current->euid;
 	ps->disccontext = NULL;
@@ -611,6 +612,7 @@
 	usb_autosuspend_device(dev, 1);
 	usb_unlock_device(dev);
 	usb_put_dev(dev);
+	put_pid(ps->disc_pid);
 	kfree(ps);
 	return 0;
 }
@@ -1063,7 +1065,7 @@
 		as->userbuffer = NULL;
 	as->signr = uurb->signr;
 	as->ifnum = ifnum;
-	as->pid = current->pid;
+	as->pid = get_pid(task_pid(current));
 	as->uid = current->uid;
 	as->euid = current->euid;
 	security_task_getsecid(current, &as->secid);
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index c376c65..f794f07 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -1,5 +1,5 @@
 /*
- * drivers/usb/file.c
+ * drivers/usb/core/file.c
  *
  * (C) Copyright Linus Torvalds 1999
  * (C) Copyright Johannes Erdfelt 1999-2001
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 37f9f5e7..e658089 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -318,8 +318,8 @@
 
  	// id 3 == vendor description
 	} else if (id == 3) {
-		snprintf (buf, sizeof buf, "%s %s %s", system_utsname.sysname,
-			system_utsname.release, hcd->driver->description);
+		snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname,
+			init_utsname()->release, hcd->driver->description);
 
 	// unsupported IDs --> "protocol stall"
 	} else
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 7c77c2d..b5d6a79 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -699,7 +699,7 @@
 			sinfo.si_errno = EPIPE;
 			sinfo.si_code = SI_ASYNCIO;
 			sinfo.si_addr = ds->disccontext;
-			kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
+			kill_pid_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
 		}
 	}
 }
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index e4df9ed..467cb02 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1,5 +1,5 @@
 /*
- * drivers/usb/usb.c
+ * drivers/usb/core/usb.c
  *
  * (C) Copyright Linus Torvalds 1999
  * (C) Copyright Johannes Erdfelt 1999-2001
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index f69df13..13322e3 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -139,7 +139,7 @@
 	struct list_head async_completed;
 	wait_queue_head_t wait;     /* wake up if a request completed */
 	unsigned int discsignr;
-	pid_t disc_pid;
+	struct pid *disc_pid;
 	uid_t disc_uid, disc_euid;
 	void __user *disccontext;
 	unsigned long ifclaimed;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 8e5dd6f..bbbc82a 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -7,7 +7,7 @@
 #
 #  - Host systems (like PCs) need CONFIG_USB (with "A" jacks).
 #  - Peripherals (like PDAs) need CONFIG_USB_GADGET (with "B" jacks).
-#  - Some systems have both kinds of of controller.
+#  - Some systems have both kinds of controllers.
 #
 # With help from a special transceiver and a "Mini-AB" jack, systems with
 # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG).
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 366dc0a..1c17d26 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2260,7 +2260,7 @@
 		return -ENODEV;
 	}
 	snprintf (manufacturer, sizeof manufacturer, "%s %s/%s",
-		system_utsname.sysname, system_utsname.release,
+		init_utsname()->sysname, init_utsname()->release,
 		gadget->name);
 
 	/* If there's an RNDIS configuration, that's what Windows wants to
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c83d3b6..8b975d1 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -4001,7 +4001,7 @@
 	usb_gadget_set_selfpowered(gadget);
 
 	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
-			system_utsname.sysname, system_utsname.release,
+			init_utsname()->sysname, init_utsname()->release,
 			gadget->name);
 
 	/* On a real device, serial[] would be loaded from permanent
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index b68cecd..83601d4 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -1189,7 +1189,7 @@
 		strlcpy(manufacturer, iManufacturer, sizeof(manufacturer));
 	} else {
 		snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
-			system_utsname.sysname, system_utsname.release,
+			init_utsname()->sysname, init_utsname()->release,
 			gadget->name);
 	}
 	if (iProduct) {
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b893e31..208e55a 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -271,7 +271,7 @@
 
 
 /* tty driver struct */
-static struct tty_operations gs_tty_ops = {
+static const struct tty_operations gs_tty_ops = {
 	.open =			gs_open,
 	.close =		gs_close,
 	.write =		gs_write,
@@ -1434,7 +1434,7 @@
 		return -ENOMEM;
 
 	snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
-		system_utsname.sysname, system_utsname.release,
+		init_utsname()->sysname, init_utsname()->release,
 		gadget->name);
 
 	memset(dev, 0, sizeof(struct gs_dev));
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index b7018ee..0f809dd 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1242,7 +1242,7 @@
 		EP_OUT_NAME, EP_IN_NAME);
 
 	snprintf (manufacturer, sizeof manufacturer, "%s %s with %s",
-		system_utsname.sysname, system_utsname.release,
+		init_utsname()->sysname, init_utsname()->release,
 		gadget->name);
 
 	return 0;
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index a102a58..21cd226 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -60,16 +60,17 @@
 	  If unsure, say N.
 
 config HID_PID
-	bool "PID Devices (Microsoft Sidewinder Force Feedback 2)"
+	bool "PID device support"
 	depends on HID_FF
 	help
-	  Say Y here if you have a PID-compliant joystick and wish to enable force
-	  feedback for it. The Microsoft Sidewinder Force Feedback 2 is one such
-	  device.
+	  Say Y here if you have a PID-compliant device and wish to enable force
+	  feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
+	  devices.
 
 config LOGITECH_FF
 	bool "Logitech WingMan *3D support"
 	depends on HID_FF
+	select INPUT_FF_MEMLESS if USB_HID
 	help
 	  Say Y here if you have one of these devices:
 	  - Logitech WingMan Cordless RumblePad
@@ -81,12 +82,21 @@
 config THRUSTMASTER_FF
 	bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
 	depends on HID_FF && EXPERIMENTAL
+	select INPUT_FF_MEMLESS if USB_HID
 	help
 	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2,
 	  and want to enable force feedback support for it.
 	  Note: if you say N here, this device will still be supported, but without
 	  force feedback.
 
+config ZEROPLUS_FF
+	bool "Zeroplus based game controller support"
+	depends on HID_FF
+	select INPUT_FF_MEMLESS if USB_HID
+	help
+	  Say Y here if you have a Zeroplus based game controller and want to
+	  enable force feedback for it.
+
 config USB_HIDDEV
 	bool "/dev/hiddev raw HID device support"
 	depends on USB_HID
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 48551be..295f459 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -15,7 +15,7 @@
 	usbhid-objs	+= hid-input.o
 endif
 ifeq ($(CONFIG_HID_PID),y)
-	usbhid-objs	+= pid.o
+	usbhid-objs	+= hid-pidff.o
 endif
 ifeq ($(CONFIG_LOGITECH_FF),y)
 	usbhid-objs	+= hid-lgff.o
@@ -23,6 +23,9 @@
 ifeq ($(CONFIG_THRUSTMASTER_FF),y)
 	usbhid-objs	+= hid-tmff.o
 endif
+ifeq ($(CONFIG_ZEROPLUS_FF),y)
+	usbhid-objs	+= hid-zpff.o
+endif
 ifeq ($(CONFIG_HID_FF),y)
 	usbhid-objs	+= hid-ff.o
 endif
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 81b1ea0..e0fd116 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -543,8 +543,6 @@
 {
 	unsigned i,j;
 
-	hid_ff_exit(device);
-
 	for (i = 0; i < HID_REPORT_TYPES; i++) {
 		struct hid_report_enum *report_enum = device->report_enum + i;
 
@@ -1109,7 +1107,7 @@
 /*
  * Find a report field with a specified HID usage.
  */
-
+#if 0
 struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type)
 {
 	struct hid_report *report;
@@ -1121,6 +1119,7 @@
 				return report->field[i];
 	return NULL;
 }
+#endif  /*  0  */
 
 static int hid_submit_out(struct hid_device *hid)
 {
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
index d5c91ee..a8fc46c 100644
--- a/drivers/usb/input/hid-ff.c
+++ b/drivers/usb/input/hid-ff.c
@@ -44,45 +44,38 @@
 	int (*init)(struct hid_device*);
 };
 
+/*
+ * We try pidff when no other driver is found because PID is the
+ * standards compliant way of implementing force feedback in HID.
+ * pidff_init() will quickly abort if the device doesn't appear to
+ * be a PID device
+ */
 static struct hid_ff_initializer inits[] = {
 #ifdef CONFIG_LOGITECH_FF
-	{0x46d, 0xc211, hid_lgff_init}, // Logitech Cordless rumble pad
-	{0x46d, 0xc283, hid_lgff_init}, // Logitech Wingman Force 3d
-	{0x46d, 0xc295, hid_lgff_init},	// Logitech MOMO force wheel
-	{0x46d, 0xc219, hid_lgff_init}, // Logitech Cordless rumble pad 2
-#endif
-#ifdef CONFIG_HID_PID
-	{0x45e, 0x001b, hid_pid_init},
+	{ 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
+	{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
+	{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
+	{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
 #endif
 #ifdef CONFIG_THRUSTMASTER_FF
-	{0x44f, 0xb304, hid_tmff_init},
+	{ 0x44f, 0xb304, hid_tmff_init },
 #endif
-	{0, 0, NULL} /* Terminating entry */
+#ifdef CONFIG_ZEROPLUS_FF
+	{ 0xc12, 0x0005, hid_zpff_init },
+	{ 0xc12, 0x0030, hid_zpff_init },
+#endif
+	{ 0,	 0,	 hid_pidff_init}  /* Matches anything */
 };
 
-static struct hid_ff_initializer *hid_get_ff_init(__u16 idVendor,
-						  __u16 idProduct)
-{
-	struct hid_ff_initializer *init;
-	for (init = inits;
-	     init->idVendor
-	     && !(init->idVendor == idVendor
-		  && init->idProduct == idProduct);
-	     init++);
-
-	return init->idVendor? init : NULL;
-}
-
 int hid_ff_init(struct hid_device* hid)
 {
 	struct hid_ff_initializer *init;
+	int vendor = le16_to_cpu(hid->dev->descriptor.idVendor);
+	int product = le16_to_cpu(hid->dev->descriptor.idProduct);
 
-	init = hid_get_ff_init(le16_to_cpu(hid->dev->descriptor.idVendor),
-			       le16_to_cpu(hid->dev->descriptor.idProduct));
+	for (init = inits; init->idVendor; init++)
+		if (init->idVendor == vendor && init->idProduct == product)
+			break;
 
-	if (!init) {
-		dbg("hid_ff_init could not find initializer");
-		return -ENOSYS;
-	}
 	return init->init(hid);
 }
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 7208839..4c62afb 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -65,11 +65,9 @@
 #define map_rel(c)	do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
 #define map_key(c)	do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
 #define map_led(c)	do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
-#define map_ff(c)	do { usage->code = c; usage->type = EV_FF;  bit = input->ffbit;  max =  FF_MAX; } while (0)
 
 #define map_abs_clear(c)	do { map_abs(c); clear_bit(c, bit); } while (0)
 #define map_key_clear(c)	do { map_key(c); clear_bit(c, bit); } while (0)
-#define map_ff_effect(c)	do { set_bit(c, input->ffbit); } while (0)
 
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
 
@@ -525,23 +523,7 @@
 
 		case HID_UP_PID:
 
-			set_bit(EV_FF, input->evbit);
 			switch(usage->hid & HID_USAGE) {
-				case 0x26: map_ff_effect(FF_CONSTANT);	goto ignore;
-				case 0x27: map_ff_effect(FF_RAMP);	goto ignore;
-				case 0x28: map_ff_effect(FF_CUSTOM);	goto ignore;
-				case 0x30: map_ff_effect(FF_SQUARE);	map_ff_effect(FF_PERIODIC); goto ignore;
-				case 0x31: map_ff_effect(FF_SINE);	map_ff_effect(FF_PERIODIC); goto ignore;
-				case 0x32: map_ff_effect(FF_TRIANGLE);	map_ff_effect(FF_PERIODIC); goto ignore;
-				case 0x33: map_ff_effect(FF_SAW_UP);	map_ff_effect(FF_PERIODIC); goto ignore;
-				case 0x34: map_ff_effect(FF_SAW_DOWN);	map_ff_effect(FF_PERIODIC); goto ignore;
-				case 0x40: map_ff_effect(FF_SPRING);	goto ignore;
-				case 0x41: map_ff_effect(FF_DAMPER);	goto ignore;
-				case 0x42: map_ff_effect(FF_INERTIA);	goto ignore;
-				case 0x43: map_ff_effect(FF_FRICTION);	goto ignore;
-				case 0x7e: map_ff(FF_GAIN);		break;
-				case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
-				case 0x98: map_ff(FF_AUTOCENTER);	break;
 				case 0xa4: map_key_clear(BTN_DEAD);	break;
 				default: goto ignore;
 			}
@@ -698,8 +680,7 @@
 	}
 
 	if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
-		input->ff_effects_max = value;
-		dbg("Maximum Effects - %d",input->ff_effects_max);
+		dbg("Maximum Effects - %d",value);
 		return;
 	}
 
@@ -748,7 +729,7 @@
 	int offset;
 
 	if (type == EV_FF)
-		return hid_ff_event(hid, dev, type, code, value);
+		return input_ff_event(dev, type, code, value);
 
 	if (type != EV_LED)
 		return -1;
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index f07d443..93da222 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -1,12 +1,11 @@
 /*
- * $$
- *
  * Force feedback support for hid-compliant for some of the devices from
  * Logitech, namely:
  * - WingMan Cordless RumblePad
  * - WingMan Force 3D
  *
  *  Copyright (c) 2002-2004 Johann Deneux
+ *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
  */
 
 /*
@@ -29,495 +28,117 @@
  */
 
 #include <linux/input.h>
-#include <linux/sched.h>
-
-//#define DEBUG
 #include <linux/usb.h>
-
-#include <linux/circ_buf.h>
-
 #include "hid.h"
-#include "fixp-arith.h"
-
-
-/* Periodicity of the update */
-#define PERIOD (HZ/10)
-
-#define RUN_AT(t) (jiffies + (t))
-
-/* Effect status */
-#define EFFECT_STARTED 0     /* Effect is going to play after some time
-				(ff_replay.delay) */
-#define EFFECT_PLAYING 1     /* Effect is being played */
-#define EFFECT_USED    2
-
-// For lgff_device::flags
-#define DEVICE_CLOSING 0     /* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
-        || effect.owner == current->pid)
-
-#define LGFF_CHECK_OWNERSHIP(i, l) \
-        (i>=0 && i<LGFF_EFFECTS \
-        && test_bit(EFFECT_USED, l->effects[i].flags) \
-        && CHECK_OWNERSHIP(l->effects[i]))
-
-#define LGFF_EFFECTS 8
 
 struct device_type {
 	u16 idVendor;
 	u16 idProduct;
-	signed short *ff;
+	const signed short *ff;
 };
 
-struct lgff_effect {
-	pid_t owner;
-
-	struct ff_effect effect;
-
-	unsigned long flags[1];
-	unsigned int count;          /* Number of times left to play */
-	unsigned long started_at;    /* When the effect started to play */
-};
-
-struct lgff_device {
-	struct hid_device* hid;
-
-	struct hid_report* constant;
-	struct hid_report* rumble;
-	struct hid_report* condition;
-
-	struct lgff_effect effects[LGFF_EFFECTS];
-	spinlock_t lock;             /* device-level lock. Having locks on
-					a per-effect basis could be nice, but
-					isn't really necessary */
-
-	unsigned long flags[1];      /* Contains various information about the
-				        state of the driver for this device */
-
-	struct timer_list timer;
-};
-
-/* Callbacks */
-static void hid_lgff_exit(struct hid_device* hid);
-static int hid_lgff_event(struct hid_device *hid, struct input_dev *input,
-			  unsigned int type, unsigned int code, int value);
-static int hid_lgff_flush(struct input_dev *input, struct file *file);
-static int hid_lgff_upload_effect(struct input_dev *input,
-				  struct ff_effect *effect);
-static int hid_lgff_erase(struct input_dev *input, int id);
-
-/* Local functions */
-static void hid_lgff_input_init(struct hid_device* hid);
-static void hid_lgff_timer(unsigned long timer_data);
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report*);
-static void hid_lgff_delete_report(struct hid_report*);
-
-static signed short ff_rumble[] = {
+static const signed short ff_rumble[] = {
 	FF_RUMBLE,
 	-1
 };
 
-static signed short ff_joystick[] = {
+static const signed short ff_joystick[] = {
 	FF_CONSTANT,
 	-1
 };
 
-static struct device_type devices[] = {
-	{0x046d, 0xc211, ff_rumble},
-	{0x046d, 0xc219, ff_rumble},
-	{0x046d, 0xc283, ff_joystick},
-	{0x0000, 0x0000, ff_joystick}
+static const struct device_type devices[] = {
+	{ 0x046d, 0xc211, ff_rumble },
+	{ 0x046d, 0xc219, ff_rumble },
+	{ 0x046d, 0xc283, ff_joystick },
+	{ 0x0000, 0x0000, ff_joystick }
 };
 
+static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+	struct hid_device *hid = dev->private;
+	struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+	int x, y;
+	unsigned int left, right;
+
+#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
+
+	switch (effect->type) {
+	case FF_CONSTANT:
+		x = effect->u.ramp.start_level + 0x7f;	/* 0x7f is center */
+		y = effect->u.ramp.end_level + 0x7f;
+		CLAMP(x);
+		CLAMP(y);
+		report->field[0]->value[0] = 0x51;
+		report->field[0]->value[1] = 0x08;
+		report->field[0]->value[2] = x;
+		report->field[0]->value[3] = y;
+		dbg("(x, y)=(%04x, %04x)", x, y);
+		hid_submit_report(hid, report, USB_DIR_OUT);
+		break;
+
+	case FF_RUMBLE:
+		right = effect->u.rumble.strong_magnitude;
+		left = effect->u.rumble.weak_magnitude;
+		right = right * 0xff / 0xffff;
+		left = left * 0xff / 0xffff;
+		CLAMP(left);
+		CLAMP(right);
+		report->field[0]->value[0] = 0x42;
+		report->field[0]->value[1] = 0x00;
+		report->field[0]->value[2] = left;
+		report->field[0]->value[3] = right;
+		dbg("(left, right)=(%04x, %04x)", left, right);
+		hid_submit_report(hid, report, USB_DIR_OUT);
+		break;
+	}
+	return 0;
+}
+
 int hid_lgff_init(struct hid_device* hid)
 {
-	struct lgff_device *private;
-	struct hid_report* report;
-	struct hid_field* field;
+	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+	struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct input_dev *dev = hidinput->input;
+	struct hid_report *report;
+	struct hid_field *field;
+	int error;
+	int i, j;
 
 	/* Find the report to use */
-	if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
+	if (list_empty(report_list)) {
 		err("No output report found");
 		return -1;
 	}
+
 	/* Check that the report looks ok */
-	report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next;
+	report = list_entry(report_list->next, struct hid_report, list);
 	if (!report) {
 		err("NULL output report");
 		return -1;
 	}
+
 	field = report->field[0];
 	if (!field) {
 		err("NULL field");
 		return -1;
 	}
 
-	private = kzalloc(sizeof(struct lgff_device), GFP_KERNEL);
-	if (!private)
-		return -1;
-	hid->ff_private = private;
-
-	/* Input init */
-	hid_lgff_input_init(hid);
-
-
-	private->constant = hid_lgff_duplicate_report(report);
-	if (!private->constant) {
-		kfree(private);
-		return -1;
-	}
-	private->constant->field[0]->value[0] = 0x51;
-	private->constant->field[0]->value[1] = 0x08;
-	private->constant->field[0]->value[2] = 0x7f;
-	private->constant->field[0]->value[3] = 0x7f;
-
-	private->rumble = hid_lgff_duplicate_report(report);
-	if (!private->rumble) {
-		hid_lgff_delete_report(private->constant);
-		kfree(private);
-		return -1;
-	}
-	private->rumble->field[0]->value[0] = 0x42;
-
-
-	private->condition = hid_lgff_duplicate_report(report);
-	if (!private->condition) {
-		hid_lgff_delete_report(private->rumble);
-		hid_lgff_delete_report(private->constant);
-		kfree(private);
-		return -1;
+	for (i = 0; i < ARRAY_SIZE(devices); i++) {
+		if (dev->id.vendor == devices[i].idVendor &&
+		    dev->id.product == devices[i].idProduct) {
+			for (j = 0; devices[i].ff[j] >= 0; j++)
+				set_bit(devices[i].ff[j], dev->ffbit);
+			break;
+		}
 	}
 
-	private->hid = hid;
-
-	spin_lock_init(&private->lock);
-	init_timer(&private->timer);
-	private->timer.data = (unsigned long)private;
-	private->timer.function = hid_lgff_timer;
-
-	/* Event and exit callbacks */
-	hid->ff_exit = hid_lgff_exit;
-	hid->ff_event = hid_lgff_event;
-
-	/* Start the update task */
-	private->timer.expires = RUN_AT(PERIOD);
-	add_timer(&private->timer);  /*TODO: only run the timer when at least
-				       one effect is playing */
+	error = input_ff_create_memless(dev, NULL, hid_lgff_play);
+	if (error)
+		return error;
 
 	printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
 
 	return 0;
 }
-
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
-{
-	struct hid_report* ret;
-
-	ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
-	if (!ret)
-		return NULL;
-	*ret = *report;
-
-	ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL);
-	if (!ret->field[0]) {
-		kfree(ret);
-		return NULL;
-	}
-	*ret->field[0] = *report->field[0];
-
-	ret->field[0]->value = kzalloc(sizeof(s32[8]), GFP_KERNEL);
-	if (!ret->field[0]->value) {
-		kfree(ret->field[0]);
-		kfree(ret);
-		return NULL;
-	}
-
-	return ret;
-}
-
-static void hid_lgff_delete_report(struct hid_report* report)
-{
-	if (report) {
-		kfree(report->field[0]->value);
-		kfree(report->field[0]);
-		kfree(report);
-	}
-}
-
-static void hid_lgff_input_init(struct hid_device* hid)
-{
-	struct device_type* dev = devices;
-	signed short* ff;
-	u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
-	u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
-	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-	struct input_dev *input_dev = hidinput->input;
-
-	while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
-		dev++;
-
-	for (ff = dev->ff; *ff >= 0; ff++)
-		set_bit(*ff, input_dev->ffbit);
-
-	input_dev->upload_effect = hid_lgff_upload_effect;
-	input_dev->flush = hid_lgff_flush;
-
-	set_bit(EV_FF, input_dev->evbit);
-	input_dev->ff_effects_max = LGFF_EFFECTS;
-}
-
-static void hid_lgff_exit(struct hid_device* hid)
-{
-	struct lgff_device *lgff = hid->ff_private;
-
-	set_bit(DEVICE_CLOSING, lgff->flags);
-	del_timer_sync(&lgff->timer);
-
-	hid_lgff_delete_report(lgff->condition);
-	hid_lgff_delete_report(lgff->rumble);
-	hid_lgff_delete_report(lgff->constant);
-
-	kfree(lgff);
-}
-
-static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
-			  unsigned int type, unsigned int code, int value)
-{
-	struct lgff_device *lgff = hid->ff_private;
-	struct lgff_effect *effect = lgff->effects + code;
-	unsigned long flags;
-
-	if (type != EV_FF)                     return -EINVAL;
-	if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
-	if (value < 0)                         return -EINVAL;
-
-	spin_lock_irqsave(&lgff->lock, flags);
-
-	if (value > 0) {
-		if (test_bit(EFFECT_STARTED, effect->flags)) {
-			spin_unlock_irqrestore(&lgff->lock, flags);
-			return -EBUSY;
-		}
-		if (test_bit(EFFECT_PLAYING, effect->flags)) {
-			spin_unlock_irqrestore(&lgff->lock, flags);
-			return -EBUSY;
-		}
-
-		effect->count = value;
-
-		if (effect->effect.replay.delay) {
-			set_bit(EFFECT_STARTED, effect->flags);
-		} else {
-			set_bit(EFFECT_PLAYING, effect->flags);
-		}
-		effect->started_at = jiffies;
-	}
-	else { /* value == 0 */
-		clear_bit(EFFECT_STARTED, effect->flags);
-		clear_bit(EFFECT_PLAYING, effect->flags);
-	}
-
-	spin_unlock_irqrestore(&lgff->lock, flags);
-
-	return 0;
-
-}
-
-/* Erase all effects this process owns */
-static int hid_lgff_flush(struct input_dev *dev, struct file *file)
-{
-	struct hid_device *hid = dev->private;
-	struct lgff_device *lgff = hid->ff_private;
-	int i;
-
-	for (i=0; i<dev->ff_effects_max; ++i) {
-
-		/*NOTE: no need to lock here. The only times EFFECT_USED is
-		  modified is when effects are uploaded or when an effect is
-		  erased. But a process cannot close its dev/input/eventX fd
-		  and perform ioctls on the same fd all at the same time */
-		if ( current->pid == lgff->effects[i].owner
-		     && test_bit(EFFECT_USED, lgff->effects[i].flags)) {
-
-			if (hid_lgff_erase(dev, i))
-				warn("erase effect %d failed", i);
-		}
-
-	}
-
-	return 0;
-}
-
-static int hid_lgff_erase(struct input_dev *dev, int id)
-{
-	struct hid_device *hid = dev->private;
-	struct lgff_device *lgff = hid->ff_private;
-	unsigned long flags;
-
-	if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES;
-
-	spin_lock_irqsave(&lgff->lock, flags);
-	lgff->effects[id].flags[0] = 0;
-	spin_unlock_irqrestore(&lgff->lock, flags);
-
-	return 0;
-}
-
-static int hid_lgff_upload_effect(struct input_dev* input,
-				  struct ff_effect* effect)
-{
-	struct hid_device *hid = input->private;
-	struct lgff_device *lgff = hid->ff_private;
-	struct lgff_effect new;
-	int id;
-	unsigned long flags;
-
-	dbg("ioctl rumble");
-
-	if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
-
-	spin_lock_irqsave(&lgff->lock, flags);
-
-	if (effect->id == -1) {
-		int i;
-
-		for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i);
-		if (i >= LGFF_EFFECTS) {
-			spin_unlock_irqrestore(&lgff->lock, flags);
-			return -ENOSPC;
-		}
-
-		effect->id = i;
-		lgff->effects[i].owner = current->pid;
-		lgff->effects[i].flags[0] = 0;
-		set_bit(EFFECT_USED, lgff->effects[i].flags);
-	}
-	else if (!LGFF_CHECK_OWNERSHIP(effect->id, lgff)) {
-		spin_unlock_irqrestore(&lgff->lock, flags);
-		return -EACCES;
-	}
-
-	id = effect->id;
-	new = lgff->effects[id];
-
-	new.effect = *effect;
-
-	if (test_bit(EFFECT_STARTED, lgff->effects[id].flags)
-	    || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) {
-
-		/* Changing replay parameters is not allowed (for the time
-		   being) */
-		if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay
-		    || new.effect.replay.length != lgff->effects[id].effect.replay.length) {
-			spin_unlock_irqrestore(&lgff->lock, flags);
-			return -ENOSYS;
-		}
-
-		lgff->effects[id] = new;
-
-	} else {
-		lgff->effects[id] = new;
-	}
-
-	spin_unlock_irqrestore(&lgff->lock, flags);
-	return 0;
-}
-
-static void hid_lgff_timer(unsigned long timer_data)
-{
-	struct lgff_device *lgff = (struct lgff_device*)timer_data;
-	struct hid_device *hid = lgff->hid;
-	unsigned long flags;
-	int x = 0x7f, y = 0x7f;   // Coordinates of constant effects
-	unsigned int left = 0, right = 0;   // Rumbling
-	int i;
-
-	spin_lock_irqsave(&lgff->lock, flags);
-
-	for (i=0; i<LGFF_EFFECTS; ++i) {
-		struct lgff_effect* effect = lgff->effects +i;
-
-		if (test_bit(EFFECT_PLAYING, effect->flags)) {
-
-			switch (effect->effect.type) {
-			case FF_CONSTANT: {
-				//TODO: handle envelopes
-				int degrees = effect->effect.direction * 360 >> 16;
-				x += fixp_mult(fixp_sin(degrees),
-					       fixp_new16(effect->effect.u.constant.level));
-				y += fixp_mult(-fixp_cos(degrees),
-					       fixp_new16(effect->effect.u.constant.level));
-			}       break;
-			case FF_RUMBLE:
-				right += effect->effect.u.rumble.strong_magnitude;
-				left += effect->effect.u.rumble.weak_magnitude;
-				break;
-			};
-
-			/* One run of the effect is finished playing */
-			if (time_after(jiffies,
-					effect->started_at
-					+ effect->effect.replay.delay*HZ/1000
-					+ effect->effect.replay.length*HZ/1000)) {
-				dbg("Finished playing once %d", i);
-				if (--effect->count <= 0) {
-					dbg("Stopped %d", i);
-					clear_bit(EFFECT_PLAYING, effect->flags);
-				}
-				else {
-					dbg("Start again %d", i);
-					if (effect->effect.replay.length != 0) {
-						clear_bit(EFFECT_PLAYING, effect->flags);
-						set_bit(EFFECT_STARTED, effect->flags);
-					}
-					effect->started_at = jiffies;
-				}
-			}
-
-		} else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) {
-			/* Check if we should start playing the effect */
-			if (time_after(jiffies,
-					lgff->effects[i].started_at
-					+ lgff->effects[i].effect.replay.delay*HZ/1000)) {
-				dbg("Now playing %d", i);
-				clear_bit(EFFECT_STARTED, lgff->effects[i].flags);
-				set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
-			}
-		}
-	}
-
-#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
-
-	// Clamp values
-	CLAMP(x);
-	CLAMP(y);
-	CLAMP(left);
-	CLAMP(right);
-
-#undef CLAMP
-
-	if (x != lgff->constant->field[0]->value[2]
-	    || y != lgff->constant->field[0]->value[3]) {
-		lgff->constant->field[0]->value[2] = x;
-		lgff->constant->field[0]->value[3] = y;
-		dbg("(x,y)=(%04x, %04x)", x, y);
-		hid_submit_report(hid, lgff->constant, USB_DIR_OUT);
-	}
-
-	if (left != lgff->rumble->field[0]->value[2]
-	    || right != lgff->rumble->field[0]->value[3]) {
-		lgff->rumble->field[0]->value[2] = left;
-		lgff->rumble->field[0]->value[3] = right;
-		dbg("(left,right)=(%04x, %04x)", left, right);
-		hid_submit_report(hid, lgff->rumble, USB_DIR_OUT);
-	}
-
-	if (!test_bit(DEVICE_CLOSING, lgff->flags)) {
-		lgff->timer.expires = RUN_AT(PERIOD);
-		add_timer(&lgff->timer);
-	}
-
-	spin_unlock_irqrestore(&lgff->lock, flags);
-}
diff --git a/drivers/usb/input/hid-pidff.c b/drivers/usb/input/hid-pidff.c
new file mode 100644
index 0000000..5420c13
--- /dev/null
+++ b/drivers/usb/input/hid-pidff.c
@@ -0,0 +1,1330 @@
+/*
+ *  Force feedback driver for USB HID PID compliant devices
+ *
+ *  Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.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
+ */
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
+
+#include <linux/sched.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "hid.h"
+
+#define	PID_EFFECTS_MAX		64
+
+/* Report usage table used to put reports into an array */
+
+#define PID_SET_EFFECT		0
+#define PID_EFFECT_OPERATION	1
+#define PID_DEVICE_GAIN		2
+#define PID_POOL		3
+#define PID_BLOCK_LOAD		4
+#define PID_BLOCK_FREE		5
+#define PID_DEVICE_CONTROL	6
+#define PID_CREATE_NEW_EFFECT	7
+
+#define PID_REQUIRED_REPORTS	7
+
+#define PID_SET_ENVELOPE	8
+#define PID_SET_CONDITION	9
+#define PID_SET_PERIODIC	10
+#define PID_SET_CONSTANT	11
+#define PID_SET_RAMP		12
+static const u8 pidff_reports[] = {
+	0x21, 0x77, 0x7d, 0x7f, 0x89, 0x90, 0x96, 0xab,
+	0x5a, 0x5f, 0x6e, 0x73, 0x74
+};
+
+/* device_control is really 0x95, but 0x96 specified as it is the usage of
+the only field in that report */
+
+/* Value usage tables used to put fields and values into arrays */
+
+#define PID_EFFECT_BLOCK_INDEX	0
+
+#define PID_DURATION		1
+#define PID_GAIN		2
+#define PID_TRIGGER_BUTTON	3
+#define PID_TRIGGER_REPEAT_INT	4
+#define PID_DIRECTION_ENABLE	5
+#define PID_START_DELAY		6
+static const u8 pidff_set_effect[] = {
+	0x22, 0x50, 0x52, 0x53, 0x54, 0x56, 0xa7
+};
+
+#define PID_ATTACK_LEVEL	1
+#define PID_ATTACK_TIME		2
+#define PID_FADE_LEVEL		3
+#define PID_FADE_TIME		4
+static const u8 pidff_set_envelope[] = { 0x22, 0x5b, 0x5c, 0x5d, 0x5e };
+
+#define PID_PARAM_BLOCK_OFFSET	1
+#define PID_CP_OFFSET		2
+#define PID_POS_COEFFICIENT	3
+#define PID_NEG_COEFFICIENT	4
+#define PID_POS_SATURATION	5
+#define PID_NEG_SATURATION	6
+#define PID_DEAD_BAND		7
+static const u8 pidff_set_condition[] = {
+	0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65
+};
+
+#define PID_MAGNITUDE		1
+#define PID_OFFSET		2
+#define PID_PHASE		3
+#define PID_PERIOD		4
+static const u8 pidff_set_periodic[] = { 0x22, 0x70, 0x6f, 0x71, 0x72 };
+static const u8 pidff_set_constant[] = { 0x22, 0x70 };
+
+#define PID_RAMP_START		1
+#define PID_RAMP_END		2
+static const u8 pidff_set_ramp[] = { 0x22, 0x75, 0x76 };
+
+#define PID_RAM_POOL_AVAILABLE	1
+static const u8 pidff_block_load[] = { 0x22, 0xac };
+
+#define PID_LOOP_COUNT		1
+static const u8 pidff_effect_operation[] = { 0x22, 0x7c };
+
+static const u8 pidff_block_free[] = { 0x22 };
+
+#define PID_DEVICE_GAIN_FIELD	0
+static const u8 pidff_device_gain[] = { 0x7e };
+
+#define PID_RAM_POOL_SIZE	0
+#define PID_SIMULTANEOUS_MAX	1
+#define PID_DEVICE_MANAGED_POOL	2
+static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
+
+/* Special field key tables used to put special field keys into arrays */
+
+#define PID_ENABLE_ACTUATORS	0
+#define PID_RESET		1
+static const u8 pidff_device_control[] = { 0x97, 0x9a };
+
+#define PID_CONSTANT	0
+#define PID_RAMP	1
+#define PID_SQUARE	2
+#define PID_SINE	3
+#define PID_TRIANGLE	4
+#define PID_SAW_UP	5
+#define PID_SAW_DOWN	6
+#define PID_SPRING	7
+#define PID_DAMPER	8
+#define PID_INERTIA	9
+#define PID_FRICTION	10
+static const u8 pidff_effect_types[] = {
+	0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34,
+	0x40, 0x41, 0x42, 0x43
+};
+
+#define PID_BLOCK_LOAD_SUCCESS	0
+#define PID_BLOCK_LOAD_FULL	1
+static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
+
+#define PID_EFFECT_START	0
+#define PID_EFFECT_STOP		1
+static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
+
+struct pidff_usage {
+	struct hid_field *field;
+	s32 *value;
+};
+
+struct pidff_device {
+	struct hid_device *hid;
+
+	struct hid_report *reports[sizeof(pidff_reports)];
+
+	struct pidff_usage set_effect[sizeof(pidff_set_effect)];
+	struct pidff_usage set_envelope[sizeof(pidff_set_envelope)];
+	struct pidff_usage set_condition[sizeof(pidff_set_condition)];
+	struct pidff_usage set_periodic[sizeof(pidff_set_periodic)];
+	struct pidff_usage set_constant[sizeof(pidff_set_constant)];
+	struct pidff_usage set_ramp[sizeof(pidff_set_ramp)];
+
+	struct pidff_usage device_gain[sizeof(pidff_device_gain)];
+	struct pidff_usage block_load[sizeof(pidff_block_load)];
+	struct pidff_usage pool[sizeof(pidff_pool)];
+	struct pidff_usage effect_operation[sizeof(pidff_effect_operation)];
+	struct pidff_usage block_free[sizeof(pidff_block_free)];
+
+	/* Special field is a field that is not composed of
+	   usage<->value pairs that pidff_usage values are */
+
+	/* Special field in create_new_effect */
+	struct hid_field *create_new_effect_type;
+
+	/* Special fields in set_effect */
+	struct hid_field *set_effect_type;
+	struct hid_field *effect_direction;
+
+	/* Special field in device_control */
+	struct hid_field *device_control;
+
+	/* Special field in block_load */
+	struct hid_field *block_load_status;
+
+	/* Special field in effect_operation */
+	struct hid_field *effect_operation_status;
+
+	int control_id[sizeof(pidff_device_control)];
+	int type_id[sizeof(pidff_effect_types)];
+	int status_id[sizeof(pidff_block_load_status)];
+	int operation_id[sizeof(pidff_effect_operation_status)];
+
+	int pid_id[PID_EFFECTS_MAX];
+};
+
+/*
+ * Scale an unsigned value with range 0..max for the given field
+ */
+static int pidff_rescale(int i, int max, struct hid_field *field)
+{
+	return i * (field->logical_maximum - field->logical_minimum) / max +
+	    field->logical_minimum;
+}
+
+/*
+ * Scale a signed value in range -0x8000..0x7fff for the given field
+ */
+static int pidff_rescale_signed(int i, struct hid_field *field)
+{
+	return i == 0 ? 0 : i >
+	    0 ? i * field->logical_maximum / 0x7fff : i *
+	    field->logical_minimum / -0x8000;
+}
+
+static void pidff_set(struct pidff_usage *usage, u16 value)
+{
+	usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
+	debug("calculated from %d to %d", value, usage->value[0]);
+}
+
+static void pidff_set_signed(struct pidff_usage *usage, s16 value)
+{
+	if (usage->field->logical_minimum < 0)
+		usage->value[0] = pidff_rescale_signed(value, usage->field);
+	else {
+		if (value < 0)
+			usage->value[0] =
+			    pidff_rescale(-value, 0x8000, usage->field);
+		else
+			usage->value[0] =
+			    pidff_rescale(value, 0x7fff, usage->field);
+	}
+	debug("calculated from %d to %d", value, usage->value[0]);
+}
+
+/*
+ * Send envelope report to the device
+ */
+static void pidff_set_envelope_report(struct pidff_device *pidff,
+				      struct ff_envelope *envelope)
+{
+	pidff->set_envelope[PID_EFFECT_BLOCK_INDEX].value[0] =
+	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+	pidff->set_envelope[PID_ATTACK_LEVEL].value[0] =
+	    pidff_rescale(envelope->attack_level >
+			  0x7fff ? 0x7fff : envelope->attack_level, 0x7fff,
+			  pidff->set_envelope[PID_ATTACK_LEVEL].field);
+	pidff->set_envelope[PID_FADE_LEVEL].value[0] =
+	    pidff_rescale(envelope->fade_level >
+			  0x7fff ? 0x7fff : envelope->fade_level, 0x7fff,
+			  pidff->set_envelope[PID_FADE_LEVEL].field);
+
+	pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
+	pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
+
+	debug("attack %u => %d", envelope->attack_level,
+	      pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
+
+	hid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
+			  USB_DIR_OUT);
+}
+
+/*
+ * Test if the new envelope differs from old one
+ */
+static int pidff_needs_set_envelope(struct ff_envelope *envelope,
+				    struct ff_envelope *old)
+{
+	return envelope->attack_level != old->attack_level ||
+	       envelope->fade_level != old->fade_level ||
+	       envelope->attack_length != old->attack_length ||
+	       envelope->fade_length != old->fade_length;
+}
+
+/*
+ * Send constant force report to the device
+ */
+static void pidff_set_constant_force_report(struct pidff_device *pidff,
+					    struct ff_effect *effect)
+{
+	pidff->set_constant[PID_EFFECT_BLOCK_INDEX].value[0] =
+		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+	pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
+			 effect->u.constant.level);
+
+	hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
+			  USB_DIR_OUT);
+}
+
+/*
+ * Test if the constant parameters have changed between effects
+ */
+static int pidff_needs_set_constant(struct ff_effect *effect,
+				    struct ff_effect *old)
+{
+	return effect->u.constant.level != old->u.constant.level;
+}
+
+/*
+ * Send set effect report to the device
+ */
+static void pidff_set_effect_report(struct pidff_device *pidff,
+				    struct ff_effect *effect)
+{
+	pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
+		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+	pidff->set_effect_type->value[0] =
+		pidff->create_new_effect_type->value[0];
+	pidff->set_effect[PID_DURATION].value[0] = effect->replay.length;
+	pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button;
+	pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] =
+		effect->trigger.interval;
+	pidff->set_effect[PID_GAIN].value[0] =
+		pidff->set_effect[PID_GAIN].field->logical_maximum;
+	pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
+	pidff->effect_direction->value[0] =
+		pidff_rescale(effect->direction, 0xffff,
+				pidff->effect_direction);
+	pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
+
+	hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+			  USB_DIR_OUT);
+}
+
+/*
+ * Test if the values used in set_effect have changed
+ */
+static int pidff_needs_set_effect(struct ff_effect *effect,
+				  struct ff_effect *old)
+{
+	return effect->replay.length != old->replay.length ||
+	       effect->trigger.interval != old->trigger.interval ||
+	       effect->trigger.button != old->trigger.button ||
+	       effect->direction != old->direction ||
+	       effect->replay.delay != old->replay.delay;
+}
+
+/*
+ * Send periodic effect report to the device
+ */
+static void pidff_set_periodic_report(struct pidff_device *pidff,
+				      struct ff_effect *effect)
+{
+	pidff->set_periodic[PID_EFFECT_BLOCK_INDEX].value[0] =
+		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+	pidff_set_signed(&pidff->set_periodic[PID_MAGNITUDE],
+			 effect->u.periodic.magnitude);
+	pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
+			 effect->u.periodic.offset);
+	pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
+	pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
+
+	hid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
+			  USB_DIR_OUT);
+
+}
+
+/*
+ * Test if periodic effect parameters have changed
+ */
+static int pidff_needs_set_periodic(struct ff_effect *effect,
+				    struct ff_effect *old)
+{
+	return effect->u.periodic.magnitude != old->u.periodic.magnitude ||
+	       effect->u.periodic.offset != old->u.periodic.offset ||
+	       effect->u.periodic.phase != old->u.periodic.phase ||
+	       effect->u.periodic.period != old->u.periodic.period;
+}
+
+/*
+ * Send condition effect reports to the device
+ */
+static void pidff_set_condition_report(struct pidff_device *pidff,
+				       struct ff_effect *effect)
+{
+	int i;
+
+	pidff->set_condition[PID_EFFECT_BLOCK_INDEX].value[0] =
+		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+	for (i = 0; i < 2; i++) {
+		pidff->set_condition[PID_PARAM_BLOCK_OFFSET].value[0] = i;
+		pidff_set_signed(&pidff->set_condition[PID_CP_OFFSET],
+				 effect->u.condition[i].center);
+		pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT],
+				 effect->u.condition[i].right_coeff);
+		pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],
+				 effect->u.condition[i].left_coeff);
+		pidff_set(&pidff->set_condition[PID_POS_SATURATION],
+			  effect->u.condition[i].right_saturation);
+		pidff_set(&pidff->set_condition[PID_NEG_SATURATION],
+			  effect->u.condition[i].left_saturation);
+		pidff_set(&pidff->set_condition[PID_DEAD_BAND],
+			  effect->u.condition[i].deadband);
+		hid_wait_io(pidff->hid);
+		hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
+				  USB_DIR_OUT);
+	}
+}
+
+/*
+ * Test if condition effect parameters have changed
+ */
+static int pidff_needs_set_condition(struct ff_effect *effect,
+				     struct ff_effect *old)
+{
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < 2; i++) {
+		struct ff_condition_effect *cond = &effect->u.condition[i];
+		struct ff_condition_effect *old_cond = &old->u.condition[i];
+
+		ret |= cond->center != old_cond->center ||
+		       cond->right_coeff != old_cond->right_coeff ||
+		       cond->left_coeff != old_cond->left_coeff ||
+		       cond->right_saturation != old_cond->right_saturation ||
+		       cond->left_saturation != old_cond->left_saturation ||
+		       cond->deadband != old_cond->deadband;
+	}
+
+	return ret;
+}
+
+/*
+ * Send ramp force report to the device
+ */
+static void pidff_set_ramp_force_report(struct pidff_device *pidff,
+					struct ff_effect *effect)
+{
+	pidff->set_ramp[PID_EFFECT_BLOCK_INDEX].value[0] =
+		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+	pidff_set_signed(&pidff->set_ramp[PID_RAMP_START],
+			 effect->u.ramp.start_level);
+	pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
+			 effect->u.ramp.end_level);
+	hid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
+			  USB_DIR_OUT);
+}
+
+/*
+ * Test if ramp force parameters have changed
+ */
+static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
+{
+	return effect->u.ramp.start_level != old->u.ramp.start_level ||
+	       effect->u.ramp.end_level != old->u.ramp.end_level;
+}
+
+/*
+ * Send a request for effect upload to the device
+ *
+ * Returns 0 if device reported success, -ENOSPC if the device reported memory
+ * is full. Upon unknown response the function will retry for 60 times, if
+ * still unsuccessful -EIO is returned.
+ */
+static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
+{
+	int j;
+
+	pidff->create_new_effect_type->value[0] = efnum;
+	hid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
+			  USB_DIR_OUT);
+	debug("create_new_effect sent, type: %d", efnum);
+
+	pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
+	pidff->block_load_status->value[0] = 0;
+	hid_wait_io(pidff->hid);
+
+	for (j = 0; j < 60; j++) {
+		debug("pid_block_load requested");
+		hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
+				  USB_DIR_IN);
+		hid_wait_io(pidff->hid);
+		if (pidff->block_load_status->value[0] ==
+		    pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
+			debug("device reported free memory: %d bytes",
+			      pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+				pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
+			return 0;
+		}
+		if (pidff->block_load_status->value[0] ==
+		    pidff->status_id[PID_BLOCK_LOAD_FULL]) {
+			debug("not enough memory free: %d bytes",
+			      pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+				pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
+			return -ENOSPC;
+		}
+	}
+	printk(KERN_ERR "hid-pidff: pid_block_load failed 60 times\n");
+	return -EIO;
+}
+
+/*
+ * Play the effect with PID id n times
+ */
+static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
+{
+	pidff->effect_operation[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
+
+	if (n == 0) {
+		pidff->effect_operation_status->value[0] =
+			pidff->operation_id[PID_EFFECT_STOP];
+	} else {
+		pidff->effect_operation_status->value[0] =
+			pidff->operation_id[PID_EFFECT_START];
+		pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
+	}
+
+	hid_wait_io(pidff->hid);
+	hid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
+			  USB_DIR_OUT);
+}
+
+/**
+ * Play the effect with effect id @effect_id for @value times
+ */
+static int pidff_playback(struct input_dev *dev, int effect_id, int value)
+{
+	struct pidff_device *pidff = dev->ff->private;
+
+	pidff_playback_pid(pidff, pidff->pid_id[effect_id], value);
+
+	return 0;
+}
+
+/*
+ * Erase effect with PID id
+ */
+static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
+{
+	pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
+	hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
+			  USB_DIR_OUT);
+}
+
+/*
+ * Stop and erase effect with effect_id
+ */
+static int pidff_erase_effect(struct input_dev *dev, int effect_id)
+{
+	struct pidff_device *pidff = dev->ff->private;
+	int pid_id = pidff->pid_id[effect_id];
+
+	debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]);
+	pidff_playback_pid(pidff, pid_id, 0);
+	pidff_erase_pid(pidff, pid_id);
+
+	return 0;
+}
+
+/*
+ * Effect upload handler
+ */
+static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
+			       struct ff_effect *old)
+{
+	struct pidff_device *pidff = dev->ff->private;
+	int type_id;
+	int error;
+
+	switch (effect->type) {
+	case FF_CONSTANT:
+		if (!old) {
+			error = pidff_request_effect_upload(pidff,
+					pidff->type_id[PID_CONSTANT]);
+			if (error)
+				return error;
+		}
+		if (!old || pidff_needs_set_effect(effect, old))
+			pidff_set_effect_report(pidff, effect);
+		if (!old || pidff_needs_set_constant(effect, old))
+			pidff_set_constant_force_report(pidff, effect);
+		if (!old ||
+		    pidff_needs_set_envelope(&effect->u.constant.envelope,
+					&old->u.constant.envelope))
+			pidff_set_envelope_report(pidff,
+					&effect->u.constant.envelope);
+		break;
+
+	case FF_PERIODIC:
+		if (!old) {
+			switch (effect->u.periodic.waveform) {
+			case FF_SQUARE:
+				type_id = PID_SQUARE;
+				break;
+			case FF_TRIANGLE:
+				type_id = PID_TRIANGLE;
+				break;
+			case FF_SINE:
+				type_id = PID_SINE;
+				break;
+			case FF_SAW_UP:
+				type_id = PID_SAW_UP;
+				break;
+			case FF_SAW_DOWN:
+				type_id = PID_SAW_DOWN;
+				break;
+			default:
+				printk(KERN_ERR
+				       "hid-pidff: invalid waveform\n");
+				return -EINVAL;
+			}
+
+			error = pidff_request_effect_upload(pidff,
+					pidff->type_id[type_id]);
+			if (error)
+				return error;
+		}
+		if (!old || pidff_needs_set_effect(effect, old))
+			pidff_set_effect_report(pidff, effect);
+		if (!old || pidff_needs_set_periodic(effect, old))
+			pidff_set_periodic_report(pidff, effect);
+		if (!old ||
+		    pidff_needs_set_envelope(&effect->u.periodic.envelope,
+					&old->u.periodic.envelope))
+			pidff_set_envelope_report(pidff,
+					&effect->u.periodic.envelope);
+		break;
+
+	case FF_RAMP:
+		if (!old) {
+			error = pidff_request_effect_upload(pidff,
+					pidff->type_id[PID_RAMP]);
+			if (error)
+				return error;
+		}
+		if (!old || pidff_needs_set_effect(effect, old))
+			pidff_set_effect_report(pidff, effect);
+		if (!old || pidff_needs_set_ramp(effect, old))
+			pidff_set_ramp_force_report(pidff, effect);
+		if (!old ||
+		    pidff_needs_set_envelope(&effect->u.ramp.envelope,
+					&old->u.ramp.envelope))
+			pidff_set_envelope_report(pidff,
+					&effect->u.ramp.envelope);
+		break;
+
+	case FF_SPRING:
+		if (!old) {
+			error = pidff_request_effect_upload(pidff,
+					pidff->type_id[PID_SPRING]);
+			if (error)
+				return error;
+		}
+		if (!old || pidff_needs_set_effect(effect, old))
+			pidff_set_effect_report(pidff, effect);
+		if (!old || pidff_needs_set_condition(effect, old))
+			pidff_set_condition_report(pidff, effect);
+		break;
+
+	case FF_FRICTION:
+		if (!old) {
+			error = pidff_request_effect_upload(pidff,
+					pidff->type_id[PID_FRICTION]);
+			if (error)
+				return error;
+		}
+		if (!old || pidff_needs_set_effect(effect, old))
+			pidff_set_effect_report(pidff, effect);
+		if (!old || pidff_needs_set_condition(effect, old))
+			pidff_set_condition_report(pidff, effect);
+		break;
+
+	case FF_DAMPER:
+		if (!old) {
+			error = pidff_request_effect_upload(pidff,
+					pidff->type_id[PID_DAMPER]);
+			if (error)
+				return error;
+		}
+		if (!old || pidff_needs_set_effect(effect, old))
+			pidff_set_effect_report(pidff, effect);
+		if (!old || pidff_needs_set_condition(effect, old))
+			pidff_set_condition_report(pidff, effect);
+		break;
+
+	case FF_INERTIA:
+		if (!old) {
+			error = pidff_request_effect_upload(pidff,
+					pidff->type_id[PID_INERTIA]);
+			if (error)
+				return error;
+		}
+		if (!old || pidff_needs_set_effect(effect, old))
+			pidff_set_effect_report(pidff, effect);
+		if (!old || pidff_needs_set_condition(effect, old))
+			pidff_set_condition_report(pidff, effect);
+		break;
+
+	default:
+		printk(KERN_ERR "hid-pidff: invalid type\n");
+		return -EINVAL;
+	}
+
+	if (!old)
+		pidff->pid_id[effect->id] =
+		    pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+	debug("uploaded");
+
+	return 0;
+}
+
+/*
+ * set_gain() handler
+ */
+static void pidff_set_gain(struct input_dev *dev, u16 gain)
+{
+	struct pidff_device *pidff = dev->ff->private;
+
+	pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
+	hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+			  USB_DIR_OUT);
+}
+
+static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
+{
+	struct hid_field *field =
+		pidff->block_load[PID_EFFECT_BLOCK_INDEX].field;
+
+	if (!magnitude) {
+		pidff_playback_pid(pidff, field->logical_minimum, 0);
+		return;
+	}
+
+	pidff_playback_pid(pidff, field->logical_minimum, 1);
+
+	pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
+		pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum;
+	pidff->set_effect_type->value[0] = pidff->type_id[PID_SPRING];
+	pidff->set_effect[PID_DURATION].value[0] = 0;
+	pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
+	pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
+	pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
+	pidff->set_effect[PID_START_DELAY].value[0] = 0;
+
+	hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+			  USB_DIR_OUT);
+}
+
+/*
+ * pidff_set_autocenter() handler
+ */
+static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+	struct pidff_device *pidff = dev->ff->private;
+
+	pidff_autocenter(pidff, magnitude);
+}
+
+/*
+ * Find fields from a report and fill a pidff_usage
+ */
+static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
+			     struct hid_report *report, int count, int strict)
+{
+	int i, j, k, found;
+
+	for (k = 0; k < count; k++) {
+		found = 0;
+		for (i = 0; i < report->maxfield; i++) {
+			if (report->field[i]->maxusage !=
+			    report->field[i]->report_count) {
+				debug("maxusage and report_count do not match, "
+				      "skipping");
+				continue;
+			}
+			for (j = 0; j < report->field[i]->maxusage; j++) {
+				if (report->field[i]->usage[j].hid ==
+				    (HID_UP_PID | table[k])) {
+					debug("found %d at %d->%d", k, i, j);
+					usage[k].field = report->field[i];
+					usage[k].value =
+						&report->field[i]->value[j];
+					found = 1;
+					break;
+				}
+			}
+			if (found)
+				break;
+		}
+		if (!found && strict) {
+			debug("failed to locate %d", k);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Return index into pidff_reports for the given usage
+ */
+static int pidff_check_usage(int usage)
+{
+	int i;
+
+	for (i = 0; i < sizeof(pidff_reports); i++)
+		if (usage == (HID_UP_PID | pidff_reports[i]))
+			return i;
+
+	return -1;
+}
+
+/*
+ * Find the reports and fill pidff->reports[]
+ * report_type specifies either OUTPUT or FEATURE reports
+ */
+static void pidff_find_reports(struct hid_device *hid, int report_type,
+			       struct pidff_device *pidff)
+{
+	struct hid_report *report;
+	int i, ret;
+
+	list_for_each_entry(report,
+			    &hid->report_enum[report_type].report_list, list) {
+		if (report->maxfield < 1)
+			continue;
+		ret = pidff_check_usage(report->field[0]->logical);
+		if (ret != -1) {
+			debug("found usage 0x%02x from field->logical",
+			      pidff_reports[ret]);
+			pidff->reports[ret] = report;
+			continue;
+		}
+
+		/*
+		 * Sometimes logical collections are stacked to indicate
+		 * different usages for the report and the field, in which
+		 * case we want the usage of the parent. However, Linux HID
+		 * implementation hides this fact, so we have to dig it up
+		 * ourselves
+		 */
+		i = report->field[0]->usage[0].collection_index;
+		if (i <= 0 ||
+		    hid->collection[i - 1].type != HID_COLLECTION_LOGICAL)
+			continue;
+		ret = pidff_check_usage(hid->collection[i - 1].usage);
+		if (ret != -1 && !pidff->reports[ret]) {
+			debug("found usage 0x%02x from collection array",
+			      pidff_reports[ret]);
+			pidff->reports[ret] = report;
+		}
+	}
+}
+
+/*
+ * Test if the required reports have been found
+ */
+static int pidff_reports_ok(struct pidff_device *pidff)
+{
+	int i;
+
+	for (i = 0; i <= PID_REQUIRED_REPORTS; i++) {
+		if (!pidff->reports[i]) {
+			debug("%d missing", i);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+/*
+ * Find a field with a specific usage within a report
+ */
+static struct hid_field *pidff_find_special_field(struct hid_report *report,
+						  int usage, int enforce_min)
+{
+	int i;
+
+	for (i = 0; i < report->maxfield; i++) {
+		if (report->field[i]->logical == (HID_UP_PID | usage) &&
+		    report->field[i]->report_count > 0) {
+			if (!enforce_min ||
+			    report->field[i]->logical_minimum == 1)
+				return report->field[i];
+			else {
+				printk(KERN_ERR "hid-pidff: logical_minimum "
+					"is not 1 as it should be\n");
+				return NULL;
+			}
+		}
+	}
+	return NULL;
+}
+
+/*
+ * Fill a pidff->*_id struct table
+ */
+static int pidff_find_special_keys(int *keys, struct hid_field *fld,
+				   const u8 *usagetable, int count)
+{
+
+	int i, j;
+	int found = 0;
+
+	for (i = 0; i < count; i++) {
+		for (j = 0; j < fld->maxusage; j++) {
+			if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) {
+				keys[i] = j + 1;
+				found++;
+				break;
+			}
+		}
+	}
+	return found;
+}
+
+#define PIDFF_FIND_SPECIAL_KEYS(keys, field, name) \
+	pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
+		sizeof(pidff_ ## name))
+
+/*
+ * Find and check the special fields
+ */
+static int pidff_find_special_fields(struct pidff_device *pidff)
+{
+	debug("finding special fields");
+
+	pidff->create_new_effect_type =
+		pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
+					 0x25, 1);
+	pidff->set_effect_type =
+		pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
+					 0x25, 1);
+	pidff->effect_direction =
+		pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
+					 0x57, 0);
+	pidff->device_control =
+		pidff_find_special_field(pidff->reports[PID_DEVICE_CONTROL],
+					 0x96, 1);
+	pidff->block_load_status =
+		pidff_find_special_field(pidff->reports[PID_BLOCK_LOAD],
+					 0x8b, 1);
+	pidff->effect_operation_status =
+		pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
+					 0x78, 1);
+
+	debug("search done");
+
+	if (!pidff->create_new_effect_type || !pidff->set_effect_type) {
+		printk(KERN_ERR "hid-pidff: effect lists not found\n");
+		return -1;
+	}
+
+	if (!pidff->effect_direction) {
+		printk(KERN_ERR "hid-pidff: direction field not found\n");
+		return -1;
+	}
+
+	if (!pidff->device_control) {
+		printk(KERN_ERR "hid-pidff: device control field not found\n");
+		return -1;
+	}
+
+	if (!pidff->block_load_status) {
+		printk(KERN_ERR
+		       "hid-pidff: block load status field not found\n");
+		return -1;
+	}
+
+	if (!pidff->effect_operation_status) {
+		printk(KERN_ERR
+		       "hid-pidff: effect operation field not found\n");
+		return -1;
+	}
+
+	pidff_find_special_keys(pidff->control_id, pidff->device_control,
+				pidff_device_control,
+				sizeof(pidff_device_control));
+
+	PIDFF_FIND_SPECIAL_KEYS(control_id, device_control, device_control);
+
+	if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
+				     effect_types)) {
+		printk(KERN_ERR "hid-pidff: no effect types found\n");
+		return -1;
+	}
+
+	if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status,
+				    block_load_status) !=
+			sizeof(pidff_block_load_status)) {
+		printk(KERN_ERR
+		       "hidpidff: block load status identifiers not found\n");
+		return -1;
+	}
+
+	if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status,
+				    effect_operation_status) !=
+			sizeof(pidff_effect_operation_status)) {
+		printk(KERN_ERR
+		       "hidpidff: effect operation identifiers not found\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * Find the implemented effect types
+ */
+static int pidff_find_effects(struct pidff_device *pidff,
+			      struct input_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < sizeof(pidff_effect_types); i++) {
+		int pidff_type = pidff->type_id[i];
+		if (pidff->set_effect_type->usage[pidff_type].hid !=
+		    pidff->create_new_effect_type->usage[pidff_type].hid) {
+			printk(KERN_ERR "hid-pidff: "
+			       "effect type number %d is invalid\n", i);
+			return -1;
+		}
+	}
+
+	if (pidff->type_id[PID_CONSTANT])
+		set_bit(FF_CONSTANT, dev->ffbit);
+	if (pidff->type_id[PID_RAMP])
+		set_bit(FF_RAMP, dev->ffbit);
+	if (pidff->type_id[PID_SQUARE]) {
+		set_bit(FF_SQUARE, dev->ffbit);
+		set_bit(FF_PERIODIC, dev->ffbit);
+	}
+	if (pidff->type_id[PID_SINE]) {
+		set_bit(FF_SINE, dev->ffbit);
+		set_bit(FF_PERIODIC, dev->ffbit);
+	}
+	if (pidff->type_id[PID_TRIANGLE]) {
+		set_bit(FF_TRIANGLE, dev->ffbit);
+		set_bit(FF_PERIODIC, dev->ffbit);
+	}
+	if (pidff->type_id[PID_SAW_UP]) {
+		set_bit(FF_SAW_UP, dev->ffbit);
+		set_bit(FF_PERIODIC, dev->ffbit);
+	}
+	if (pidff->type_id[PID_SAW_DOWN]) {
+		set_bit(FF_SAW_DOWN, dev->ffbit);
+		set_bit(FF_PERIODIC, dev->ffbit);
+	}
+	if (pidff->type_id[PID_SPRING])
+		set_bit(FF_SPRING, dev->ffbit);
+	if (pidff->type_id[PID_DAMPER])
+		set_bit(FF_DAMPER, dev->ffbit);
+	if (pidff->type_id[PID_INERTIA])
+		set_bit(FF_INERTIA, dev->ffbit);
+	if (pidff->type_id[PID_FRICTION])
+		set_bit(FF_FRICTION, dev->ffbit);
+
+	return 0;
+
+}
+
+#define PIDFF_FIND_FIELDS(name, report, strict) \
+	pidff_find_fields(pidff->name, pidff_ ## name, \
+		pidff->reports[report], \
+		sizeof(pidff_ ## name), strict)
+
+/*
+ * Fill and check the pidff_usages
+ */
+static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
+{
+	int envelope_ok = 0;
+
+	if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
+		printk(KERN_ERR
+		       "hid-pidff: unknown set_effect report layout\n");
+		return -ENODEV;
+	}
+
+	PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
+	if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
+		printk(KERN_ERR
+		       "hid-pidff: unknown pid_block_load report layout\n");
+		return -ENODEV;
+	}
+
+	if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) {
+		printk(KERN_ERR
+		       "hid-pidff: unknown effect_operation report layout\n");
+		return -ENODEV;
+	}
+
+	if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) {
+		printk(KERN_ERR
+		       "hid-pidff: unknown pid_block_free report layout\n");
+		return -ENODEV;
+	}
+
+	if (!PIDFF_FIND_FIELDS(set_envelope, PID_SET_ENVELOPE, 1))
+		envelope_ok = 1;
+
+	if (pidff_find_special_fields(pidff) || pidff_find_effects(pidff, dev))
+		return -ENODEV;
+
+	if (!envelope_ok) {
+		if (test_and_clear_bit(FF_CONSTANT, dev->ffbit))
+			printk(KERN_WARNING "hid-pidff: "
+			       "has constant effect but no envelope\n");
+		if (test_and_clear_bit(FF_RAMP, dev->ffbit))
+			printk(KERN_WARNING "hid-pidff: "
+				"has ramp effect but no envelope\n");
+
+		if (test_and_clear_bit(FF_PERIODIC, dev->ffbit))
+			printk(KERN_WARNING "hid-pidff: "
+				"has periodic effect but no envelope\n");
+	}
+
+	if (test_bit(FF_CONSTANT, dev->ffbit) &&
+	    PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) {
+		printk(KERN_WARNING
+		       "hid-pidff: unknown constant effect layout\n");
+		clear_bit(FF_CONSTANT, dev->ffbit);
+	}
+
+	if (test_bit(FF_RAMP, dev->ffbit) &&
+	    PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) {
+		printk(KERN_WARNING "hid-pidff: unknown ramp effect layout\n");
+		clear_bit(FF_RAMP, dev->ffbit);
+	}
+
+	if ((test_bit(FF_SPRING, dev->ffbit) ||
+	     test_bit(FF_DAMPER, dev->ffbit) ||
+	     test_bit(FF_FRICTION, dev->ffbit) ||
+	     test_bit(FF_INERTIA, dev->ffbit)) &&
+	    PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) {
+		printk(KERN_WARNING
+		       "hid-pidff: unknown condition effect layout\n");
+		clear_bit(FF_SPRING, dev->ffbit);
+		clear_bit(FF_DAMPER, dev->ffbit);
+		clear_bit(FF_FRICTION, dev->ffbit);
+		clear_bit(FF_INERTIA, dev->ffbit);
+	}
+
+	if (test_bit(FF_PERIODIC, dev->ffbit) &&
+	    PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) {
+		printk(KERN_WARNING
+		       "hid-pidff: unknown periodic effect layout\n");
+		clear_bit(FF_PERIODIC, dev->ffbit);
+	}
+
+	PIDFF_FIND_FIELDS(pool, PID_POOL, 0);
+
+	if (!PIDFF_FIND_FIELDS(device_gain, PID_DEVICE_GAIN, 1))
+		set_bit(FF_GAIN, dev->ffbit);
+
+	return 0;
+}
+
+/*
+ * Reset the device
+ */
+static void pidff_reset(struct pidff_device *pidff)
+{
+	struct hid_device *hid = pidff->hid;
+	int i = 0;
+
+	pidff->device_control->value[0] = pidff->control_id[PID_RESET];
+	/* We reset twice as sometimes hid_wait_io isn't waiting long enough */
+	hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+	hid_wait_io(hid);
+	hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+	hid_wait_io(hid);
+
+	pidff->device_control->value[0] =
+		pidff->control_id[PID_ENABLE_ACTUATORS];
+	hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+	hid_wait_io(hid);
+
+	/* pool report is sometimes messed up, refetch it */
+	hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
+	hid_wait_io(hid);
+
+	if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
+		int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
+		while (sim_effects < 2) {
+			if (i++ > 20) {
+				printk(KERN_WARNING "hid-pidff: device reports "
+				       "%d simultaneous effects\n",
+				       sim_effects);
+				break;
+			}
+			debug("pid_pool requested again");
+			hid_submit_report(hid, pidff->reports[PID_POOL],
+					  USB_DIR_IN);
+			hid_wait_io(hid);
+		}
+	}
+}
+
+/*
+ * Test if autocenter modification is using the supported method
+ */
+static int pidff_check_autocenter(struct pidff_device *pidff,
+				  struct input_dev *dev)
+{
+	int error;
+
+	/*
+	 * Let's find out if autocenter modification is supported
+	 * Specification doesn't specify anything, so we request an
+	 * effect upload and cancel it immediately. If the approved
+	 * effect id was one above the minimum, then we assume the first
+	 * effect id is a built-in spring type effect used for autocenter
+	 */
+
+	error = pidff_request_effect_upload(pidff, 1);
+	if (error) {
+		printk(KERN_ERR "hid-pidff: upload request failed\n");
+		return error;
+	}
+
+	if (pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] ==
+	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1) {
+		pidff_autocenter(pidff, 0xffff);
+		set_bit(FF_AUTOCENTER, dev->ffbit);
+	} else {
+		printk(KERN_NOTICE "hid-pidff: "
+		       "device has unknown autocenter control method\n");
+	}
+
+	pidff_erase_pid(pidff,
+			pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]);
+
+	return 0;
+
+}
+
+/*
+ * Check if the device is PID and initialize it
+ */
+int hid_pidff_init(struct hid_device *hid)
+{
+	struct pidff_device *pidff;
+	struct hid_input *hidinput = list_entry(hid->inputs.next,
+						struct hid_input, list);
+	struct input_dev *dev = hidinput->input;
+	struct ff_device *ff;
+	int max_effects;
+	int error;
+
+	debug("starting pid init");
+
+	if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
+		debug("not a PID device, no output report");
+		return -ENODEV;
+	}
+
+	pidff = kzalloc(sizeof(*pidff), GFP_KERNEL);
+	if (!pidff)
+		return -ENOMEM;
+
+	pidff->hid = hid;
+
+	pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
+	pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
+
+	if (!pidff_reports_ok(pidff)) {
+		debug("reports not ok, aborting");
+		error = -ENODEV;
+		goto fail;
+	}
+
+	error = pidff_init_fields(pidff, dev);
+	if (error)
+		goto fail;
+
+	pidff_reset(pidff);
+
+	if (test_bit(FF_GAIN, dev->ffbit)) {
+		pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
+		hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+				  USB_DIR_OUT);
+	}
+
+	error = pidff_check_autocenter(pidff, dev);
+	if (error)
+		goto fail;
+
+	max_effects =
+	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum -
+	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum +
+	    1;
+	debug("max effects is %d", max_effects);
+
+	if (max_effects > PID_EFFECTS_MAX)
+		max_effects = PID_EFFECTS_MAX;
+
+	if (pidff->pool[PID_SIMULTANEOUS_MAX].value)
+		debug("max simultaneous effects is %d",
+		      pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
+
+	if (pidff->pool[PID_RAM_POOL_SIZE].value)
+		debug("device memory size is %d bytes",
+		      pidff->pool[PID_RAM_POOL_SIZE].value[0]);
+
+	if (pidff->pool[PID_DEVICE_MANAGED_POOL].value &&
+	    pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) {
+		printk(KERN_NOTICE "hid-pidff: "
+		       "device does not support device managed pool\n");
+		goto fail;
+	}
+
+	error = input_ff_create(dev, max_effects);
+	if (error)
+		goto fail;
+
+	ff = dev->ff;
+	ff->private = pidff;
+	ff->upload = pidff_upload_effect;
+	ff->erase = pidff_erase_effect;
+	ff->set_gain = pidff_set_gain;
+	ff->set_autocenter = pidff_set_autocenter;
+	ff->playback = pidff_playback;
+
+	printk(KERN_INFO "Force feedback for USB HID PID devices by "
+	       "Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+	return 0;
+
+ fail:
+	kfree(pidff);
+	return error;
+}
diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
index 534425c..2d5be4c 100644
--- a/drivers/usb/input/hid-tmff.c
+++ b/drivers/usb/input/hid-tmff.c
@@ -28,97 +28,65 @@
  */
 
 #include <linux/input.h>
-#include <linux/sched.h>
 
 #undef DEBUG
 #include <linux/usb.h>
 
-#include <linux/circ_buf.h>
-
 #include "hid.h"
-#include "fixp-arith.h"
 
 /* Usages for thrustmaster devices I know about */
 #define THRUSTMASTER_USAGE_RUMBLE_LR	(HID_UP_GENDESK | 0xbb)
-#define DELAY_CALC(t,delay)		((t) + (delay)*HZ/1000)
 
-/* Effect status */
-#define EFFECT_STARTED 0	/* Effect is going to play after some time */
-#define EFFECT_PLAYING 1	/* Effect is playing */
-#define EFFECT_USED    2
-
-/* For tmff_device::flags */
-#define DEVICE_CLOSING 0	/* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
-        || effect.owner == current->pid)
-
-#define TMFF_CHECK_ID(id)	((id) >= 0 && (id) < TMFF_EFFECTS)
-
-#define TMFF_CHECK_OWNERSHIP(i, l) \
-        (test_bit(EFFECT_USED, l->effects[i].flags) \
-        && CHECK_OWNERSHIP(l->effects[i]))
-
-#define TMFF_EFFECTS 8
-
-struct tmff_effect {
-	pid_t owner;
-
-	struct ff_effect effect;
-
-	unsigned long flags[1];
-	unsigned int count;             /* Number of times left to play */
-
-	unsigned long play_at;          /* When the effect starts to play */
-	unsigned long stop_at;		/* When the effect ends */
-};
 
 struct tmff_device {
-	struct hid_device *hid;
-
 	struct hid_report *report;
-
 	struct hid_field *rumble;
-
-	unsigned int effects_playing;
-	struct tmff_effect effects[TMFF_EFFECTS];
-	spinlock_t lock;             /* device-level lock. Having locks on
-					a per-effect basis could be nice, but
-					isn't really necessary */
-
-	unsigned long flags[1];      /* Contains various information about the
-					state of the driver for this device */
-
-	struct timer_list timer;
 };
 
-/* Callbacks */
-static void hid_tmff_exit(struct hid_device *hid);
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
-			  unsigned int type, unsigned int code, int value);
-static int hid_tmff_flush(struct input_dev *input, struct file *file);
-static int hid_tmff_upload_effect(struct input_dev *input,
-				  struct ff_effect *effect);
-static int hid_tmff_erase(struct input_dev *input, int id);
+/* Changes values from 0 to 0xffff into values from minimum to maximum */
+static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
+{
+	int ret;
 
-/* Local functions */
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff);
-static void hid_tmff_timer(unsigned long timer_data);
+	ret = (in * (maximum - minimum) / 0xffff) + minimum;
+	if (ret < minimum)
+		return minimum;
+	if (ret > maximum)
+		return maximum;
+	return ret;
+}
+
+static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+	struct hid_device *hid = dev->private;
+	struct tmff_device *tmff = data;
+	int left, right;	/* Rumbling */
+
+	left = hid_tmff_scale(effect->u.rumble.weak_magnitude,
+		tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
+	right = hid_tmff_scale(effect->u.rumble.strong_magnitude,
+		tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
+
+	tmff->rumble->value[0] = left;
+	tmff->rumble->value[1] = right;
+	dbg("(left,right)=(%08x, %08x)", left, right);
+	hid_submit_report(hid, tmff->report, USB_DIR_OUT);
+
+	return 0;
+}
 
 int hid_tmff_init(struct hid_device *hid)
 {
-	struct tmff_device *private;
+	struct tmff_device *tmff;
 	struct list_head *pos;
 	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
 	struct input_dev *input_dev = hidinput->input;
+	int error;
 
-	private = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
-	if (!private)
+	tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
+	if (!tmff)
 		return -ENOMEM;
 
-	hid->ff_private = private;
-
 	/* Find the report to use */
 	__list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) {
 		struct hid_report *report = (struct hid_report *)pos;
@@ -142,18 +110,18 @@
 						continue;
 					}
 
-					if (private->report && private->report != report) {
+					if (tmff->report && tmff->report != report) {
 						warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR in other report");
 						continue;
 					}
 
-					if (private->rumble && private->rumble != field) {
+					if (tmff->rumble && tmff->rumble != field) {
 						warn("ignoring duplicate THRUSTMASTER_USAGE_RUMBLE_LR");
 						continue;
 					}
 
-					private->report = report;
-					private->rumble = field;
+					tmff->report = report;
+					tmff->rumble = field;
 
 					set_bit(FF_RUMBLE, input_dev->ffbit);
 					break;
@@ -162,302 +130,17 @@
 					warn("ignoring unknown output usage %08x", field->usage[0].hid);
 					continue;
 			}
-
-			/* Fallthrough to here only when a valid usage is found */
-			input_dev->upload_effect = hid_tmff_upload_effect;
-			input_dev->flush = hid_tmff_flush;
-
-			set_bit(EV_FF, input_dev->evbit);
-			input_dev->ff_effects_max = TMFF_EFFECTS;
 		}
 	}
 
-	private->hid = hid;
-
-	spin_lock_init(&private->lock);
-	init_timer(&private->timer);
-	private->timer.data = (unsigned long)private;
-	private->timer.function = hid_tmff_timer;
-
-	/* Event and exit callbacks */
-	hid->ff_exit = hid_tmff_exit;
-	hid->ff_event = hid_tmff_event;
+	error = input_ff_create_memless(input_dev, tmff, hid_tmff_play);
+	if (error) {
+		kfree(tmff);
+		return error;
+	}
 
 	info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");
 
 	return 0;
 }
 
-static void hid_tmff_exit(struct hid_device *hid)
-{
-	struct tmff_device *tmff = hid->ff_private;
-	unsigned long flags;
-
-	spin_lock_irqsave(&tmff->lock, flags);
-
-	set_bit(DEVICE_CLOSING, tmff->flags);
-	del_timer_sync(&tmff->timer);
-
-	spin_unlock_irqrestore(&tmff->lock, flags);
-
-	kfree(tmff);
-}
-
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
-			  unsigned int type, unsigned int code, int value)
-{
-	struct tmff_device *tmff = hid->ff_private;
-	struct tmff_effect *effect = &tmff->effects[code];
-	unsigned long flags;
-
-	if (type != EV_FF)
-		return -EINVAL;
-	if (!TMFF_CHECK_ID(code))
-		return -EINVAL;
-	if (!TMFF_CHECK_OWNERSHIP(code, tmff))
-		return -EACCES;
-	if (value < 0)
-		return -EINVAL;
-
-	spin_lock_irqsave(&tmff->lock, flags);
-
-	if (value > 0) {
-		set_bit(EFFECT_STARTED, effect->flags);
-		clear_bit(EFFECT_PLAYING, effect->flags);
-		effect->count = value;
-		effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
-	} else {
-		clear_bit(EFFECT_STARTED, effect->flags);
-		clear_bit(EFFECT_PLAYING, effect->flags);
-	}
-
-	hid_tmff_recalculate_timer(tmff);
-
-	spin_unlock_irqrestore(&tmff->lock, flags);
-
-	return 0;
-
-}
-
-/* Erase all effects this process owns */
-
-static int hid_tmff_flush(struct input_dev *dev, struct file *file)
-{
-	struct hid_device *hid = dev->private;
-	struct tmff_device *tmff = hid->ff_private;
-	int i;
-
-	for (i=0; i<dev->ff_effects_max; ++i)
-
-	     /* NOTE: no need to lock here. The only times EFFECT_USED is
-		modified is when effects are uploaded or when an effect is
-		erased. But a process cannot close its dev/input/eventX fd
-		and perform ioctls on the same fd all at the same time */
-
-		if (current->pid == tmff->effects[i].owner
-		     && test_bit(EFFECT_USED, tmff->effects[i].flags))
-			if (hid_tmff_erase(dev, i))
-				warn("erase effect %d failed", i);
-
-
-	return 0;
-}
-
-static int hid_tmff_erase(struct input_dev *dev, int id)
-{
-	struct hid_device *hid = dev->private;
-	struct tmff_device *tmff = hid->ff_private;
-	unsigned long flags;
-
-	if (!TMFF_CHECK_ID(id))
-		return -EINVAL;
-	if (!TMFF_CHECK_OWNERSHIP(id, tmff))
-		return -EACCES;
-
-	spin_lock_irqsave(&tmff->lock, flags);
-
-	tmff->effects[id].flags[0] = 0;
-	hid_tmff_recalculate_timer(tmff);
-
-	spin_unlock_irqrestore(&tmff->lock, flags);
-
-	return 0;
-}
-
-static int hid_tmff_upload_effect(struct input_dev *input,
-				  struct ff_effect *effect)
-{
-	struct hid_device *hid = input->private;
-	struct tmff_device *tmff = hid->ff_private;
-	int id;
-	unsigned long flags;
-
-	if (!test_bit(effect->type, input->ffbit))
-		return -EINVAL;
-	if (effect->id != -1 && !TMFF_CHECK_ID(effect->id))
-		return -EINVAL;
-
-	spin_lock_irqsave(&tmff->lock, flags);
-
-	if (effect->id == -1) {
-		/* Find a free effect */
-		for (id = 0; id < TMFF_EFFECTS && test_bit(EFFECT_USED, tmff->effects[id].flags); ++id);
-
-		if (id >= TMFF_EFFECTS) {
-			spin_unlock_irqrestore(&tmff->lock, flags);
-			return -ENOSPC;
-		}
-
-		effect->id = id;
-		tmff->effects[id].owner = current->pid;
-		tmff->effects[id].flags[0] = 0;
-		set_bit(EFFECT_USED, tmff->effects[id].flags);
-
-	} else {
-		/* Re-uploading an owned effect, to change parameters */
-		id = effect->id;
-		clear_bit(EFFECT_PLAYING, tmff->effects[id].flags);
-	}
-
-	tmff->effects[id].effect = *effect;
-
-	hid_tmff_recalculate_timer(tmff);
-
-	spin_unlock_irqrestore(&tmff->lock, flags);
-	return 0;
-}
-
-/* Start the timer for the next start/stop/delay */
-/* Always call this while tmff->lock is locked */
-
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff)
-{
-	int i;
-	int events = 0;
-	unsigned long next_time;
-
-	next_time = 0;	/* Shut up compiler's incorrect warning */
-
-	/* Find the next change in an effect's status */
-	for (i = 0; i < TMFF_EFFECTS; ++i) {
-		struct tmff_effect *effect = &tmff->effects[i];
-		unsigned long play_time;
-
-		if (!test_bit(EFFECT_STARTED, effect->flags))
-			continue;
-
-		effect->stop_at = DELAY_CALC(effect->play_at, effect->effect.replay.length);
-
-		if (!test_bit(EFFECT_PLAYING, effect->flags))
-			play_time = effect->play_at;
-		else
-			play_time = effect->stop_at;
-
-		events++;
-
-		if (time_after(jiffies, play_time))
-			play_time = jiffies;
-
-		if (events == 1)
-			next_time = play_time;
-		else {
-			if (time_after(next_time, play_time))
-				next_time = play_time;
-		}
-	}
-
-	if (!events && tmff->effects_playing) {
-		/* Treat all effects turning off as an event */
-		events = 1;
-		next_time = jiffies;
-	}
-
-	if (!events) {
-		/* No events, no time, no need for a timer. */
-		del_timer_sync(&tmff->timer);
-		return;
-	}
-
-	mod_timer(&tmff->timer, next_time);
-}
-
-/* Changes values from 0 to 0xffff into values from minimum to maximum */
-static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
-{
-	int ret;
-
-	ret = (in * (maximum - minimum) / 0xffff) + minimum;
-	if (ret < minimum)
-		return minimum;
-	if (ret > maximum)
-		return maximum;
-	return ret;
-}
-
-static void hid_tmff_timer(unsigned long timer_data)
-{
-	struct tmff_device *tmff = (struct tmff_device *) timer_data;
-	struct hid_device *hid = tmff->hid;
-	unsigned long flags;
-	int left = 0, right = 0;	/* Rumbling */
-	int i;
-
-	spin_lock_irqsave(&tmff->lock, flags);
-
-	tmff->effects_playing = 0;
-
-	for (i = 0; i < TMFF_EFFECTS; ++i) {
-		struct tmff_effect *effect = &tmff->effects[i];
-
-		if (!test_bit(EFFECT_STARTED, effect->flags))
-			continue;
-
-		if (!time_after(jiffies, effect->play_at))
-			continue;
-
-		if (time_after(jiffies, effect->stop_at)) {
-
-			dbg("Finished playing once %d", i);
-			clear_bit(EFFECT_PLAYING, effect->flags);
-
-			if (--effect->count <= 0) {
-				dbg("Stopped %d", i);
-				clear_bit(EFFECT_STARTED, effect->flags);
-				continue;
-			} else {
-				dbg("Start again %d", i);
-				effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
-				continue;
-			}
-		}
-
-		++tmff->effects_playing;
-
-		set_bit(EFFECT_PLAYING, effect->flags);
-
-		switch (effect->effect.type) {
-			case FF_RUMBLE:
-				right += effect->effect.u.rumble.strong_magnitude;
-				left += effect->effect.u.rumble.weak_magnitude;
-				break;
-			default:
-				BUG();
-				break;
-		}
-	}
-
-	left = hid_tmff_scale(left, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
-	right = hid_tmff_scale(right, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
-
-	if (left != tmff->rumble->value[0] || right != tmff->rumble->value[1]) {
-		tmff->rumble->value[0] = left;
-		tmff->rumble->value[1] = right;
-		dbg("(left,right)=(%08x, %08x)", left, right);
-		hid_submit_report(hid, tmff->report, USB_DIR_OUT);
-	}
-
-	if (!test_bit(DEVICE_CLOSING, tmff->flags))
-		hid_tmff_recalculate_timer(tmff);
-
-	spin_unlock_irqrestore(&tmff->lock, flags);
-}
diff --git a/drivers/usb/input/hid-zpff.c b/drivers/usb/input/hid-zpff.c
new file mode 100644
index 0000000..d2ce321
--- /dev/null
+++ b/drivers/usb/input/hid-zpff.c
@@ -0,0 +1,110 @@
+/*
+ *  Force feedback support for Zeroplus based devices
+ *
+ *  Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.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
+ */
+
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg)
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include "hid.h"
+
+struct zpff_device {
+	struct hid_report *report;
+};
+
+static int hid_zpff_play(struct input_dev *dev, void *data,
+			 struct ff_effect *effect)
+{
+	struct hid_device *hid = dev->private;
+	struct zpff_device *zpff = data;
+	int left, right;
+
+	/*
+	 * The following is specified the other way around in the Zeroplus
+	 * datasheet but the order below is correct for the XFX Executioner;
+	 * however it is possible that the XFX Executioner is an exception
+	 */
+
+	left = effect->u.rumble.strong_magnitude;
+	right = effect->u.rumble.weak_magnitude;
+	debug("called with 0x%04x 0x%04x", left, right);
+
+	left = left * 0x7f / 0xffff;
+	right = right * 0x7f / 0xffff;
+
+	zpff->report->field[2]->value[0] = left;
+	zpff->report->field[3]->value[0] = right;
+	debug("running with 0x%02x 0x%02x", left, right);
+	hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+	return 0;
+}
+
+int hid_zpff_init(struct hid_device *hid)
+{
+	struct zpff_device *zpff;
+	struct hid_report *report;
+	struct hid_input *hidinput = list_entry(hid->inputs.next,
+						struct hid_input, list);
+	struct list_head *report_list =
+			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct input_dev *dev = hidinput->input;
+	int error;
+
+	if (list_empty(report_list)) {
+		printk(KERN_ERR "hid-zpff: no output report found\n");
+		return -ENODEV;
+	}
+
+	report = list_entry(report_list->next, struct hid_report, list);
+
+	if (report->maxfield < 4) {
+		printk(KERN_ERR "hid-zpff: not enough fields in report\n");
+		return -ENODEV;
+	}
+
+	zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
+	if (!zpff)
+		return -ENOMEM;
+
+	set_bit(FF_RUMBLE, dev->ffbit);
+
+	error = input_ff_create_memless(dev, zpff, hid_zpff_play);
+	if (error) {
+		kfree(zpff);
+		return error;
+	}
+
+	zpff->report = report;
+	zpff->report->field[0]->value[0] = 0x00;
+	zpff->report->field[1]->value[0] = 0x02;
+	zpff->report->field[2]->value[0] = 0x00;
+	zpff->report->field[3]->value[0] = 0x00;
+	hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+	printk(KERN_INFO "Force feedback for Zeroplus based devices by "
+	       "Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+	return 0;
+}
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index 778e575..b03fd9b 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -449,11 +449,6 @@
 	char phys[64];							/* Device physical location */
 	char uniq[64];							/* Device unique identifier (serial #) */
 
-	void *ff_private;                                               /* Private data for the force-feedback driver */
-	void (*ff_exit)(struct hid_device*);                            /* Called by hid_exit_ff(hid) */
-	int (*ff_event)(struct hid_device *hid, struct input_dev *input,
-			unsigned int type, unsigned int code, int value);
-
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
 	unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
 	unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
@@ -521,29 +516,22 @@
 int hid_set_field(struct hid_field *, unsigned, __s32);
 void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
 void hid_init_reports(struct hid_device *hid);
-struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type);
 int hid_wait_io(struct hid_device* hid);
 
 
 #ifdef CONFIG_HID_FF
 int hid_ff_init(struct hid_device *hid);
+
+int hid_lgff_init(struct hid_device *hid);
+int hid_tmff_init(struct hid_device *hid);
+int hid_zpff_init(struct hid_device *hid);
+#ifdef CONFIG_HID_PID
+int hid_pidff_init(struct hid_device *hid);
+#else
+static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
+#endif
+
 #else
 static inline int hid_ff_init(struct hid_device *hid) { return -1; }
 #endif
-static inline void hid_ff_exit(struct hid_device *hid)
-{
-	if (hid->ff_exit)
-		hid->ff_exit(hid);
-}
-static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input,
-			unsigned int type, unsigned int code, int value)
-{
-	if (hid->ff_event)
-		return hid->ff_event(hid, input, type, code, value);
-	return -ENOSYS;
-}
-
-int hid_lgff_init(struct hid_device* hid);
-int hid_tmff_init(struct hid_device* hid);
-int hid_pid_init(struct hid_device* hid);
 
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
deleted file mode 100644
index d9d9f65..0000000
--- a/drivers/usb/input/pid.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- *  PID Force feedback support for hid devices.
- *
- *  Copyright (c) 2002 Rodrigo Damazio.
- *  Portions by Johann Deneux and Bjorn Augustson
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-#include <linux/spinlock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include "hid.h"
-#include "pid.h"
-
-#define CHECK_OWNERSHIP(i, hid_pid)	\
-	((i) < FF_EFFECTS_MAX && i >= 0 && \
-	test_bit(FF_PID_FLAGS_USED, &hid_pid->effects[(i)].flags) && \
-	(current->pid == 0 || \
-	(hid_pid)->effects[(i)].owner == current->pid))
-
-/* Called when a transfer is completed */
-static void hid_pid_ctrl_out(struct urb *u, struct pt_regs *regs)
-{
-	dev_dbg(&u->dev->dev, "hid_pid_ctrl_out - Transfer Completed\n");
-}
-
-static void hid_pid_exit(struct hid_device *hid)
-{
-	struct hid_ff_pid *private = hid->ff_private;
-
-	if (private->urbffout) {
-		usb_kill_urb(private->urbffout);
-		usb_free_urb(private->urbffout);
-	}
-}
-
-static int pid_upload_periodic(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "requested periodic force upload\n");
-	return 0;
-}
-
-static int pid_upload_constant(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "requested constant force upload\n");
-	return 0;
-}
-
-static int pid_upload_condition(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "requested Condition force upload\n");
-	return 0;
-}
-
-static int pid_upload_ramp(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "request ramp force upload\n");
-	return 0;
-}
-
-static int hid_pid_event(struct hid_device *hid, struct input_dev *input,
-			 unsigned int type, unsigned int code, int value)
-{
-	dev_dbg(&hid->dev->dev, "PID event received: type=%d,code=%d,value=%d.\n", type, code, value);
-
-	if (type != EV_FF)
-		return -1;
-
-	return 0;
-}
-
-/* Lock must be held by caller */
-static void hid_pid_ctrl_playback(struct hid_device *hid, struct hid_pid_effect *effect, int play)
-{
-	if (play)
-		set_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
-	else
-		clear_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
-}
-
-static int hid_pid_erase(struct input_dev *dev, int id)
-{
-	struct hid_device *hid = dev->private;
-	struct hid_ff_pid *pid = hid->ff_private;
-	struct hid_field *field;
-	unsigned long flags;
-	int ret;
-
-	if (!CHECK_OWNERSHIP(id, pid))
-		return -EACCES;
-
-	/* Find report */
-	field = hid_find_field_by_usage(hid, HID_UP_PID | FF_PID_USAGE_BLOCK_FREE,
-					HID_OUTPUT_REPORT);
-	if (!field) {
-		dev_err(&hid->dev->dev, "couldn't find report\n");
-		return -EIO;
-	}
-
-	ret = hid_set_field(field, 0, pid->effects[id].device_id);
-	if (ret) {
-		dev_err(&hid->dev->dev, "couldn't set field\n");
-		return ret;
-	}
-
-	hid_submit_report(hid, field->report, USB_DIR_OUT);
-
-	spin_lock_irqsave(&pid->lock, flags);
-	hid_pid_ctrl_playback(hid, pid->effects + id, 0);
-	pid->effects[id].flags = 0;
-	spin_unlock_irqrestore(&pid->lock, flags);
-
-	return 0;
-}
-
-/* Erase all effects this process owns */
-static int hid_pid_flush(struct input_dev *dev, struct file *file)
-{
-	struct hid_device *hid = dev->private;
-	struct hid_ff_pid *pid = hid->ff_private;
-	int i;
-
-	/*NOTE: no need to lock here. The only times EFFECT_USED is
-	   modified is when effects are uploaded or when an effect is
-	   erased. But a process cannot close its dev/input/eventX fd
-	   and perform ioctls on the same fd all at the same time */
-	/*FIXME: multiple threads, anyone? */
-	for (i = 0; i < dev->ff_effects_max; ++i)
-		if (current->pid == pid->effects[i].owner
-		    && test_bit(FF_PID_FLAGS_USED, &pid->effects[i].flags))
-			if (hid_pid_erase(dev, i))
-				dev_warn(&hid->dev->dev, "erase effect %d failed", i);
-
-	return 0;
-}
-
-static int hid_pid_upload_effect(struct input_dev *dev,
-				 struct ff_effect *effect)
-{
-	struct hid_ff_pid *pid_private = (struct hid_ff_pid *)(dev->private);
-	int ret;
-	int is_update;
-	unsigned long flags;
-
-	dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n", effect->type);
-	/* Check this effect type is supported by this device */
-	if (!test_bit(effect->type, dev->ffbit)) {
-		dev_dbg(&pid_private->hid->dev->dev,
-			"invalid kind of effect requested.\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * If we want to create a new effect, get a free id
-	 */
-	if (effect->id == -1) {
-		int id = 0;
-
-		// Spinlock so we don`t get a race condition when choosing IDs
-		spin_lock_irqsave(&pid_private->lock, flags);
-
-		while (id < FF_EFFECTS_MAX)
-			if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags))
-				break;
-
-		if (id == FF_EFFECTS_MAX) {
-			spin_unlock_irqrestore(&pid_private->lock, flags);
-// TEMP - We need to get ff_effects_max correctly first:  || id >= dev->ff_effects_max) {
-			dev_dbg(&pid_private->hid->dev->dev, "Not enough device memory\n");
-			return -ENOMEM;
-		}
-
-		effect->id = id;
-		dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
-		pid_private->effects[id].owner = current->pid;
-		pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
-		spin_unlock_irqrestore(&pid_private->lock, flags);
-
-		is_update = FF_PID_FALSE;
-	} else {
-		/* We want to update an effect */
-		if (!CHECK_OWNERSHIP(effect->id, pid_private))
-			return -EACCES;
-
-		/* Parameter type cannot be updated */
-		if (effect->type != pid_private->effects[effect->id].effect.type)
-			return -EINVAL;
-
-		/* Check the effect is not already being updated */
-		if (test_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags))
-			return -EAGAIN;
-
-		is_update = FF_PID_TRUE;
-	}
-
-	/*
-	 * Upload the effect
-	 */
-	switch (effect->type) {
-	case FF_PERIODIC:
-		ret = pid_upload_periodic(pid_private, effect, is_update);
-		break;
-
-	case FF_CONSTANT:
-		ret = pid_upload_constant(pid_private, effect, is_update);
-		break;
-
-	case FF_SPRING:
-	case FF_FRICTION:
-	case FF_DAMPER:
-	case FF_INERTIA:
-		ret = pid_upload_condition(pid_private, effect, is_update);
-		break;
-
-	case FF_RAMP:
-		ret = pid_upload_ramp(pid_private, effect, is_update);
-		break;
-
-	default:
-		dev_dbg(&pid_private->hid->dev->dev,
-			"invalid type of effect requested - %x.\n",
-			effect->type);
-		return -EINVAL;
-	}
-	/* If a packet was sent, forbid new updates until we are notified
-	 * that the packet was updated
-	 */
-	if (ret == 0)
-		set_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags);
-	pid_private->effects[effect->id].effect = *effect;
-	return ret;
-}
-
-int hid_pid_init(struct hid_device *hid)
-{
-	struct hid_ff_pid *private;
-	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-	struct input_dev *input_dev = hidinput->input;
-
-	private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
-	if (!private)
-		return -ENOMEM;
-
-	private->hid = hid;
-
-	hid->ff_exit = hid_pid_exit;
-	hid->ff_event = hid_pid_event;
-
-	/* Open output URB */
-	if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) {
-		kfree(private);
-		return -1;
-	}
-
-	usb_fill_control_urb(private->urbffout, hid->dev, 0,
-			     (void *)&private->ffcr, private->ctrl_buffer, 8,
-			     hid_pid_ctrl_out, hid);
-
-	input_dev->upload_effect = hid_pid_upload_effect;
-	input_dev->flush = hid_pid_flush;
-	input_dev->ff_effects_max = 8;	// A random default
-	set_bit(EV_FF, input_dev->evbit);
-	set_bit(EV_FF_STATUS, input_dev->evbit);
-
-	spin_lock_init(&private->lock);
-
-	printk(KERN_INFO "Force feedback driver for PID devices by Rodrigo Damazio <rdamazio@lsi.usp.br>.\n");
-
-	return 0;
-}
diff --git a/drivers/usb/input/pid.h b/drivers/usb/input/pid.h
deleted file mode 100644
index a2cb962..0000000
--- a/drivers/usb/input/pid.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  PID Force feedback support for hid devices.
- *
- *  Copyright (c) 2002 Rodrigo Damazio.
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#define FF_EFFECTS_MAX 64
-
-#define FF_PID_FLAGS_USED	1	/* If the effect exists */
-#define FF_PID_FLAGS_UPDATING	2	/* If the effect is being updated */
-#define FF_PID_FLAGS_PLAYING	3	/* If the effect is currently being played */
-
-#define FF_PID_FALSE	0
-#define FF_PID_TRUE	1
-
-struct hid_pid_effect {
-	unsigned long flags;
-	pid_t owner;
-	unsigned int device_id;	/* The device-assigned ID */
-	struct ff_effect effect;
-};
-
-struct hid_ff_pid {
-	struct hid_device *hid;
-	unsigned long gain;
-
-	struct urb *urbffout;
-	struct usb_ctrlrequest ffcr;
-	spinlock_t lock;
-
-	unsigned char ctrl_buffer[8];
-
-	struct hid_pid_effect effects[FF_EFFECTS_MAX];
-};
-
-/*
- * Constants from the PID usage table (still far from complete)
- */
-
-#define FF_PID_USAGE_BLOCK_LOAD 	0x89UL
-#define FF_PID_USAGE_BLOCK_FREE		0x90UL
-#define FF_PID_USAGE_NEW_EFFECT 	0xABUL
-#define FF_PID_USAGE_POOL_REPORT	0x7FUL
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0222d92..8006e51 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1015,7 +1015,7 @@
 	dev_info(dev, "device disconnected\n");
 }
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
 	.open =			serial_open,
 	.close =		serial_close,
 	.write =		serial_write,
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 422a4b2..fe2c4cd 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -119,7 +119,7 @@
 	  Say Y here to include additional code to support the Olympus MAUSB-10
 	  and Fujifilm DPC-R1 USB Card reader/writer devices.
 
-	  These devices are based on the Alauda chip and support support both
+	  These devices are based on the Alauda chip and support both
 	  XD and SmartMedia cards.
 
 config USB_STORAGE_ONETOUCH
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e0ef332..daaa486 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -53,6 +53,11 @@
 	  (e.g. an accelerated X server) and that are not frame buffer
 	  device-aware may cause unexpected results. If unsure, say N.
 
+config FB_DDC
+       tristate
+       depends on FB && I2C && I2C_ALGOBIT
+       default n
+
 config FB_CFB_FILLRECT
 	tristate
 	depends on FB
@@ -183,7 +188,7 @@
 	bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC"
 	help
 	  This is an implementation of the Sharp LQ035Q7DB02, a 3.5"
-	  color QVGA, HRTFT panel.  The LogicPD device includes an
+	  color QVGA, HRTFT panel.  The LogicPD device includes
 	  an integrated HRTFT controller IC.
 	  The native resolution is 240x320.
 
@@ -398,7 +403,7 @@
 	  is based on the KS-108 lcd controller and is typically a matrix
 	  of 2*n chips. This driver was tested with a 128x64 panel. This
 	  driver supports it for use with x86 SBCs through a 16 bit GPIO
-	  interface (8 bit data, 8 bit control). If you anticpate using
+	  interface (8 bit data, 8 bit control). If you anticipate using
 	  this driver, say Y or M; otherwise say N. You must specify the
 	  GPIO IO address to be used for setting control and data.
 
@@ -696,6 +701,7 @@
 	depends on FB && PCI
 	select I2C_ALGOBIT if FB_NVIDIA_I2C
 	select I2C if FB_NVIDIA_I2C
+	select FB_DDC if FB_NVIDIA_I2C
 	select FB_MODE_HELPERS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
@@ -734,6 +740,7 @@
 	depends on FB && PCI
 	select I2C_ALGOBIT if FB_RIVA_I2C
 	select I2C if FB_RIVA_I2C
+	select FB_DDC if FB_RIVA_I2C
 	select FB_MODE_HELPERS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
@@ -764,7 +771,7 @@
 	default n
 	help
 	  Say Y here if you want the Riva driver to output all sorts
-	  of debugging informations to provide to the maintainer when
+	  of debugging information to provide to the maintainer when
 	  something goes wrong.
 
 config FB_RIVA_BACKLIGHT
@@ -822,6 +829,7 @@
 	depends on FB_I810 && FB_I810_GTF
 	select I2C
 	select I2C_ALGOBIT
+	select FB_DDC
 	help
 
 config FB_INTEL
@@ -857,7 +865,7 @@
 	depends on FB_INTEL
 	---help---
 	  Say Y here if you want the Intel driver to output all sorts
-	  of debugging informations to provide to the maintainer when
+	  of debugging information to provide to the maintainer when
 	  something goes wrong.
 
 config FB_INTEL_I2C
@@ -1012,6 +1020,7 @@
 	depends on FB && PCI
 	select I2C_ALGOBIT if FB_RADEON_I2C
 	select I2C if FB_RADEON_I2C
+	select FB_DDC if FB_RADEON_I2C
 	select FB_MODE_HELPERS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
@@ -1053,7 +1062,7 @@
 	default n
 	help
 	  Say Y here if you want the Radeon driver to output all sorts
-	  of debugging informations to provide to the maintainer when
+	  of debugging information to provide to the maintainer when
 	  something goes wrong.
 
 config FB_ATY128
@@ -1140,6 +1149,7 @@
 	depends on FB && PCI && EXPERIMENTAL
 	select I2C_ALGOBIT if FB_SAVAGE_I2C
 	select I2C if FB_SAVAGE_I2C
+	select FB_DDC if FB_SAVAGE_I2C
 	select FB_MODE_HELPERS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
@@ -1619,7 +1629,8 @@
 	  kernel option `video=vfb:'.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called vfb.
+	  module will be called vfb. In order to load it, you must use
+	  the vfb_enable=1 option.
 
 	  If unsure, say N.
 if VT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 481c6c9..a6980e9 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -18,6 +18,7 @@
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
 obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
 obj-$(CONFIG_FB_MACMODES)      += macmodes.o
+obj-$(CONFIG_FB_DDC)           += fb_ddc.o
 
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_RETINAZ3)         += retz3fb.o
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index 55fb8b04..b04f49f 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -355,5 +355,9 @@
 
 extern void aty_reset_engine(const struct atyfb_par *par);
 extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
-extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par);
 extern u8   aty_ld_pll_ct(int offset, const struct atyfb_par *par);
+
+void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
+
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 19a71f0..b45c9fd 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -240,9 +240,6 @@
 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
 static int atyfb_blank(int blank, struct fb_info *info);
 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
-extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
-extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
 #ifdef __sparc__
 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
 #endif
@@ -3863,6 +3860,7 @@
 
 static int __devinit atyfb_init(void)
 {
+    int err1 = 1, err2 = 1;
 #ifndef MODULE
     char *option = NULL;
 
@@ -3872,12 +3870,13 @@
 #endif
 
 #ifdef CONFIG_PCI
-    pci_register_driver(&atyfb_driver);
+    err1 = pci_register_driver(&atyfb_driver);
 #endif
 #ifdef CONFIG_ATARI
-    atyfb_atari_probe();
+    err2 = atyfb_atari_probe();
 #endif
-    return 0;
+
+    return (err1 && err2) ? -ENODEV : 0;
 }
 
 static void __exit atyfb_exit(void)
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index e705693..5080816 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -27,7 +27,7 @@
 	return res;
 }
 
-void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
+static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
 {
 	/* write addr byte */
 	aty_st_8(CLOCK_CNTL_ADDR, ((offset << 2) & PLL_ADDR) | PLL_WR_EN, par);
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 9aaca58..6767545 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -16,8 +16,6 @@
 #include "radeonfb.h"
 #include "../edid.h"
 
-#define RADEON_DDC 	0x50
-
 static void radeon_gpio_setscl(void* data, int state)
 {
 	struct radeon_i2c_chan 	*chan = data;
@@ -138,108 +136,10 @@
 	rinfo->i2c[3].rinfo = NULL;
 }
 
-
-static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan)
+int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
+			       u8 **out_edid)
 {
-	u8 start = 0x0;
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= RADEON_DDC,
-			.len	= 1,
-			.buf	= &start,
-		}, {
-			.addr	= RADEON_DDC,
-			.flags	= I2C_M_RD,
-			.len	= EDID_LENGTH,
-		},
-	};
-	u8 *buf;
-
-	buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-	if (!buf) {
-		dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n");
-		return NULL;
-	}
-	msgs[1].buf = buf;
-
-	if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
-		return buf;
-	dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n");
-	kfree(buf);
-	return NULL;
-}
-
-
-int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid)
-{
-	u32 reg = rinfo->i2c[conn-1].ddc_reg;
-	u8 *edid = NULL;
-	int i, j;
-
-	OUTREG(reg, INREG(reg) & 
-			~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
-
-	OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
-	(void)INREG(reg);
-
-	for (i = 0; i < 3; i++) {
-		/* For some old monitors we need the
-		 * following process to initialize/stop DDC
-		 */
-		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
-		(void)INREG(reg);
-		msleep(13);
-
-		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
-		(void)INREG(reg);
-		for (j = 0; j < 5; j++) {
-			msleep(10);
-			if (INREG(reg) & VGA_DDC_CLK_INPUT)
-				break;
-		}
-		if (j == 5)
-			continue;
-
-		OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
-		(void)INREG(reg);
-		msleep(15);
-		OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
-		(void)INREG(reg);
-		msleep(15);
-		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
-		(void)INREG(reg);
-		msleep(15);
-
-		/* Do the real work */
-		edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);
-
-		OUTREG(reg, INREG(reg) | 
-				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
-		(void)INREG(reg);
-		msleep(15);
-		
-		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
-		(void)INREG(reg);
-		for (j = 0; j < 10; j++) {
-			msleep(10);
-			if (INREG(reg) & VGA_DDC_CLK_INPUT)
-				break;
-		}
-
-		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
-		(void)INREG(reg);
-		msleep(15);
-		OUTREG(reg, INREG(reg) |
-				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
-		(void)INREG(reg);
-		if (edid)
-			break;
-	}
-	/* Release the DDC lines when done or the Apple Cinema HD display
-	 * will switch off
-	 */
-	OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN));
-	(void)INREG(reg);
+	u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
 
 	if (out_edid)
 		*out_edid = edid;
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 365de5d..9a2b0d6 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -86,6 +86,9 @@
 	BUGFIX("Samsung P35",
 	       PCI_VENDOR_ID_SAMSUNG, 0xc00c,
 	       radeon_pm_off, radeon_reinitialize_M10),
+	BUGFIX("Acer Aspire 2010",
+	       PCI_VENDOR_ID_AI, 0x0061,
+	       radeon_pm_off, radeon_reinitialize_M10),
 	{ .ident = NULL }
 };
 
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index f25d5d6..ef5c16f 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -8,6 +8,7 @@
  *  	<c.pellegrin@exadron.com>
  *
  * PM support added by Rodolfo Giometti <giometti@linux.it>
+ * Cursor enable/disable by Rodolfo Giometti <giometti@linux.it>
  *
  * Copyright 2002 MontaVista Software
  * Author: MontaVista Software, Inc.
@@ -110,6 +111,10 @@
 
 static struct au1100fb_drv_info drv_info;
 
+static int nocursor = 0;
+module_param(nocursor, int, 0644);
+MODULE_PARM_DESC(nocursor, "cursor enable/disable");
+
 /*
  * Set hardware with var settings. This will enable the controller with a specific
  * mode, normally validated with the fb_check_var method
@@ -422,6 +427,17 @@
 	return 0;
 }
 
+/* fb_cursor
+ * Used to disable cursor drawing...
+ */
+int au1100fb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	if (nocursor)
+		return 0;
+	else
+		return -EINVAL;	/* just to force soft_cursor() call */
+}
+
 static struct fb_ops au1100fb_ops =
 {
 	.owner			= THIS_MODULE,
@@ -433,6 +449,7 @@
 	.fb_imageblit		= cfb_imageblit,
 	.fb_rotate		= au1100fb_fb_rotate,
 	.fb_mmap		= au1100fb_fb_mmap,
+	.fb_cursor		= au1100fb_fb_cursor,
 };
 
 
@@ -677,7 +694,7 @@
 	if (options) {
 		while ((this_opt = strsep(&options,",")) != NULL) {
 			/* Panel option */
-		if (!strncmp(this_opt, "panel:", 6)) {
+			if (!strncmp(this_opt, "panel:", 6)) {
 				int i;
 				this_opt += 6;
 				for (i = 0; i < num_panels; i++) {
@@ -685,13 +702,18 @@
 					      	     known_lcd_panels[i].name,
 							strlen(this_opt))) {
 						panel_idx = i;
-					break;
+						break;
+					}
 				}
-			}
 				if (i >= num_panels) {
  					print_warn("Panel %s not supported!", this_opt);
 				}
 			}
+			if (!strncmp(this_opt, "nocursor", 8)) {
+				this_opt += 8;
+				nocursor = 1;
+				print_info("Cursor disabled");
+			}
 			/* Mode option (only option that start with digit) */
 			else if (isdigit(this_opt[0])) {
 				mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL);
@@ -700,7 +722,7 @@
 			/* Unsupported option */
 			else {
 				print_warn("Unsupported option \"%s\"", this_opt);
-		}
+			}
 		}
 	}
 
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 1b4f75d..8c041da 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -133,6 +133,7 @@
 
 /* console rotation */
 static int rotate;
+static int fbcon_has_sysfs;
 
 static const struct consw fb_con;
 
@@ -396,9 +397,8 @@
 		vc = vc_cons[ops->currcon].d;
 
 	if (!vc || !CON_IS_VISIBLE(vc) ||
-	    fbcon_is_inactive(vc, info) ||
  	    registered_fb[con2fb_map[vc->vc_num]] != info ||
-	    vc_cons[ops->currcon].d->vc_deccm != 1) {
+	    vc->vc_deccm != 1) {
 		release_console_sem();
 		return;
 	}
@@ -2166,7 +2166,12 @@
 			fbcon_del_cursor_timer(old_info);
 	}
 
-	fbcon_add_cursor_timer(info);
+	if (fbcon_is_inactive(vc, info) ||
+	    ops->blank_state != FB_BLANK_UNBLANK)
+		fbcon_del_cursor_timer(info);
+	else
+		fbcon_add_cursor_timer(info);
+
 	set_blitting_type(vc, info);
 	ops->cursor_reset = 1;
 
@@ -2276,10 +2281,11 @@
 			update_screen(vc);
 	}
 
-	if (!blank)
-		fbcon_add_cursor_timer(info);
-	else
+	if (fbcon_is_inactive(vc, info) ||
+	    ops->blank_state != FB_BLANK_UNBLANK)
 		fbcon_del_cursor_timer(info);
+	else
+		fbcon_add_cursor_timer(info);
 
 	return 0;
 }
@@ -3161,11 +3167,26 @@
 
 static int fbcon_init_class_device(void)
 {
-	int i;
+	int i, error = 0;
 
-	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_create_file(fbcon_class_device,
-					 &class_device_attrs[i]);
+	fbcon_has_sysfs = 1;
+
+	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+		error = class_device_create_file(fbcon_class_device,
+						 &class_device_attrs[i]);
+
+		if (error)
+			break;
+	}
+
+	if (error) {
+		while (--i >= 0)
+			class_device_remove_file(fbcon_class_device,
+						 &class_device_attrs[i]);
+
+		fbcon_has_sysfs = 0;
+	}
+
 	return 0;
 }
 
@@ -3225,7 +3246,10 @@
 			module_put(info->fbops->owner);
 
 			if (info->fbcon_par) {
+				struct fbcon_ops *ops = info->fbcon_par;
+
 				fbcon_del_cursor_timer(info);
+				kfree(ops->cursor_src);
 				kfree(info->fbcon_par);
 				info->fbcon_par = NULL;
 			}
@@ -3271,9 +3295,13 @@
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_remove_file(fbcon_class_device,
-					 &class_device_attrs[i]);
+	if (fbcon_has_sysfs) {
+		for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+			class_device_remove_file(fbcon_class_device,
+						 &class_device_attrs[i]);
+
+		fbcon_has_sysfs = 0;
+	}
 }
 
 static void __exit fb_console_exit(void)
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index f244ad0..b9386d1 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -80,6 +80,8 @@
 	char  *cursor_data;
 	u8    *fontbuffer;
 	u8    *fontdata;
+	u8    *cursor_src;
+	u32    cursor_size;
 	u32    fd_size;
 };
     /*
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 4481c80..825e6d6 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -391,7 +391,7 @@
 	ops->cursor_reset = 0;
 }
 
-int ccw_update_start(struct fb_info *info)
+static int ccw_update_start(struct fb_info *info)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
 	u32 yoffset;
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index 7f92c06..c637e63 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -375,7 +375,7 @@
 	ops->cursor_reset = 0;
 }
 
-int cw_update_start(struct fb_info *info)
+static int cw_update_start(struct fb_info *info)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
 	u32 vxres = GETVXRES(ops->p->scrollmode, info);
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index ab91005..1473506 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -415,7 +415,7 @@
 	ops->cursor_reset = 0;
 }
 
-int ud_update_start(struct fb_info *info)
+static int ud_update_start(struct fb_info *info)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
 	int xoffset, yoffset;
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 557c563..7d07d83 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -20,11 +20,12 @@
 
 int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
+	struct fbcon_ops *ops = info->fbcon_par;
 	unsigned int scan_align = info->pixmap.scan_align - 1;
 	unsigned int buf_align = info->pixmap.buf_align - 1;
 	unsigned int i, size, dsize, s_pitch, d_pitch;
 	struct fb_image *image;
-	u8 *dst, *src;
+	u8 *dst;
 
 	if (info->state != FBINFO_STATE_RUNNING)
 		return 0;
@@ -32,11 +33,19 @@
 	s_pitch = (cursor->image.width + 7) >> 3;
 	dsize = s_pitch * cursor->image.height;
 
-	src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC);
-	if (!src)
-		return -ENOMEM;
+	if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
+		if (ops->cursor_src != NULL)
+			kfree(ops->cursor_src);
+		ops->cursor_size = dsize + sizeof(struct fb_image);
 
-	image = (struct fb_image *) (src + dsize);
+		ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
+		if (!ops->cursor_src) {
+			ops->cursor_size = 0;
+			return -ENOMEM;
+		}
+	}
+
+	image = (struct fb_image *) (ops->cursor_src + dsize);
 	*image = cursor->image;
 	d_pitch = (s_pitch + scan_align) & ~scan_align;
 
@@ -48,21 +57,23 @@
 		switch (cursor->rop) {
 		case ROP_XOR:
 			for (i = 0; i < dsize; i++)
-				src[i] = image->data[i] ^ cursor->mask[i];
+				ops->cursor_src[i] = image->data[i] ^
+					cursor->mask[i];
 			break;
 		case ROP_COPY:
 		default:
 			for (i = 0; i < dsize; i++)
-				src[i] = image->data[i] & cursor->mask[i];
+				ops->cursor_src[i] = image->data[i] &
+					cursor->mask[i];
 			break;
 		}
 	} else
-		memcpy(src, image->data, dsize);
+		memcpy(ops->cursor_src, image->data, dsize);
 
-	fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
+	fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch,
+			      image->height);
 	image->data = dst;
 	info->fbops->fb_imageblit(info, image);
-	kfree(src);
 	return 0;
 }
 
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c
new file mode 100644
index 0000000..3aa6ebf
--- /dev/null
+++ b/drivers/video/fb_ddc.c
@@ -0,0 +1,116 @@
+/*
+ * driver/vide/fb_ddc.c - DDC/EDID read support.
+ *
+ *  Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
+ *
+ * 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/delay.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/i2c-algo-bit.h>
+
+#include "edid.h"
+
+#define DDC_ADDR	0x50
+
+static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter)
+{
+	unsigned char start = 0x0;
+	struct i2c_msg msgs[] = {
+		{
+			.addr	= DDC_ADDR,
+			.len	= 1,
+			.buf	= &start,
+		}, {
+			.addr	= DDC_ADDR,
+			.flags	= I2C_M_RD,
+			.len	= EDID_LENGTH,
+		}
+	};
+	unsigned char *buf;
+
+	buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+	if (!buf) {
+		dev_warn(&adapter->dev, "unable to allocate memory for EDID "
+			 "block.\n");
+		return NULL;
+	}
+	msgs[1].buf = buf;
+
+	if (i2c_transfer(adapter, msgs, 2) == 2)
+		return buf;
+
+	dev_warn(&adapter->dev, "unable to read EDID block.\n");
+	kfree(buf);
+	return NULL;
+}
+
+unsigned char *fb_ddc_read(struct i2c_adapter *adapter)
+{
+	struct i2c_algo_bit_data *algo_data = adapter->algo_data;
+	unsigned char *edid = NULL;
+	int i, j;
+
+	algo_data->setscl(algo_data->data, 1);
+	algo_data->setscl(algo_data->data, 0);
+
+	for (i = 0; i < 3; i++) {
+		/* For some old monitors we need the
+		 * following process to initialize/stop DDC
+		 */
+		algo_data->setsda(algo_data->data, 0);
+		msleep(13);
+
+		algo_data->setscl(algo_data->data, 1);
+		for (j = 0; j < 5; j++) {
+			msleep(10);
+			if (algo_data->getscl(algo_data->data))
+				break;
+		}
+		if (j == 5)
+			continue;
+
+		algo_data->setsda(algo_data->data, 0);
+		msleep(15);
+		algo_data->setscl(algo_data->data, 0);
+		msleep(15);
+		algo_data->setsda(algo_data->data, 1);
+		msleep(15);
+
+		/* Do the real work */
+		edid = fb_do_probe_ddc_edid(adapter);
+		algo_data->setsda(algo_data->data, 0);
+		algo_data->setscl(algo_data->data, 0);
+		msleep(15);
+
+		algo_data->setscl(algo_data->data, 1);
+		for (j = 0; j < 10; j++) {
+			msleep(10);
+			if (algo_data->getscl(algo_data->data))
+				break;
+		}
+
+		algo_data->setsda(algo_data->data, 1);
+		msleep(15);
+		algo_data->setscl(algo_data->data, 0);
+		if (edid)
+			break;
+	}
+	/* Release the DDC lines when done or the Apple Cinema HD display
+	 * will switch off
+	 */
+	algo_data->setsda(algo_data->data, 0);
+	algo_data->setscl(algo_data->data, 0);
+
+	return edid;
+}
+
+EXPORT_SYMBOL_GPL(fb_ddc_read);
+
+MODULE_AUTHOR("Dennis Munsie <dmunsie@cecropia.com>");
+MODULE_DESCRIPTION("DDC/EDID reading support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 17961e3..93ffcdd 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -554,7 +554,8 @@
 	int clen;
 
 	clen = 0;
-	for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
+	for (fi = registered_fb; fi < &registered_fb[FB_MAX] && clen < 4000;
+	     fi++)
 		if (*fi)
 			clen += sprintf(buf + clen, "%d %s\n",
 				        (*fi)->node,
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index c151dcf..d3a5041 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -20,6 +20,8 @@
 #include <linux/console.h>
 #include <linux/module.h>
 
+#define FB_SYSFS_FLAG_ATTR 1
+
 /**
  * framebuffer_alloc - creates a new frame buffer info structure
  *
@@ -483,12 +485,27 @@
 
 int fb_init_class_device(struct fb_info *fb_info)
 {
-	unsigned int i;
+	int i, error = 0;
+
 	class_set_devdata(fb_info->class_device, fb_info);
 
-	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_create_file(fb_info->class_device,
-					 &class_device_attrs[i]);
+	fb_info->class_flag |= FB_SYSFS_FLAG_ATTR;
+
+	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+		error = class_device_create_file(fb_info->class_device,
+						 &class_device_attrs[i]);
+
+		if (error)
+			break;
+	}
+
+	if (error) {
+		while (--i >= 0)
+			class_device_remove_file(fb_info->class_device,
+						 &class_device_attrs[i]);
+		fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
+	}
+
 	return 0;
 }
 
@@ -496,9 +513,13 @@
 {
 	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_remove_file(fb_info->class_device,
-					 &class_device_attrs[i]);
+	if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) {
+		for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+			class_device_remove_file(fb_info->class_device,
+						 &class_device_attrs[i]);
+
+		fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
+	}
 }
 
 #ifdef CONFIG_FB_BACKLIGHT
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 7d06b38..b38d805 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -19,7 +19,6 @@
 #include "i810_main.h"
 #include "../edid.h"
 
-#define I810_DDC 0x50
 /* bit locations in the registers */
 #define SCL_DIR_MASK		0x0001
 #define SCL_DIR			0x0002
@@ -150,53 +149,14 @@
 	par->chan[2].par = NULL;
 }
 
-static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
-{
-        u8 start = 0x0;
-        struct i2c_msg msgs[] = {
-                {
-                        .addr   = I810_DDC,
-                        .len    = 1,
-                        .buf    = &start,
-                }, {
-                        .addr   = I810_DDC,
-                        .flags  = I2C_M_RD,
-                        .len    = EDID_LENGTH,
-                },
-        };
-        u8 *buf;
-
-        buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-        if (!buf) {
-		DPRINTK("i810-i2c: Failed to allocate memory\n");
-                return NULL;
-        }
-        msgs[1].buf = buf;
-
-        if (i2c_transfer(&chan->adapter, msgs, 2) == 2) {
-		DPRINTK("i810-i2c: I2C Transfer successful\n");
-                return buf;
-	}
-
-        DPRINTK("i810-i2c: Unable to read EDID block.\n");
-        kfree(buf);
-        return NULL;
-}
-
 int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
 {
 	struct i810fb_par *par = info->par;
         u8 *edid = NULL;
-        int i;
 
 	DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn+1);
 	if (conn < par->ddc_num) {
-		for (i = 0; i < 3; i++) {
-			/* Do the real work */
-			edid = i810_do_probe_i2c_edid(&par->chan[conn]);
-			if (edid)
-				break;
-		}
+		edid = fb_ddc_read(&par->chan[conn].adapter);
 	} else {
 		const u8 *e = fb_firmware_edid(info->device);
 
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index d42edac..b55a12d 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1602,7 +1602,10 @@
 	acquire_console_sem();
 	pci_set_power_state(dev, PCI_D0);
 	pci_restore_state(dev);
-	pci_enable_device(dev);
+
+	if (pci_enable_device(dev))
+		goto fail;
+
 	pci_set_master(dev);
 	agp_bind_memory(par->i810_gtt.i810_fb_memory,
 			par->fb.offset);
@@ -1611,6 +1614,7 @@
 	i810fb_set_par(info);
 	fb_set_suspend (info, 0);
 	info->fbops->fb_blank(VESA_NO_BLANKING, info);
+fail:
 	release_console_sem();
 	return 0;
 }
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 4a57dab..7acf01c 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -2277,10 +2277,13 @@
 	}
 }
 
-static void __init matrox_init(void) {
+static int __init matrox_init(void) {
+	int err;
+
 	matroxfb_init_params();
-	pci_register_driver(&matroxfb_driver);
+	err = pci_register_driver(&matroxfb_driver);
 	dev = -1;	/* accept all new devices... */
+	return err;
 }
 
 /* **************************** exit-time only **************************** */
@@ -2437,6 +2440,7 @@
 static int __init matroxfb_init(void)
 {
 	char *option = NULL;
+	int err = 0;
 
 	DBG(__FUNCTION__)
 
@@ -2448,11 +2452,11 @@
 		return -ENXIO;
 	if (!initialized) {
 		initialized = 1;
-		matrox_init();
+		err = matrox_init();
 	}
 	hotplug = 1;
 	/* never return failure, user can hotplug matrox later... */
-	return 0;
+	return err;
 }
 
 module_init(matroxfb_init);
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 6849ab7..a32d1af 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -118,8 +118,19 @@
 	/* convert pixclock to KHz */
 	pixclock = PICOS2KHZ(pixclock_ps);
 
+	/* PLL output freq = (ref_clk * M) / (N * 2^P)
+	 *
+	 * M: 1 to 63
+	 * N: 1 to 7
+	 * P: 0 to 7
+	 */
+
+	/* RAPH: When N==1, the resulting pixel clock appears to
+	 * get divided by 2. Preventing N=1 by starting the following
+	 * loop at 2 prevents this. Is this a bug with my chip
+	 * revision or something I dont understand? */
 	for (m = 1; m < 64; m++) {
-		for (n = 1; n < 8; n++) {
+		for (n = 2; n < 8; n++) {
 			for (p = 0; p < 8; p++) {
 				clk = (ref_clk * m) / (n * (1 << p));
 				err = (clk > pixclock) ? (clk - pixclock) :
@@ -244,8 +255,8 @@
 
 	/* setup resolution */
 	gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
-	gsctrl |= Gsctrl_Width(info->var.xres - 1) |
-		Gsctrl_Height(info->var.yres - 1);
+	gsctrl |= Gsctrl_Width(info->var.xres) |
+		Gsctrl_Height(info->var.yres);
 	writel(gsctrl, GSCTRL);
 	udelay(1000);
 
@@ -402,8 +413,8 @@
 {
 	unsigned long gsctrl;
 
-	gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) |
-		Gsctrl_Height(fbi->var.yres - 1);
+	gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |
+		Gsctrl_Height(fbi->var.yres);
 	switch (fbi->var.bits_per_pixel) {
 	case 16:
 		if (fbi->var.green.length == 5)
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 19eef3a..e48de3c 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -160,51 +160,12 @@
 
 }
 
-static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
-{
-	u8 start = 0x0;
-	struct i2c_msg msgs[] = {
-		{
-		 .addr = 0x50,
-		 .len = 1,
-		 .buf = &start,
-		 }, {
-		     .addr = 0x50,
-		     .flags = I2C_M_RD,
-		     .len = EDID_LENGTH,
-		     },
-	};
-	u8 *buf;
-
-	if (!chan->par)
-		return NULL;
-
-	buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-	if (!buf) {
-		dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n");
-		return NULL;
-	}
-	msgs[1].buf = buf;
-
-	if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
-		return buf;
-	dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n");
-	kfree(buf);
-	return NULL;
-}
-
 int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
 {
 	struct nvidia_par *par = info->par;
-	u8 *edid = NULL;
-	int i;
+	u8 *edid;
 
-	for (i = 0; i < 3; i++) {
-		/* Do the real work */
-		edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]);
-		if (edid)
-			break;
-	}
+	edid = fb_ddc_read(&par->chan[conn - 1].adapter);
 
 	if (!edid && conn == 1) {
 		/* try to get from firmware */
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index f8cd4c5..eb24107 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -28,6 +28,9 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #endif
+#ifdef CONFIG_BOOTX_TEXT
+#include <asm/btext.h>
+#endif
 
 #include "nv_local.h"
 #include "nv_type.h"
@@ -681,6 +684,13 @@
 
 	nvidia_vga_protect(par, 0);
 
+#ifdef CONFIG_BOOTX_TEXT
+	/* Update debug text engine */
+	btext_update_display(info->fix.smem_start,
+			     info->var.xres, info->var.yres,
+			     info->var.bits_per_pixel, info->fix.line_length);
+#endif
+
 	NVTRACE_LEAVE();
 	return 0;
 }
@@ -984,7 +994,10 @@
 
 	if (par->pm_state != PM_EVENT_FREEZE) {
 		pci_restore_state(dev);
-		pci_enable_device(dev);
+
+		if (pci_enable_device(dev))
+			goto fail;
+
 		pci_set_master(dev);
 	}
 
@@ -993,6 +1006,7 @@
 	fb_set_suspend (info, 0);
 	nvidiafb_blank(FB_BLANK_UNBLANK, info);
 
+fail:
 	release_console_sem();
 	return 0;
 }
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index bbb0710..3bc5da4 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -59,7 +59,7 @@
 #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP|LCCR3_VSP|LCCR3_PCD|LCCR3_BPP)
 
 static void (*pxafb_backlight_power)(int);
-static void (*pxafb_lcd_power)(int);
+static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 
 static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *);
 static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
@@ -214,6 +214,48 @@
 #endif
 
 /*
+ * Select the smallest mode that allows the desired resolution to be
+ * displayed. If desired parameters can be rounded up.
+ */
+static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struct fb_var_screeninfo *var)
+{
+	struct pxafb_mode_info *mode = NULL;
+	struct pxafb_mode_info *modelist = mach->modes;
+	unsigned int best_x = 0xffffffff, best_y = 0xffffffff;
+	unsigned int i;
+
+	for (i = 0 ; i < mach->num_modes ; i++) {
+		if (modelist[i].xres >= var->xres && modelist[i].yres >= var->yres &&
+				modelist[i].xres < best_x && modelist[i].yres < best_y &&
+				modelist[i].bpp >= var->bits_per_pixel ) {
+			best_x = modelist[i].xres;
+			best_y = modelist[i].yres;
+			mode = &modelist[i];
+		}
+	}
+
+	return mode;
+}
+
+static void pxafb_setmode(struct fb_var_screeninfo *var, struct pxafb_mode_info *mode)
+{
+	var->xres		= mode->xres;
+	var->yres		= mode->yres;
+	var->bits_per_pixel	= mode->bpp;
+	var->pixclock		= mode->pixclock;
+	var->hsync_len		= mode->hsync_len;
+	var->left_margin	= mode->left_margin;
+	var->right_margin	= mode->right_margin;
+	var->vsync_len		= mode->vsync_len;
+	var->upper_margin	= mode->upper_margin;
+	var->lower_margin	= mode->lower_margin;
+	var->sync		= mode->sync;
+	var->grayscale		= mode->cmap_greyscale;
+	var->xres_virtual 	= var->xres;
+	var->yres_virtual	= var->yres;
+}
+
+/*
  *  pxafb_check_var():
  *    Get the video params out of 'var'. If a value doesn't fit, round it up,
  *    if it's too big, return -EINVAL.
@@ -225,15 +267,29 @@
 static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
 	struct pxafb_info *fbi = (struct pxafb_info *)info;
+	struct pxafb_mach_info *inf = fbi->dev->platform_data;
 
 	if (var->xres < MIN_XRES)
 		var->xres = MIN_XRES;
 	if (var->yres < MIN_YRES)
 		var->yres = MIN_YRES;
-	if (var->xres > fbi->max_xres)
-		return -EINVAL;
-	if (var->yres > fbi->max_yres)
-		return -EINVAL;
+
+	if (inf->fixed_modes) {
+		struct pxafb_mode_info *mode;
+
+		mode = pxafb_getmode(inf, var);
+		if (!mode)
+			return -EINVAL;
+		pxafb_setmode(var, mode);
+	} else {
+		if (var->xres > inf->modes->xres)
+			return -EINVAL;
+		if (var->yres > inf->modes->yres)
+			return -EINVAL;
+		if (var->bits_per_pixel > inf->modes->bpp)
+			return -EINVAL;
+	}
+
 	var->xres_virtual =
 		max(var->xres_virtual, var->xres);
 	var->yres_virtual =
@@ -693,7 +749,7 @@
 	pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff");
 
 	if (pxafb_lcd_power)
-		pxafb_lcd_power(on);
+		pxafb_lcd_power(on, &fbi->fb.var);
 }
 
 static void pxafb_setup_gpio(struct pxafb_info *fbi)
@@ -869,9 +925,11 @@
 		 * registers.
 		 */
 		if (old_state == C_ENABLE) {
+			__pxafb_lcd_power(fbi, 0);
 			pxafb_disable_controller(fbi);
 			pxafb_setup_gpio(fbi);
 			pxafb_enable_controller(fbi);
+			__pxafb_lcd_power(fbi, 1);
 		}
 		break;
 
@@ -1049,6 +1107,8 @@
 	struct pxafb_info *fbi;
 	void *addr;
 	struct pxafb_mach_info *inf = dev->platform_data;
+	struct pxafb_mode_info *mode = inf->modes;
+	int i, smemlen;
 
 	/* Alloc the pxafb_info and pseudo_palette in one step */
 	fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
@@ -1082,31 +1142,21 @@
 	addr = addr + sizeof(struct pxafb_info);
 	fbi->fb.pseudo_palette	= addr;
 
-	fbi->max_xres			= inf->xres;
-	fbi->fb.var.xres		= inf->xres;
-	fbi->fb.var.xres_virtual	= inf->xres;
-	fbi->max_yres			= inf->yres;
-	fbi->fb.var.yres		= inf->yres;
-	fbi->fb.var.yres_virtual	= inf->yres;
-	fbi->max_bpp			= inf->bpp;
-	fbi->fb.var.bits_per_pixel	= inf->bpp;
-	fbi->fb.var.pixclock		= inf->pixclock;
-	fbi->fb.var.hsync_len		= inf->hsync_len;
-	fbi->fb.var.left_margin		= inf->left_margin;
-	fbi->fb.var.right_margin	= inf->right_margin;
-	fbi->fb.var.vsync_len		= inf->vsync_len;
-	fbi->fb.var.upper_margin	= inf->upper_margin;
-	fbi->fb.var.lower_margin	= inf->lower_margin;
-	fbi->fb.var.sync		= inf->sync;
-	fbi->fb.var.grayscale		= inf->cmap_greyscale;
+	pxafb_setmode(&fbi->fb.var, mode);
+
 	fbi->cmap_inverse		= inf->cmap_inverse;
 	fbi->cmap_static		= inf->cmap_static;
+
 	fbi->lccr0			= inf->lccr0;
 	fbi->lccr3			= inf->lccr3;
 	fbi->state			= C_STARTUP;
 	fbi->task_state			= (u_char)-1;
-	fbi->fb.fix.smem_len		= fbi->max_xres * fbi->max_yres *
-					  fbi->max_bpp / 8;
+
+	for (i = 0; i < inf->num_modes; i++) {
+		smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8;
+		if (smemlen > fbi->fb.fix.smem_len)
+			fbi->fb.fix.smem_len = smemlen;
+	}
 
 	init_waitqueue_head(&fbi->ctrlr_wait);
 	INIT_WORK(&fbi->task, pxafb_task, fbi);
@@ -1307,12 +1357,12 @@
 	    (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                 dev_warn(&dev->dev, "Dual panel only valid in passive mode\n");
         if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
-             (inf->upper_margin || inf->lower_margin))
+             (inf->modes->upper_margin || inf->modes->lower_margin))
                 dev_warn(&dev->dev, "Upper and lower margins must be 0 in passive mode\n");
 #endif
 
-	dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->xres, inf->yres, inf->bpp);
-	if (inf->xres == 0 || inf->yres == 0 || inf->bpp == 0) {
+	dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->modes->xres, inf->modes->yres, inf->modes->bpp);
+	if (inf->modes->xres == 0 || inf->modes->yres == 0 || inf->modes->bpp == 0) {
 		dev_err(&dev->dev, "Invalid resolution or bit depth\n");
 		ret = -EINVAL;
 		goto failed;
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 47f41f7..7499a1c 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -41,10 +41,6 @@
 	struct fb_info		fb;
 	struct device		*dev;
 
-	u_int			max_bpp;
-	u_int			max_xres;
-	u_int			max_yres;
-
 	/*
 	 * These are the addresses we mapped
 	 * the framebuffer memory region to.
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 4acde4f..a433cc7 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -393,8 +393,8 @@
 	mutex_lock(&info->bl_mutex);
 	info->bl_dev = bd;
 	fb_bl_default_curve(info, 0,
-		0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
-		0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
+		MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
+		FB_BACKLIGHT_MAX);
 	mutex_unlock(&info->bl_mutex);
 
 	down(&bd->sem);
@@ -784,7 +784,7 @@
 	
 	NVTRACE_ENTER();
 	/* time to calculate */
-	rivafb_blank(1, info);
+	rivafb_blank(FB_BLANK_NORMAL, info);
 
 	bpp = info->var.bits_per_pixel;
 	if (bpp == 16 && info->var.green.length == 5)
@@ -917,7 +917,7 @@
 	par->current_state = newmode;
 	riva_load_state(par, &par->current_state);
 	par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
-	rivafb_blank(0, info);
+	rivafb_blank(FB_BLANK_UNBLANK, info);
 	NVTRACE_LEAVE();
 }
 
@@ -1843,7 +1843,7 @@
 		for (i = 0; propnames[i] != NULL; ++i) {
 			pedid = get_property(dp, propnames[i], NULL);
 			if (pedid != NULL) {
-				par->EDID = pedid;
+				par->EDID = (unsigned char *)pedid;
 				NVTRACE("LCD found.\n");
 				return 1;
 			}
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 9751c37..c15b259 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -25,8 +25,6 @@
 #include "rivafb.h"
 #include "../edid.h"
 
-#define RIVA_DDC 	0x50
-
 static void riva_gpio_setscl(void* data, int state)
 {
 	struct riva_i2c_chan 	*chan = data;
@@ -158,50 +156,12 @@
 	par->chan[2].par = NULL;
 }
 
-static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan)
-{
-	u8 start = 0x0;
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= RIVA_DDC,
-			.len	= 1,
-			.buf	= &start,
-		}, {
-			.addr	= RIVA_DDC,
-			.flags	= I2C_M_RD,
-			.len	= EDID_LENGTH,
-		},
-	};
-	u8 *buf;
-
-	if (!chan->par)
-		return NULL;
-
-	buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-	if (!buf) {
-		dev_warn(&chan->par->pdev->dev, "Out of memory!\n");
-		return NULL;
-	}
-	msgs[1].buf = buf;
-
-	if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
-		return buf;
-	dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n");
-	kfree(buf);
-	return NULL;
-}
-
 int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
 {
 	u8 *edid = NULL;
-	int i;
 
-	for (i = 0; i < 3; i++) {
-		/* Do the real work */
-		edid = riva_do_probe_i2c_edid(&par->chan[conn-1]);
-		if (edid)
-			break;
-	}
+	edid = fb_ddc_read(&par->chan[conn-1].adapter);
+
 	if (out_edid)
 		*out_edid = edid;
 	if (!edid)
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index be40968..f3f8a8e 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/s3c2410fb.h
+ * linux/drivers/video/s3c2410fb.h
  * Copyright (c) Arnaud Patard
  *
  * This file is subject to the terms and conditions of the GNU General Public
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index d7d810db..3f94223 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -213,52 +213,15 @@
 	par->chan.par = NULL;
 }
 
-static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
-{
-	u8 start = 0x0;
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= SAVAGE_DDC,
-			.len	= 1,
-			.buf	= &start,
-		}, {
-			.addr	= SAVAGE_DDC,
-			.flags	= I2C_M_RD,
-			.len	= EDID_LENGTH,
-		},
-	};
-	u8 *buf = NULL;
-
-	if (chan->par) {
-		buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-
-		if (buf) {
-			msgs[1].buf = buf;
-
-			if (i2c_transfer(&chan->adapter, msgs, 2) != 2) {
-				dev_dbg(&chan->par->pcidev->dev,
-					"Unable to read EDID block.\n");
-				kfree(buf);
-				buf = NULL;
-			}
-		}
-	}
-
-	return buf;
-}
-
 int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
 {
 	struct savagefb_par *par = info->par;
-	u8 *edid = NULL;
-	int i;
+	u8 *edid;
 
-	for (i = 0; i < 3; i++) {
-		/* Do the real work */
-		edid = savage_do_probe_i2c_edid(&par->chan);
-		if (edid)
-			break;
-	}
+	if (par->chan.par)
+		edid = fb_ddc_read(&par->chan.adapter);
+	else
+		edid = NULL;
 
 	if (!edid) {
 		/* try to get from firmware */
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 7ecab87..59d1284 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -77,16 +77,9 @@
 #include <linux/types.h>
 #include <asm/io.h>
 #include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#endif
 #include "sis.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
 #include <video/sisfb.h>
 #endif
-#endif
 
 /* Mode numbers */
 static const unsigned short ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index bc321dc..4f3a286 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -71,16 +71,9 @@
 #include <linux/types.h>
 #include <asm/io.h>
 #include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#endif
 #include "sis.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
 #include <video/sisfb.h>
 #endif
-#endif
 
 static const unsigned char SiS_YPbPrTable[3][64] = {
   {
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index 09f5d75..c3884a2 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -34,12 +34,10 @@
 #include <linux/types.h>
 #include <linux/fb.h>
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 int		sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
 			unsigned char modeno, unsigned char rateindex);
 int		sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
 			unsigned char rateindex, struct fb_var_screeninfo *var);
-#endif
 BOOLEAN		sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
 			int *htotal, int *vtotal, unsigned char rateindex);
 
@@ -49,7 +47,6 @@
 extern void	SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
 			int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 int
 sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
 			unsigned char rateindex)
@@ -177,7 +174,6 @@
 
     return 1;
 }
-#endif /* Linux >= 2.5 */
 
 BOOLEAN
 sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index f595680..d048bd3 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -100,11 +100,7 @@
 #define SIS315H
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #define SIS_LINUX_KERNEL_26
-#else
-#define SIS_LINUX_KERNEL_24
-#endif
 
 #if !defined(SIS300) && !defined(SIS315H)
 #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
index 3b7ce03..7addf91 100644
--- a/drivers/video/sis/sis_accel.c
+++ b/drivers/video/sis/sis_accel.c
@@ -32,22 +32,10 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/console.h>
-#endif
 #include <linux/ioport.h>
 #include <linux/types.h>
-
 #include <asm/io.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#endif
-
 #include "sis.h"
 #include "sis_accel.h"
 
@@ -91,11 +79,9 @@
     0xFF,       /* dest = 0xFF;         1,      GXset,          0xF */
 };
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
 static const int myrops[] = {
    	3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
 };
-#endif
 
 /* 300 series ----------------------------------------------------- */
 #ifdef CONFIG_FB_SIS_300
@@ -315,8 +301,6 @@
 	}
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  /* --------------- 2.5 --------------- */
-
 int fbcon_sis_sync(struct fb_info *info)
 {
 	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
@@ -438,13 +422,3 @@
 
 	sisfb_syncaccel(ivideo);
 }
-
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* -------------- 2.4 --------------- */
-
-#include "sisfb_accel_2_4.h"
-
-#endif /* KERNEL VERSION */
-
-
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h
index 046e2c4..30e03cd 100644
--- a/drivers/video/sis/sis_accel.h
+++ b/drivers/video/sis/sis_accel.h
@@ -390,25 +390,11 @@
 	MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \
 	CmdQueLen -= 2;
 
-
 int  sisfb_initaccel(struct sis_video_info *ivideo);
 void sisfb_syncaccel(struct sis_video_info *ivideo);
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
-void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty,
-			int dstx, int height, int width);
-void fbcon_sis_revc(struct display *p, int srcy, int srcx);
-void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy,
-			int srcx, int height, int width);
-void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy,
-			int srcx, int height, int width);
-void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
-			int srcx, int height, int width);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
 int  fbcon_sis_sync(struct fb_info *info);
 void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
 void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-#endif
 
 #endif
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 895ebda..baaf495 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -35,9 +35,7 @@
 
 #include <linux/version.h>
 #include <linux/module.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #include <linux/moduleparam.h>
-#endif
 #include <linux/kernel.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
@@ -58,9 +56,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/vt_kern.h>
-#endif
 #include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/types.h>
@@ -70,35 +65,9 @@
 #include <asm/mtrr.h>
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#endif
-
 #include "sis.h"
 #include "sis_main.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
-#error "This version of sisfb requires at least 2.6.3"
-#endif
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef FBCON_HAS_CFB8
-extern struct display_switch fbcon_sis8;
-#endif
-#ifdef FBCON_HAS_CFB16
-extern struct display_switch fbcon_sis16;
-#endif
-#ifdef FBCON_HAS_CFB32
-extern struct display_switch fbcon_sis32;
-#endif
-#endif
-
 static void sisfb_handle_command(struct sis_video_info *ivideo,
 				 struct sisfb_cmd *sisfb_command);
 
@@ -114,17 +83,7 @@
 	sisfb_max		= -1;
 	sisfb_userom		= -1;
 	sisfb_useoem		= -1;
-#ifdef MODULE
-	/* Module: "None" for 2.4, default mode for 2.5+ */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 	sisfb_mode_idx		= -1;
-#else
-	sisfb_mode_idx		= MODE_INDEX_NONE;
-#endif
-#else
-	/* Static: Default mode */
-	sisfb_mode_idx		= -1;
-#endif
 	sisfb_parm_rate		= -1;
 	sisfb_crt1off		= 0;
 	sisfb_forcecrt1		= -1;
@@ -142,10 +101,6 @@
 	sisfb_tvxposoffset	= 0;
 	sisfb_tvyposoffset	= 0;
 	sisfb_nocrt2rate	= 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	sisfb_inverse		= 0;
-	sisfb_fontname[0]	= 0;
-#endif
 #if !defined(__i386__) && !defined(__x86_64__)
 	sisfb_resetcard		= 0;
 	sisfb_videoram		= 0;
@@ -162,14 +117,11 @@
 	/* We don't know the hardware specs yet and there is no ivideo */
 
 	if(vesamode == 0) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		sisfb_mode_idx = MODE_INDEX_NONE;
-#else
 		if(!quiet)
 			printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
 
 		sisfb_mode_idx = DEFAULT_MODE;
-#endif
+
 		return;
 	}
 
@@ -215,7 +167,6 @@
 		return;
 	}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 	if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
 		if(!quiet)
 			printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
@@ -223,7 +174,7 @@
 		sisfb_mode_idx = DEFAULT_MODE;
 		return;
 	}
-#endif
+
 	if(strlen(name) <= 19) {
 		strcpy(strbuf1, name);
 		for(i = 0; i < strlen(strbuf1); i++) {
@@ -1315,20 +1266,7 @@
 		ivideo->refresh_rate = 60;
 	}
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	if(ivideo->sisfb_thismonitor.datavalid) {
-		if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
-	                         ivideo->rate_idx, ivideo->refresh_rate)) {
-			printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
-		}
-	}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
-#else
 	if(isactive) {
-#endif
 		/* If acceleration to be used? Need to know
 		 * before pre/post_set_mode()
 		 */
@@ -1367,9 +1305,7 @@
 		ivideo->current_linelength = ivideo->video_linelength;
 		ivideo->current_pixclock = var->pixclock;
 		ivideo->current_refresh_rate = ivideo->refresh_rate;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 		ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
-#endif
 	}
 
 	return 0;
@@ -1435,18 +1371,6 @@
 	return 0;
 }
 
-/* ------------ FBDev related routines for 2.4 series ----------- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
-#include "sisfb_fbdev_2_4.h"
-
-#endif
-
-/* ------------ FBDev related routines for 2.6 series ----------- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-
 static int
 sisfb_open(struct fb_info *info, int user)
 {
@@ -1744,8 +1668,6 @@
 	return sisfb_myblank(ivideo, blank);
 }
 
-#endif
-
 /* ----------- FBDev related routines for all series ---------- */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
@@ -1969,20 +1891,6 @@
 
 /* ----------------  fb_ops structures ----------------- */
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static struct fb_ops sisfb_ops = {
-	.owner		= THIS_MODULE,
-	.fb_get_fix	= sisfb_get_fix,
-	.fb_get_var	= sisfb_get_var,
-	.fb_set_var	= sisfb_set_var,
-	.fb_get_cmap	= sisfb_get_cmap,
-	.fb_set_cmap	= sisfb_set_cmap,
-	.fb_pan_display = sisfb_pan_display,
-	.fb_ioctl	= sisfb_ioctl
-};
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct fb_ops sisfb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_open	= sisfb_open,
@@ -2004,7 +1912,6 @@
 #endif
 	.fb_ioctl	= sisfb_ioctl
 };
-#endif
 
 /* ---------------- Chip generation dependent routines ---------------- */
 
@@ -4100,16 +4007,6 @@
 			sisfb_search_mode(this_opt + 5, FALSE);
 		} else if(!strnicmp(this_opt, "vesa:", 5)) {
 			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		} else if(!strnicmp(this_opt, "inverse", 7)) {
-			sisfb_inverse = 1;
-			/* fb_invert_cmaps(); */
-		} else if(!strnicmp(this_opt, "font:", 5)) {
-			if(strlen(this_opt + 5) < 40) {
-			   strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
-			   sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
-			}
-#endif
 		} else if(!strnicmp(this_opt, "rate:", 5)) {
 			sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
 		} else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
@@ -5870,17 +5767,9 @@
 	if(sisfb_off)
 		return -ENXIO;
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
 	sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
 	if(!sis_fb_info)
 		return -ENOMEM;
-#else
-	sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
-	if(!sis_fb_info)
-		return -ENOMEM;
-	memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
-	sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
-#endif
 
 	ivideo = (struct sis_video_info *)sis_fb_info->par;
 	ivideo->memyselfandi = sis_fb_info;
@@ -5970,10 +5859,6 @@
 	ivideo->tvxpos = sisfb_tvxposoffset;
 	ivideo->tvypos = sisfb_tvyposoffset;
 	ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-	ivideo->sisfb_inverse = sisfb_inverse;
-#endif
-
 	ivideo->refresh_rate = 0;
 	if(ivideo->sisfb_parm_rate != -1) {
 		ivideo->refresh_rate = ivideo->sisfb_parm_rate;
@@ -6049,10 +5934,6 @@
 		}
 	}
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	strcpy(sis_fb_info->modename, ivideo->myid);
-#endif
-
 	ivideo->SiS_Pr.ChipType = ivideo->chip;
 
 	ivideo->SiS_Pr.ivideo = (void *)ivideo;
@@ -6134,20 +6015,6 @@
 #endif
 	}
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef MODULE
-	if((reg & 0x80) && (reg != 0xff)) {
-		if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni])
-									!= 0xFF) {
-			printk(KERN_INFO "sisfb: Cannot initialize display mode, "
-					 "X server is active\n");
-			ret = -EBUSY;
-			goto error_4;
-		}
-	}
-#endif
-#endif
-
 	/* Search and copy ROM image */
 	ivideo->bios_abase = NULL;
 	ivideo->SiS_Pr.VirtualRomBase = NULL;
@@ -6281,9 +6148,6 @@
 error_1:	release_mem_region(ivideo->video_base, ivideo->video_size);
 error_2:	release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 error_3:	vfree(ivideo->bios_abase);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-error_4:
-#endif
 		if(ivideo->lpcdev)
 			SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
 		if(ivideo->nbridge)
@@ -6586,7 +6450,6 @@
 		sis_fb_info->fix = ivideo->sisfb_fix;
 		sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
 		sis_fb_info->fbops = &sisfb_ops;
-
 		sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
 		sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
 
@@ -6603,10 +6466,6 @@
 		}
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		vc_resize_con(1, 1, 0);
-#endif
-
 		if(register_framebuffer(sis_fb_info) < 0) {
 			printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
 			ret = -EINVAL;
@@ -6653,12 +6512,7 @@
 
 
 		printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n",
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-			GET_FB_IDX(sis_fb_info->node),
-#else
-			sis_fb_info->node,
-#endif
-			ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+			sis_fb_info->node, ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
 
 		printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
 
@@ -6732,11 +6586,7 @@
 	/* Unregister the framebuffer */
 	if(ivideo->registered) {
 		unregister_framebuffer(sis_fb_info);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
 		framebuffer_release(sis_fb_info);
-#else
-		kfree(sis_fb_info);
-#endif
 	}
 
 	/* OK, our ivideo is gone for good from here. */
@@ -6762,7 +6612,6 @@
 
 SISINITSTATIC int __init sisfb_init(void)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #ifndef MODULE
 	char *options = NULL;
 
@@ -6771,15 +6620,12 @@
 
 	sisfb_setup(options);
 #endif
-#endif
 	return pci_register_driver(&sisfb_driver);
 }
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #ifndef MODULE
 module_init(sisfb_init);
 #endif
-#endif
 
 /*****************************************************/
 /*                      MODULE                       */
@@ -6799,9 +6645,6 @@
 static int		noaccel = -1;
 static int		noypan  = -1;
 static int		nomax = -1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int		inverse = 0;
-#endif
 static int		userom = -1;
 static int		useoem = -1;
 static char		*tvstandard = NULL;
@@ -6861,10 +6704,6 @@
 	else if(nomax == 0)
 		sisfb_max = 1;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	if(inverse) sisfb_inverse = 1;
-#endif
-
 	if(mem)
 		sisfb_parm_mem = mem;
 
@@ -6913,35 +6752,6 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM(mem, "i");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM(noypan, "i");
-MODULE_PARM(nomax, "i");
-MODULE_PARM(userom, "i");
-MODULE_PARM(useoem, "i");
-MODULE_PARM(mode, "s");
-MODULE_PARM(vesa, "i");
-MODULE_PARM(rate, "i");
-MODULE_PARM(forcecrt1, "i");
-MODULE_PARM(forcecrt2type, "s");
-MODULE_PARM(scalelcd, "i");
-MODULE_PARM(pdc, "i");
-MODULE_PARM(pdc1, "i");
-MODULE_PARM(specialtiming, "s");
-MODULE_PARM(lvdshl, "i");
-MODULE_PARM(tvstandard, "s");
-MODULE_PARM(tvxposoffset, "i");
-MODULE_PARM(tvyposoffset, "i");
-MODULE_PARM(nocrt2rate, "i");
-MODULE_PARM(inverse, "i");
-#if !defined(__i386__) && !defined(__x86_64__)
-MODULE_PARM(resetcard, "i");
-MODULE_PARM(videoram, "i");
-#endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 module_param(mem, int, 0);
 module_param(noaccel, int, 0);
 module_param(noypan, int, 0);
@@ -6966,18 +6776,7 @@
 module_param(resetcard, int, 0);
 module_param(videoram, int, 0);
 #endif
-#endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(mem,
-	"\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
-	  "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
-	  "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
-	  "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
-	  "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
-	  "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
-	  "for XFree86 4.x/X.org 6.7 and later.\n");
-#else
 MODULE_PARM_DESC(mem,
 	"\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
 	  "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
@@ -6985,7 +6784,6 @@
 	  "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
 	  "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
 	  "The value is to be specified without 'KB'.\n");
-#endif
 
 MODULE_PARM_DESC(noaccel,
 	"\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
@@ -7002,23 +6800,6 @@
 	  "enable the user to positively specify a virtual Y size of the screen using\n"
 	  "fbset. (default: 0)\n");
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(mode,
-	"\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
-	  "1024x768x16. Other formats supported include XxY-Depth and\n"
-	  "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
-	  "number, it will be interpreted as a VESA mode number. (default: none if\n"
-	  "sisfb is a module; this leaves the console untouched and the driver will\n"
-	  "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
-	  "is in the kernel)\n");
-MODULE_PARM_DESC(vesa,
-	"\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
-	  "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
-	  "and the driver will only do the video memory management for eg. DRM/DRI;\n"
-	  "0x0103 if sisfb is in the kernel)\n");
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 MODULE_PARM_DESC(mode,
 	"\nSelects the desired default display mode in the format XxYxDepth,\n"
 	 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
@@ -7028,7 +6809,6 @@
 MODULE_PARM_DESC(vesa,
 	"\nSelects the desired default display mode by VESA defined mode number, eg.\n"
 	 "0x117 (default: 0x0103)\n");
-#endif
 
 MODULE_PARM_DESC(rate,
 	"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
@@ -7094,12 +6874,6 @@
 	"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
 	  "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(inverse,
-	"\nSetting this to anything but 0 should invert the display colors, but this\n"
-	  "does not seem to work. (default: 0)\n");
-#endif
-
 #if !defined(__i386__) && !defined(__x86_64__)
 #ifdef CONFIG_FB_SIS_300
 MODULE_PARM_DESC(resetcard,
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index 70b6df3..88e4f1e 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -67,15 +67,7 @@
 static int sisfb_max = -1;
 static int sisfb_userom = 1;
 static int sisfb_useoem = -1;
-#ifdef MODULE
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int sisfb_mode_idx = -1;
-#else
-static int sisfb_mode_idx = MODE_INDEX_NONE;  /* Don't use a mode by default if we are a module */
-#endif
-#else
 static int sisfb_mode_idx = -1;               /* Use a default mode if we are inside the kernel */
-#endif
 static int sisfb_parm_rate = -1;
 static int sisfb_crt1off = 0;
 static int sisfb_forcecrt1 = -1;
@@ -93,10 +85,6 @@
 static int sisfb_tvxposoffset = 0;
 static int sisfb_tvyposoffset = 0;
 static int sisfb_nocrt2rate = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int  sisfb_inverse = 0;
-static char sisfb_fontname[40];
-#endif
 #if !defined(__i386__) && !defined(__x86_64__)
 static int sisfb_resetcard = 0;
 static int sisfb_videoram = 0;
@@ -687,54 +675,8 @@
 static int	sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
 				struct fb_info *info);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int	sisfb_get_fix(struct fb_fix_screeninfo *fix,
-				int con,
-				struct fb_info *info);
-static int	sisfb_get_var(struct fb_var_screeninfo *var,
-				int con,
-				struct fb_info *info);
-static int	sisfb_set_var(struct fb_var_screeninfo *var,
-				int con,
-				struct fb_info *info);
-static void	sisfb_crtc_to_var(struct sis_video_info *ivideo,
-				struct fb_var_screeninfo *var);
-static int	sisfb_get_cmap(struct fb_cmap *cmap,
-				int kspc,
-				int con,
-				struct fb_info *info);
-static int	sisfb_set_cmap(struct fb_cmap *cmap,
-				int kspc,
-				int con,
-				struct fb_info *info);
-static int	sisfb_update_var(int con,
-				struct fb_info *info);
-static int	sisfb_switch(int con,
-			     struct fb_info *info);
-static void	sisfb_blank(int blank,
-				struct fb_info *info);
-static void	sisfb_set_disp(int con,
-				struct fb_var_screeninfo *var,
-				struct fb_info *info);
-static int	sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-				unsigned *blue, unsigned *transp,
-				struct fb_info *fb_info);
-static void	sisfb_do_install_cmap(int con,
-				struct fb_info *info);
-static int	sisfb_ioctl(struct inode *inode, struct file *file,
-				unsigned int cmd, unsigned long arg, int con,
-				struct fb_info *info);
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
 static int	sisfb_ioctl(struct fb_info *info, unsigned int cmd,
 			    unsigned long arg);
-#else
-static int	sisfb_ioctl(struct inode *inode, struct file *file,
-				unsigned int cmd, unsigned long arg,
-				struct fb_info *info);
-#endif
 static int	sisfb_set_par(struct fb_info *info);
 static int	sisfb_blank(int blank,
 				struct fb_info *info);
@@ -743,7 +685,6 @@
 extern void	fbcon_sis_copyarea(struct fb_info *info,
 				const struct fb_copyarea *area);
 extern int	fbcon_sis_sync(struct fb_info *info);
-#endif
 
 /* Internal 2D accelerator functions */
 extern int	sisfb_initaccel(struct sis_video_info *ivideo);
@@ -811,16 +752,10 @@
 
 extern BOOLEAN		sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
 				int *htotal, int *vtotal, unsigned char rateindex);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 extern int		sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
 				unsigned char modeno, unsigned char rateindex);
 extern int		sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
 				unsigned char rateindex, struct fb_var_screeninfo *var);
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-extern void		SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
-				int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
-#endif
 
 /* Chrontel TV, DDC and DPMS functions */
 extern unsigned short	SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg);
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 831b9f4..05d08b7 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -73,12 +73,10 @@
 
 #ifdef SIS_LINUX_KERNEL
 typedef unsigned long SISIOADDRESS;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #include <linux/types.h>  /* Need __iomem */
 #undef SISIOMEMTYPE
 #define SISIOMEMTYPE __iomem
 #endif
-#endif
 
 #ifdef SIS_XORG_XF86
 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index dad54e7..711cb11 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -17,7 +17,10 @@
  *	(port driver to new frambuffer infrastructure)
  * 01/2003 Helge Deller    <deller@gmx.de>
  *	(initial work on fb hardware acceleration for voodoo2)
- *
+ * 08/2006 Alan Cox 	   <alan@redhat.com>
+ *	Remove never finished and bogus 24/32bit support
+ *	Clean up macro abuse
+ *	Minor tidying for format.
  */
 
 /*
@@ -40,6 +43,7 @@
        through the fifo. warning: issuing a nop command seems to need pci_fifo
 -FIXME: in case of failure in the init sequence, be sure we return to a safe
         state.
+- FIXME: Use accelerator for 2D scroll
 -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
  */
 
@@ -67,9 +71,6 @@
 
 #undef SST_DEBUG
 
-/* enable 24/32 bpp functions ? (completely untested!) */
-#undef EN_24_32_BPP
-
 /*
   Default video mode .
   0 800x600@60  took from glide
@@ -377,7 +378,11 @@
  *      sstfb_check_var - Optional function.  Validates a var passed in.
  *      @var: frame buffer variable screen structure
  *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *	Limit to the abilities of a single chip as SLI is not supported
+ *	by this driver.
  */
+
 static int sstfb_check_var(struct fb_var_screeninfo *var,
 		struct fb_info *info)
 {
@@ -390,7 +395,7 @@
 	unsigned int freq;
 
 	if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) {
-		eprintk("Pixclock at %ld KHZ out of range\n",
+		printk(KERN_ERR "sstfb: Pixclock at %ld KHZ out of range\n",
 				PICOS2KHZ(var->pixclock));
 		return -EINVAL;
 	}
@@ -409,27 +414,15 @@
 	case 0 ... 16 :
 		var->bits_per_pixel = 16;
 		break;
-#ifdef EN_24_32_BPP
-	case 17 ... 24 :
-		var->bits_per_pixel = 24;
-		break;
-	case 25 ... 32 :
-		var->bits_per_pixel = 32;
-		break;
-#endif
 	default :
-		eprintk("Unsupported bpp %d\n", var->bits_per_pixel);
+		printk(KERN_ERR "sstfb: Unsupported bpp %d\n", var->bits_per_pixel);
 		return -EINVAL;
 	}
 	
 	/* validity tests */
-	if ((var->xres <= 1) || (yDim <= 0 )
-	   || (var->hsync_len <= 1)
-	   || (hSyncOff <= 1)
-	   || (var->left_margin <= 2)
-	   || (vSyncOn <= 0)
-	   || (vSyncOff <= 0)
-	   || (vBackPorch <= 0)) {
+	if (var->xres <= 1 || yDim <= 0 || var->hsync_len <= 1  ||
+	    hSyncOff <= 1  || var->left_margin <= 2  || vSyncOn <= 0 ||
+	    vSyncOff <= 0 || vBackPorch <= 0) {
 		return -EINVAL;
 	}
 
@@ -437,21 +430,17 @@
 		/* Voodoo 2 limits */
 		tiles_in_X = (var->xres + 63 ) / 64 * 2;		
 
-		if (((var->xres - 1) >= POW2(11)) || (yDim >= POW2(11))) {
-			eprintk("Unsupported resolution %dx%d\n",
+		if (var->xres  > POW2(11) || yDim >= POW2(11)) {
+			printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
 			         var->xres, var->yres);
 			return -EINVAL;
 		}
 
-		if (((var->hsync_len-1) >= POW2(9))
-		   || ((hSyncOff-1) >= POW2(11))
-		   || ((var->left_margin - 2) >= POW2(9))
-		   || (vSyncOn >= POW2(13))
-		   || (vSyncOff >= POW2(13))
-		   || (vBackPorch >= POW2(9))
-		   || (tiles_in_X >= POW2(6))
-		   || (tiles_in_X <= 0)) {
-			eprintk("Unsupported Timings\n");
+		if (var->hsync_len > POW2(9) || hSyncOff > POW2(11) ||
+		    var->left_margin - 2 >= POW2(9) || vSyncOn >= POW2(13) ||
+		    vSyncOff >= POW2(13) || vBackPorch >= POW2(9) ||
+		    tiles_in_X >= POW2(6) || tiles_in_X <= 0) {
+			printk(KERN_ERR "sstfb: Unsupported timings\n");
 			return -EINVAL;
 		}
 	} else {
@@ -459,24 +448,20 @@
 		tiles_in_X = (var->xres + 63 ) / 64;
 
 		if (var->vmode) {
-			eprintk("Interlace/Doublescan not supported %#x\n",
+			printk(KERN_ERR "sstfb: Interlace/doublescan not supported %#x\n",
 				var->vmode);
 			return -EINVAL;
 		}
-		if (((var->xres - 1) >= POW2(10)) || (var->yres >= POW2(10))) {
-			eprintk("Unsupported resolution %dx%d\n",
+		if (var->xres > POW2(10) || var->yres >= POW2(10)) {
+			printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
 			         var->xres, var->yres);
 			return -EINVAL;
 		}
-		if (((var->hsync_len - 1) >= POW2(8))
-		   || ((hSyncOff-1) >= POW2(10))
-		   || ((var->left_margin - 2) >= POW2(8))
-		   || (vSyncOn >= POW2(12))
-		   || (vSyncOff >= POW2(12))
-		   || (vBackPorch >= POW2(8))
-		   || (tiles_in_X >= POW2(4))
-		   || (tiles_in_X <= 0)) {
-			eprintk("Unsupported Timings\n");
+		if (var->hsync_len > POW2(8) || hSyncOff - 1 > POW2(10) ||
+		    var->left_margin - 2 >= POW2(8) || vSyncOn >= POW2(12) ||
+		    vSyncOff >= POW2(12) || vBackPorch >= POW2(8) ||
+		    tiles_in_X >= POW2(4) || tiles_in_X <= 0) {
+			printk(KERN_ERR "sstfb: Unsupported timings\n");
 			return -EINVAL;
 		}
 	}
@@ -486,8 +471,8 @@
 	real_length = tiles_in_X  * (IS_VOODOO2(par) ? 32 : 64 )
 	              * ((var->bits_per_pixel == 16) ? 2 : 4);
 
-	if ((real_length * yDim) > info->fix.smem_len) {
-		eprintk("Not enough video memory\n");
+	if (real_length * yDim > info->fix.smem_len) {
+		printk(KERN_ERR "sstfb: Not enough video memory\n");
 		return -ENOMEM;
 	}
 
@@ -515,20 +500,6 @@
 		var->blue.offset   = 0;
 		var->transp.offset = 0;
 		break;
-#ifdef EN_24_32_BPP
-	case 24:	/* RGB 888 LfbMode 4 */
-	case 32:	/* ARGB 8888 LfbMode 5 */
-		var->red.length    = 8;
-		var->green.length  = 8;
-		var->blue.length   = 8;
-		var->transp.length = 0;
-
-		var->red.offset    = 16;
-		var->green.offset  = 8;
-		var->blue.offset   = 0;
-		var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */
-		break;
-#endif
 	default:
 		return -EINVAL;
 	}
@@ -653,13 +624,6 @@
 	case 16:
 		fbiinit1 |=  SEL_SOURCE_VCLK_2X_SEL;
 		break;
-#ifdef EN_24_32_BPP
-	case 24:
-	case 32:
-		/* sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP);*/
-		fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP;
-		break;
-#endif
 	default:
 		return -EINVAL;
 	}
@@ -690,14 +654,6 @@
 	case 16:
 		lfbmode = LFB_565;
 		break;
-#ifdef EN_24_32_BPP
-	case 24:
-		lfbmode = LFB_888;
-		break;
-	case 32:
-		lfbmode = LFB_8888;
-		break;
-#endif
 	default:
 		return -EINVAL;
 	}
@@ -789,8 +745,7 @@
 			return -EFAULT;
 		if (val > info->fix.smem_len)
 			val = info->fix.smem_len;
-		printk("filling %#x \n", val);
-		for (p=0 ; p<val; p+=2)
+		for (p = 0 ; p < val; p += 2)
 			writew(p >> 6, info->screen_base + p);
 		return 0;
 		
@@ -802,13 +757,10 @@
 		pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 				       tmp | PCI_EN_INIT_WR );
 		fbiinit0 = sst_read (FBIINIT0);
-		if (val) {
+		if (val)
 			sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
-			iprintk("Disabling VGA pass-through\n");
-		} else {
+		else
 			sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
-			iprintk("Enabling VGA pass-through\n");
-		}
 		pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
 		return 0;
 		
@@ -884,9 +836,9 @@
 	u8 __iomem *fbbase_virt = info->screen_base;
 
 	/* force memsize */
-	if ((mem >= 1 ) &&  (mem <= 4)) {
+	if (mem >= 1  && mem <= 4) {
 		*memsize = (mem * 0x100000);
-		iprintk("supplied memsize: %#x\n", *memsize);
+		printk(KERN_INFO "supplied memsize: %#x\n", *memsize);
 		return 1;
 	}
 
@@ -927,7 +879,7 @@
 	struct sstfb_par *par = info->par;
 	int i, mir, dir;
 
-	for (i=0; i<3; i++) {
+	for (i = 0; i < 3; i++) {
 		sst_dac_write(DACREG_WMA, 0); 	/* backdoor */
 		sst_dac_read(DACREG_RMR);	/* read 4 times RMR */
 		sst_dac_read(DACREG_RMR);
@@ -940,7 +892,7 @@
 		/*the 7th, device ID register */
 		dir = sst_dac_read(DACREG_RMR);
 		f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
-		if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) {
+		if (mir == DACREG_MIR_ATT && dir == DACREG_DIR_ATT) {
 			return 1;
 		}
 	}
@@ -1134,12 +1086,6 @@
 	case 16:
 		sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP);
 		break;
-#ifdef EN_24_32_BPP
-	case 24:
-	case 32:
-		sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP);
-		break;
-#endif
 	default:
 		dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
 		break;
@@ -1154,12 +1100,6 @@
 	case 16:
 		sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
 		break;
-#ifdef EN_24_32_BPP
-	case 24:
-	case 32:
-		sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP);
-		break;
-#endif
 	default:
 		dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
 		break;
@@ -1250,7 +1190,7 @@
 				PCI_EN_INIT_WR | PCI_REMAP_DAC );
 	/* detect dac type */
 	if (!sst_detect_dactype(info, par)) {
-		eprintk("Unknown dac type\n");
+		printk(KERN_ERR "sstfb: unknown dac type.\n");
 		//FIXME watch it: we are not in a safe state, bad bad bad.
 		return 0;
 	}
@@ -1258,10 +1198,10 @@
 	/* set graphic clock */
 	par->gfx_clock = spec->default_gfx_clock;
 	if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
-		iprintk("Using supplied graphic freq : %dMHz\n", gfxclk);
+		printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
 		 par->gfx_clock = gfxclk *1000;
 	} else if (gfxclk) {
-		wprintk ("%dMhz is way out of spec! Using default\n", gfxclk);
+		printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk);
 	}
 
 	sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings);
@@ -1396,7 +1336,7 @@
 
 	/* Enable device in PCI config. */
 	if ((err=pci_enable_device(pdev))) {
-		eprintk("cannot enable device\n");
+		printk(KERN_ERR "cannot enable device\n");
 		return err;
 	}
 
@@ -1422,39 +1362,39 @@
 	fix->smem_start = fix->mmio_start + 0x400000;
 
 	if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) {
-		eprintk("cannot reserve mmio memory\n");
+		printk(KERN_ERR "sstfb: cannot reserve mmio memory\n");
 		goto fail_mmio_mem;
 	}
 
 	if (!request_mem_region(fix->smem_start, 0x400000,"sstfb FB")) {
-		eprintk("cannot reserve fb memory\n");
+		printk(KERN_ERR "sstfb: cannot reserve fb memory\n");
 		goto fail_fb_mem;
 	}
 
 	par->mmio_vbase = ioremap_nocache(fix->mmio_start,
 					fix->mmio_len);
 	if (!par->mmio_vbase) {
-		eprintk("cannot remap register area %#lx\n",
+		printk(KERN_ERR "sstfb: cannot remap register area %#lx\n",
 		        fix->mmio_start);
 		goto fail_mmio_remap;
 	}
 	info->screen_base = ioremap_nocache(fix->smem_start, 0x400000);
 	if (!info->screen_base) {
-		eprintk("cannot remap framebuffer %#lx\n",
+		printk(KERN_ERR "sstfb: cannot remap framebuffer %#lx\n",
 		        fix->smem_start);
 		goto fail_fb_remap;
 	}
 
 	if (!sst_init(info, par)) {
-		eprintk("Init failed\n");
+		printk(KERN_ERR "sstfb: Init failed\n");
 		goto fail;
 	}
 	sst_get_memsize(info, &fix->smem_len);
 	strlcpy(fix->id, spec->name, sizeof(fix->id));
 
-	iprintk("%s (revision %d) with %s dac\n",
+	printk(KERN_INFO "%s (revision %d) with %s dac\n",
 		fix->id, par->revision, par->dac_sw.name);
-	iprintk("framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
+	printk(KERN_INFO "framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
 	        fix->smem_start, info->screen_base,
 	        fix->smem_len >> 20);
 
@@ -1471,24 +1411,25 @@
 	fix->accel	= FB_ACCEL_NONE;  /* FIXME */
 	/*
 	 * According to the specs, the linelength must be of 1024 *pixels*
-	 * and the 24bpp mode is in fact a 32 bpp mode.
+	 * and the 24bpp mode is in fact a 32 bpp mode (and both are in
+	 * fact dithered to 16bit).
 	 */
 	fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
 	
 	if ( mode_option &&
 	     fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) {
-		eprintk("can't set supplied video mode. Using default\n");
+		printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n");
 		info->var = sstfb_default;
 	} else
 		info->var = sstfb_default;
 
 	if (sstfb_check_var(&info->var, info)) {
-		eprintk("invalid default video mode.\n");
+		printk(KERN_ERR "sstfb: invalid default video mode.\n");
 		goto fail;
 	}
 
 	if (sstfb_set_par(info)) {
-		eprintk("can't set default video mode.\n");
+		printk(KERN_ERR "sstfb: can't set default video mode.\n");
 		goto fail;
 	}
 	
@@ -1497,7 +1438,7 @@
 	/* register fb */
 	info->device = &pdev->dev;
 	if (register_framebuffer(info) < 0) {
-		eprintk("can't register framebuffer.\n");
+		printk(KERN_ERR "sstfb: can't register framebuffer.\n");
 		goto fail;
 	}
 
@@ -1711,4 +1652,3 @@
 MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
 module_param(slowpci, bool, 0);
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
-
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 8b3d0f0..27c9d05 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -21,7 +21,7 @@
 	  There are three types of messages between w1 core and userspace:
 	  1. Events. They are generated each time new master or slave device found
 		either due to automatic or requested search.
-	  2. Userspace commands. Includes read/write and search/alarm search comamnds.
+	  2. Userspace commands. Includes read/write and search/alarm search commands.
 	  3. Replies to userspace commands.
 
 source drivers/w1/masters/Kconfig
diff --git a/fs/Kconfig b/fs/Kconfig
index fa64867..599de54 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -74,11 +74,11 @@
 	tristate "Ext3 journalling file system support"
 	select JBD
 	help
-	  This is the journaling version of the Second extended file system
+	  This is the journalling version of the Second extended file system
 	  (often called ext3), the de facto standard Linux file system
 	  (method to organize files on a storage device) for hard disks.
 
-	  The journaling code included in this driver means you do not have
+	  The journalling code included in this driver means you do not have
 	  to run e2fsck (file system checker) on your file systems after a
 	  crash.  The journal keeps track of any changes that were being made
 	  at the time the system crashed, and can ensure that your file system
@@ -143,7 +143,7 @@
 config JBD
 	tristate
 	help
-	  This is a generic journaling layer for block devices.  It is
+	  This is a generic journalling layer for block devices.  It is
 	  currently used by the ext3 and OCFS2 file systems, but it could
 	  also be used to add journal support to other file systems or block
 	  devices such as RAID or LVM.
@@ -183,7 +183,7 @@
 	tristate "Reiserfs support"
 	help
 	  Stores not just filenames but the files themselves in a balanced
-	  tree.  Uses journaling.
+	  tree.  Uses journalling.
 
 	  Balanced trees are more efficient than traditional file system
 	  architectural foundations.
@@ -996,6 +996,18 @@
 	  To compile this file system support as a module, choose M here: the
 	  module will be called affs.  If unsure, say N.
 
+config ECRYPT_FS
+	tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && KEYS && CRYPTO
+	help
+	  Encrypted filesystem that operates on the VFS layer.  See
+	  <file:Documentation/ecryptfs.txt> to learn more about
+	  eCryptfs.  Userspace components are required and can be
+	  obtained from <http://ecryptfs.sf.net>.
+
+	  To compile this file system support as a module, choose M here: the
+	  module will be called ecryptfs.
+
 config HFS_FS
 	tristate "Apple Macintosh file system support (EXPERIMENTAL)"
 	depends on BLOCK && EXPERIMENTAL
@@ -1033,7 +1045,7 @@
 	  on files and directories, and database-like indeces on selected
 	  attributes. (Also note that this driver doesn't make those features
 	  available at this time). It is a 64 bit filesystem, so it supports
-	  extremly large volumes and files.
+	  extremely large volumes and files.
 
 	  If you use this filesystem, you should also say Y to at least one
 	  of the NLS (native language support) options below.
@@ -1091,7 +1103,7 @@
 	tristate "Journalling Flash File System (JFFS) support"
 	depends on MTD && BLOCK
 	help
-	  JFFS is the Journaling Flash File System developed by Axis
+	  JFFS is the Journalling Flash File System developed by Axis
 	  Communications in Sweden, aimed at providing a crash/powerdown-safe
 	  file system for disk-less embedded devices. Further information is
 	  available at (<http://developer.axis.com/software/jffs/>).
@@ -1261,7 +1273,7 @@
 config JFFS2_CMODE_PRIORITY
         bool "priority"
         help
-          Tries the compressors in a predefinied order and chooses the first
+          Tries the compressors in a predefined order and chooses the first
           successful one.
 
 config JFFS2_CMODE_SIZE
@@ -1366,7 +1378,7 @@
 
 	  If you have floppies or hard disk partitions like that, it is likely
 	  that they contain binaries from those other Unix systems; in order
-	  to run these binaries, you will want to install linux-abi which is a
+	  to run these binaries, you will want to install linux-abi which is
 	  a set of kernel modules that lets you run SCO, Xenix, Wyse,
 	  UnixWare, Dell Unix and System V programs under Linux.  It is
 	  available via FTP (user: ftp) from
@@ -1951,7 +1963,7 @@
 	  If you say Y here, you will get an experimental Andrew File System
 	  driver. It currently only supports unsecured read-only AFS access.
 
-	  See <file:Documentation/filesystems/afs.txt> for more intormation.
+	  See <file:Documentation/filesystems/afs.txt> for more information.
 
 	  If unsure, say N.
 
diff --git a/fs/Makefile b/fs/Makefile
index 215f703..df614ea 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -76,6 +76,7 @@
 obj-$(CONFIG_ISO9660_FS)	+= isofs/
 obj-$(CONFIG_HFSPLUS_FS)	+= hfsplus/ # Before hfs to find wrapped HFS+
 obj-$(CONFIG_HFS_FS)		+= hfs/
+obj-$(CONFIG_ECRYPT_FS)		+= ecryptfs/
 obj-$(CONFIG_VXFS_FS)		+= freevxfs/
 obj-$(CONFIG_NFS_FS)		+= nfs/
 obj-$(CONFIG_EXPORTFS)		+= exportfs/
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 2fc9987..cf8a2cb 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -30,7 +30,7 @@
 static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
 static int afs_d_delete(struct dentry *dentry);
 static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
-				  loff_t fpos, ino_t ino, unsigned dtype);
+				  loff_t fpos, u64 ino, unsigned dtype);
 
 const struct file_operations afs_dir_file_operations = {
 	.open		= afs_dir_open,
@@ -409,7 +409,7 @@
  *   uniquifier through dtype
  */
 static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
-				  loff_t fpos, ino_t ino, unsigned dtype)
+				  loff_t fpos, u64 ino, unsigned dtype)
 {
 	struct afs_dir_lookup_cookie *cookie = _cookie;
 
diff --git a/fs/aio.c b/fs/aio.c
index 2e0d150..9476659 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -675,7 +675,7 @@
 	}
 
 	if (!(iocb->ki_retried & 0xff)) {
-		pr_debug("%ld retry: %d of %d\n", iocb->ki_retried,
+		pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried,
 			iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes);
 	}
 
@@ -1008,7 +1008,7 @@
 
 	pr_debug("added to ring %p at [%lu]\n", iocb, tail);
 
-	pr_debug("%ld retries: %d of %d\n", iocb->ki_retried,
+	pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried,
 		iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes);
 put_rq:
 	/* everything turned out well, dispose of the aiocb. */
diff --git a/fs/befs/befs_fs_types.h b/fs/befs/befs_fs_types.h
index 9095518..63ef1e1 100644
--- a/fs/befs/befs_fs_types.h
+++ b/fs/befs/befs_fs_types.h
@@ -1,5 +1,5 @@
 /*
- * include/linux/befs_fs_types.h
+ * fs/befs/befs_fs_types.h
  *
  * Copyright (C) 2001 Will Dyson (will@cs.earlham.edu)
  *
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 32b5d62..5bcdaaf 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -29,6 +29,7 @@
 #include <linux/personality.h>
 #include <linux/init.h>
 
+#include <asm/a.out.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
@@ -194,6 +195,7 @@
 	unsigned long som_entry;
 	struct som_hdr *som_ex;
 	struct som_exec_auxhdr *hpuxhdr;
+	struct files_struct *files;
 
 	/* Get the exec-header */
 	som_ex = (struct som_hdr *) bprm->buf;
@@ -208,15 +210,27 @@
 	size = som_ex->aux_header_size;
 	if (size > SOM_PAGESIZE)
 		goto out;
-	hpuxhdr = (struct som_exec_auxhdr *) kmalloc(size, GFP_KERNEL);
+	hpuxhdr = kmalloc(size, GFP_KERNEL);
 	if (!hpuxhdr)
 		goto out;
 
 	retval = kernel_read(bprm->file, som_ex->aux_header_location,
 			(char *) hpuxhdr, size);
+	if (retval != size) {
+		if (retval >= 0)
+			retval = -EIO;
+		goto out_free;
+	}
+
+	files = current->files; /* Refcounted so ok */
+	retval = unshare_files();
 	if (retval < 0)
 		goto out_free;
-#error "Fix security hole before enabling me"
+	if (files == current->files) {
+		put_files_struct(files);
+		files = NULL;
+	}
+
 	retval = get_unused_fd();
 	if (retval < 0)
 		goto out_free;
diff --git a/fs/cifs/README b/fs/cifs/README
index 5f0e1bd..432e515 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -269,7 +269,7 @@
 		(gid) mount option is specified.  For the uid (gid) of newly
 		created files and directories, ie files created since 
 		the last mount of the server share, the expected uid 
-		(gid) is cached as as long as the inode remains in 
+		(gid) is cached as long as the inode remains in 
 		memory on the client.   Also note that permission
 		checks (authorization checks) on accesses to a file occur
 		at the server, but there are cases in which an administrator
@@ -375,7 +375,7 @@
 		the local process on newly created files, directories, and
 		devices (create, mkdir, mknod).  If the CIFS Unix Extensions
 		are not negotiated, for newly created files and directories
-		instead of using the default uid and gid specified on the
+		instead of using the default uid and gid specified on
 		the mount, cache the new file's uid and gid locally which means
 		that the uid for the file can change when the inode is
 	        reloaded (or the user remounts the share).
@@ -440,7 +440,7 @@
 		create device files and fifos in a format compatible with
 		Services for Unix (SFU).  In addition retrieve bits 10-12
 		of the mode via the SETFILEBITS extended attribute (as
-		SFU does).  In the future the bottom 9 bits of the mode
+		SFU does).  In the future the bottom 9 bits of the
 		mode also will be emulated using queries of the security
 		descriptor (ACL).
  sign           Must use packet signing (helps avoid unwanted data modification
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0e9ba0b..c787620 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -772,12 +772,12 @@
 	separator[1] = 0; 
 
 	memset(vol->source_rfc1001_name,0x20,15);
-	for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
+	for(i=0;i < strnlen(utsname()->nodename,15);i++) {
 		/* does not have to be a perfect mapping since the field is
 		informational, only used for servers that do not support
 		port 445 and it can be overridden at mount time */
 		vol->source_rfc1001_name[i] = 
-			toupper(system_utsname.nodename[i]);
+			toupper(utsname()->nodename[i]);
 	}
 	vol->source_rfc1001_name[15] = 0;
 	/* null target name indicates to use *SMBSERVR default called name
@@ -2153,7 +2153,7 @@
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bytes_returned =
-		    cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+		    cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;
@@ -2180,8 +2180,8 @@
 		}
 		strcpy(bcc_ptr, "Linux version ");
 		bcc_ptr += strlen("Linux version ");
-		strcpy(bcc_ptr, system_utsname.release);
-		bcc_ptr += strlen(system_utsname.release) + 1;
+		strcpy(bcc_ptr, utsname()->release);
+		bcc_ptr += strlen(utsname()->release) + 1;
 		strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 		bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 	}
@@ -2445,7 +2445,7 @@
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bytes_returned =
-		    cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+		    cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
 				  nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;	/* null terminate Linux version */
@@ -2462,8 +2462,8 @@
 	} else {		/* ASCII */
 		strcpy(bcc_ptr, "Linux version ");
 		bcc_ptr += strlen("Linux version ");
-		strcpy(bcc_ptr, system_utsname.release);
-		bcc_ptr += strlen(system_utsname.release) + 1;
+		strcpy(bcc_ptr, utsname()->release);
+		bcc_ptr += strlen(utsname()->release) + 1;
 		strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 		bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 		bcc_ptr++;	/* empty domain field */
@@ -2836,7 +2836,7 @@
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bytes_returned =
-		    cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+		    cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
 				  nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;	/* null term version string */
@@ -2888,8 +2888,8 @@
 
 		strcpy(bcc_ptr, "Linux version ");
 		bcc_ptr += strlen("Linux version ");
-		strcpy(bcc_ptr, system_utsname.release);
-		bcc_ptr += strlen(system_utsname.release) + 1;
+		strcpy(bcc_ptr, utsname()->release);
+		bcc_ptr += strlen(utsname()->release) + 1;
 		strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 		bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 		bcc_ptr++;	/* null domain */
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index d1705ab..22b4c35 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -111,7 +111,7 @@
 	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
 				  nls_cp);
 	bcc_ptr += 2 * bytes_ret;
-	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
 				  32, nls_cp);
 	bcc_ptr += 2 * bytes_ret;
 	bcc_ptr += 2; /* trailing null */
@@ -158,8 +158,8 @@
 
 	strcpy(bcc_ptr, "Linux version ");
 	bcc_ptr += strlen("Linux version ");
-	strcpy(bcc_ptr, system_utsname.release);
-	bcc_ptr += strlen(system_utsname.release) + 1;
+	strcpy(bcc_ptr, init_utsname()->release);
+	bcc_ptr += strlen(init_utsname()->release) + 1;
 
 	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
diff --git a/fs/compat.c b/fs/compat.c
index 13fb08d..4d3fbcb 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -56,8 +56,6 @@
 
 int compat_log = 1;
 
-extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
-
 int compat_printk(const char *fmt, ...)
 {
 	va_list ap;
@@ -916,20 +914,24 @@
 };
 
 static int compat_fillonedir(void *__buf, const char *name, int namlen,
-			loff_t offset, ino_t ino, unsigned int d_type)
+			loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct compat_readdir_callback *buf = __buf;
 	struct compat_old_linux_dirent __user *dirent;
+	compat_ulong_t d_ino;
 
 	if (buf->result)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	buf->result++;
 	dirent = buf->dirent;
 	if (!access_ok(VERIFY_WRITE, dirent,
 			(unsigned long)(dirent->d_name + namlen + 1) -
 				(unsigned long)dirent))
 		goto efault;
-	if (	__put_user(ino, &dirent->d_ino) ||
+	if (	__put_user(d_ino, &dirent->d_ino) ||
 		__put_user(offset, &dirent->d_offset) ||
 		__put_user(namlen, &dirent->d_namlen) ||
 		__copy_to_user(dirent->d_name, name, namlen) ||
@@ -980,22 +982,26 @@
 };
 
 static int compat_filldir(void *__buf, const char *name, int namlen,
-		loff_t offset, ino_t ino, unsigned int d_type)
+		loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct compat_linux_dirent __user * dirent;
 	struct compat_getdents_callback *buf = __buf;
+	compat_ulong_t d_ino;
 	int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	if (dirent) {
 		if (__put_user(offset, &dirent->d_off))
 			goto efault;
 	}
 	dirent = buf->current_dir;
-	if (__put_user(ino, &dirent->d_ino))
+	if (__put_user(d_ino, &dirent->d_ino))
 		goto efault;
 	if (__put_user(reclen, &dirent->d_reclen))
 		goto efault;
@@ -1066,7 +1072,7 @@
 };
 
 static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset,
-		     ino_t ino, unsigned int d_type)
+		     u64 ino, unsigned int d_type)
 {
 	struct linux_dirent64 __user *dirent;
 	struct compat_getdents_callback64 *buf = __buf;
diff --git a/fs/configfs/file.c b/fs/configfs/file.c
index 85105e5..e6d5754 100644
--- a/fs/configfs/file.c
+++ b/fs/configfs/file.c
@@ -137,8 +137,8 @@
 		if ((retval = fill_read_buffer(file->f_dentry,buffer)))
 			goto out;
 	}
-	pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
-		 __FUNCTION__,count,*ppos,buffer->page);
+	pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
+		 __FUNCTION__, count, *ppos, buffer->page);
 	retval = flush_read_buffer(buffer,buf,count,ppos);
 out:
 	up(&buffer->sem);
diff --git a/fs/dcache.c b/fs/dcache.c
index fc2faa4..2355bdd 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -291,9 +291,9 @@
  * it can be unhashed only if it has no children, or if it is the root
  * of a filesystem.
  *
- * If the inode has a DCACHE_DISCONNECTED alias, then prefer
+ * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer
  * any other hashed alias over that one unless @want_discon is set,
- * in which case only return a DCACHE_DISCONNECTED alias.
+ * in which case only return an IS_ROOT, DCACHE_DISCONNECTED alias.
  */
 
 static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
@@ -309,7 +309,8 @@
 		prefetch(next);
 		alias = list_entry(tmp, struct dentry, d_alias);
  		if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
-			if (alias->d_flags & DCACHE_DISCONNECTED)
+			if (IS_ROOT(alias) &&
+			    (alias->d_flags & DCACHE_DISCONNECTED))
 				discon_alias = alias;
 			else if (!want_discon) {
 				__dget_locked(alias);
@@ -1004,7 +1005,7 @@
 {
 	struct dentry *new = NULL;
 
-	if (inode) {
+	if (inode && S_ISDIR(inode->i_mode)) {
 		spin_lock(&dcache_lock);
 		new = __d_find_alias(inode, 1);
 		if (new) {
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index ecf3da9e..e77676d 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -252,7 +252,7 @@
  *
  * This function removes a file or directory in debugfs that was previously
  * created with a call to another debugfs function (like
- * debufs_create_file() or variants thereof.)
+ * debugfs_create_file() or variants thereof.)
  *
  * This function is required to be called in order for the file to be
  * removed, no automatic cleanup of files will happen when a module is
diff --git a/fs/dnotify.c b/fs/dnotify.c
index f932591..2b0442d 100644
--- a/fs/dnotify.c
+++ b/fs/dnotify.c
@@ -92,7 +92,7 @@
 		prev = &odn->dn_next;
 	}
 
-	error = f_setown(filp, current->pid, 0);
+	error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
 	if (error)
 		goto out_free;
 
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile
new file mode 100644
index 0000000..ca65624
--- /dev/null
+++ b/fs/ecryptfs/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the Linux 2.6 eCryptfs
+#
+
+obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
+
+ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o debug.o
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
new file mode 100644
index 0000000..ed35a9712
--- /dev/null
+++ b/fs/ecryptfs/crypto.c
@@ -0,0 +1,1659 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2004 Erez Zadok
+ * Copyright (C) 2001-2004 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *   		Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/random.h>
+#include <linux/compiler.h>
+#include <linux/key.h>
+#include <linux/namei.h>
+#include <linux/crypto.h>
+#include <linux/file.h>
+#include <linux/scatterlist.h>
+#include "ecryptfs_kernel.h"
+
+static int
+ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+			     struct page *dst_page, int dst_offset,
+			     struct page *src_page, int src_offset, int size,
+			     unsigned char *iv);
+static int
+ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+			     struct page *dst_page, int dst_offset,
+			     struct page *src_page, int src_offset, int size,
+			     unsigned char *iv);
+
+/**
+ * ecryptfs_to_hex
+ * @dst: Buffer to take hex character representation of contents of
+ *       src; must be at least of size (src_size * 2)
+ * @src: Buffer to be converted to a hex string respresentation
+ * @src_size: number of bytes to convert
+ */
+void ecryptfs_to_hex(char *dst, char *src, size_t src_size)
+{
+	int x;
+
+	for (x = 0; x < src_size; x++)
+		sprintf(&dst[x * 2], "%.2x", (unsigned char)src[x]);
+}
+
+/**
+ * ecryptfs_from_hex
+ * @dst: Buffer to take the bytes from src hex; must be at least of
+ *       size (src_size / 2)
+ * @src: Buffer to be converted from a hex string respresentation to raw value
+ * @dst_size: size of dst buffer, or number of hex characters pairs to convert
+ */
+void ecryptfs_from_hex(char *dst, char *src, int dst_size)
+{
+	int x;
+	char tmp[3] = { 0, };
+
+	for (x = 0; x < dst_size; x++) {
+		tmp[0] = src[x * 2];
+		tmp[1] = src[x * 2 + 1];
+		dst[x] = (unsigned char)simple_strtol(tmp, NULL, 16);
+	}
+}
+
+/**
+ * ecryptfs_calculate_md5 - calculates the md5 of @src
+ * @dst: Pointer to 16 bytes of allocated memory
+ * @crypt_stat: Pointer to crypt_stat struct for the current inode
+ * @src: Data to be md5'd
+ * @len: Length of @src
+ *
+ * Uses the allocated crypto context that crypt_stat references to
+ * generate the MD5 sum of the contents of src.
+ */
+static int ecryptfs_calculate_md5(char *dst,
+				  struct ecryptfs_crypt_stat *crypt_stat,
+				  char *src, int len)
+{
+	int rc = 0;
+	struct scatterlist sg;
+
+	mutex_lock(&crypt_stat->cs_md5_tfm_mutex);
+	sg_init_one(&sg, (u8 *)src, len);
+	if (!crypt_stat->md5_tfm) {
+		crypt_stat->md5_tfm =
+			crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP);
+		if (!crypt_stat->md5_tfm) {
+			rc = -ENOMEM;
+			ecryptfs_printk(KERN_ERR, "Error attempting to "
+					"allocate crypto context\n");
+			goto out;
+		}
+	}
+	crypto_digest_init(crypt_stat->md5_tfm);
+	crypto_digest_update(crypt_stat->md5_tfm, &sg, 1);
+	crypto_digest_final(crypt_stat->md5_tfm, dst);
+	mutex_unlock(&crypt_stat->cs_md5_tfm_mutex);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_derive_iv
+ * @iv: destination for the derived iv vale
+ * @crypt_stat: Pointer to crypt_stat struct for the current inode
+ * @offset: Offset of the page whose's iv we are to derive
+ *
+ * Generate the initialization vector from the given root IV and page
+ * offset.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
+			      pgoff_t offset)
+{
+	int rc = 0;
+	char dst[MD5_DIGEST_SIZE];
+	char src[ECRYPTFS_MAX_IV_BYTES + 16];
+
+	if (unlikely(ecryptfs_verbosity > 0)) {
+		ecryptfs_printk(KERN_DEBUG, "root iv:\n");
+		ecryptfs_dump_hex(crypt_stat->root_iv, crypt_stat->iv_bytes);
+	}
+	/* TODO: It is probably secure to just cast the least
+	 * significant bits of the root IV into an unsigned long and
+	 * add the offset to that rather than go through all this
+	 * hashing business. -Halcrow */
+	memcpy(src, crypt_stat->root_iv, crypt_stat->iv_bytes);
+	memset((src + crypt_stat->iv_bytes), 0, 16);
+	snprintf((src + crypt_stat->iv_bytes), 16, "%ld", offset);
+	if (unlikely(ecryptfs_verbosity > 0)) {
+		ecryptfs_printk(KERN_DEBUG, "source:\n");
+		ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16));
+	}
+	rc = ecryptfs_calculate_md5(dst, crypt_stat, src,
+				    (crypt_stat->iv_bytes + 16));
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "Error attempting to compute "
+				"MD5 while generating IV for a page\n");
+		goto out;
+	}
+	memcpy(iv, dst, crypt_stat->iv_bytes);
+	if (unlikely(ecryptfs_verbosity > 0)) {
+		ecryptfs_printk(KERN_DEBUG, "derived iv:\n");
+		ecryptfs_dump_hex(iv, crypt_stat->iv_bytes);
+	}
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_init_crypt_stat
+ * @crypt_stat: Pointer to the crypt_stat struct to initialize.
+ *
+ * Initialize the crypt_stat structure.
+ */
+void
+ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
+	mutex_init(&crypt_stat->cs_mutex);
+	mutex_init(&crypt_stat->cs_tfm_mutex);
+	mutex_init(&crypt_stat->cs_md5_tfm_mutex);
+	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED);
+}
+
+/**
+ * ecryptfs_destruct_crypt_stat
+ * @crypt_stat: Pointer to the crypt_stat struct to initialize.
+ *
+ * Releases all memory associated with a crypt_stat struct.
+ */
+void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	if (crypt_stat->tfm)
+		crypto_free_tfm(crypt_stat->tfm);
+	if (crypt_stat->md5_tfm)
+		crypto_free_tfm(crypt_stat->md5_tfm);
+	memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
+}
+
+void ecryptfs_destruct_mount_crypt_stat(
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+	if (mount_crypt_stat->global_auth_tok_key)
+		key_put(mount_crypt_stat->global_auth_tok_key);
+	if (mount_crypt_stat->global_key_tfm)
+		crypto_free_tfm(mount_crypt_stat->global_key_tfm);
+	memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
+}
+
+/**
+ * virt_to_scatterlist
+ * @addr: Virtual address
+ * @size: Size of data; should be an even multiple of the block size
+ * @sg: Pointer to scatterlist array; set to NULL to obtain only
+ *      the number of scatterlist structs required in array
+ * @sg_size: Max array size
+ *
+ * Fills in a scatterlist array with page references for a passed
+ * virtual address.
+ *
+ * Returns the number of scatterlist structs in array used
+ */
+int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
+			int sg_size)
+{
+	int i = 0;
+	struct page *pg;
+	int offset;
+	int remainder_of_page;
+
+	while (size > 0 && i < sg_size) {
+		pg = virt_to_page(addr);
+		offset = offset_in_page(addr);
+		if (sg) {
+			sg[i].page = pg;
+			sg[i].offset = offset;
+		}
+		remainder_of_page = PAGE_CACHE_SIZE - offset;
+		if (size >= remainder_of_page) {
+			if (sg)
+				sg[i].length = remainder_of_page;
+			addr += remainder_of_page;
+			size -= remainder_of_page;
+		} else {
+			if (sg)
+				sg[i].length = size;
+			addr += size;
+			size = 0;
+		}
+		i++;
+	}
+	if (size > 0)
+		return -ENOMEM;
+	return i;
+}
+
+/**
+ * encrypt_scatterlist
+ * @crypt_stat: Pointer to the crypt_stat struct to initialize.
+ * @dest_sg: Destination of encrypted data
+ * @src_sg: Data to be encrypted
+ * @size: Length of data to be encrypted
+ * @iv: iv to use during encryption
+ *
+ * Returns the number of bytes encrypted; negative value on error
+ */
+static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
+			       struct scatterlist *dest_sg,
+			       struct scatterlist *src_sg, int size,
+			       unsigned char *iv)
+{
+	int rc = 0;
+
+	BUG_ON(!crypt_stat || !crypt_stat->tfm
+	       || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+				       ECRYPTFS_STRUCT_INITIALIZED));
+	if (unlikely(ecryptfs_verbosity > 0)) {
+		ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n",
+				crypt_stat->key_size);
+		ecryptfs_dump_hex(crypt_stat->key,
+				  crypt_stat->key_size);
+	}
+	/* Consider doing this once, when the file is opened */
+	mutex_lock(&crypt_stat->cs_tfm_mutex);
+	rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
+				  crypt_stat->key_size);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
+				rc);
+		mutex_unlock(&crypt_stat->cs_tfm_mutex);
+		rc = -EINVAL;
+		goto out;
+	}
+	ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
+	crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv);
+	mutex_unlock(&crypt_stat->cs_tfm_mutex);
+out:
+	return rc;
+}
+
+static void
+ecryptfs_extent_to_lwr_pg_idx_and_offset(unsigned long *lower_page_idx,
+					 int *byte_offset,
+					 struct ecryptfs_crypt_stat *crypt_stat,
+					 unsigned long extent_num)
+{
+	unsigned long lower_extent_num;
+	int extents_occupied_by_headers_at_front;
+	int bytes_occupied_by_headers_at_front;
+	int extent_offset;
+	int extents_per_page;
+
+	bytes_occupied_by_headers_at_front =
+		( crypt_stat->header_extent_size
+		  * crypt_stat->num_header_extents_at_front );
+	extents_occupied_by_headers_at_front =
+		( bytes_occupied_by_headers_at_front
+		  / crypt_stat->extent_size );
+	lower_extent_num = extents_occupied_by_headers_at_front + extent_num;
+	extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
+	(*lower_page_idx) = lower_extent_num / extents_per_page;
+	extent_offset = lower_extent_num % extents_per_page;
+	(*byte_offset) = extent_offset * crypt_stat->extent_size;
+	ecryptfs_printk(KERN_DEBUG, " * crypt_stat->header_extent_size = "
+			"[%d]\n", crypt_stat->header_extent_size);
+	ecryptfs_printk(KERN_DEBUG, " * crypt_stat->"
+			"num_header_extents_at_front = [%d]\n",
+			crypt_stat->num_header_extents_at_front);
+	ecryptfs_printk(KERN_DEBUG, " * extents_occupied_by_headers_at_"
+			"front = [%d]\n", extents_occupied_by_headers_at_front);
+	ecryptfs_printk(KERN_DEBUG, " * lower_extent_num = [0x%.16x]\n",
+			lower_extent_num);
+	ecryptfs_printk(KERN_DEBUG, " * extents_per_page = [%d]\n",
+			extents_per_page);
+	ecryptfs_printk(KERN_DEBUG, " * (*lower_page_idx) = [0x%.16x]\n",
+			(*lower_page_idx));
+	ecryptfs_printk(KERN_DEBUG, " * extent_offset = [%d]\n",
+			extent_offset);
+	ecryptfs_printk(KERN_DEBUG, " * (*byte_offset) = [%d]\n",
+			(*byte_offset));
+}
+
+static int ecryptfs_write_out_page(struct ecryptfs_page_crypt_context *ctx,
+				   struct page *lower_page,
+				   struct inode *lower_inode,
+				   int byte_offset_in_page, int bytes_to_write)
+{
+	int rc = 0;
+
+	if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
+		rc = ecryptfs_commit_lower_page(lower_page, lower_inode,
+						ctx->param.lower_file,
+						byte_offset_in_page,
+						bytes_to_write);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error calling lower "
+					"commit; rc = [%d]\n", rc);
+			goto out;
+		}
+	} else {
+		rc = ecryptfs_writepage_and_release_lower_page(lower_page,
+							       lower_inode,
+							       ctx->param.wbc);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error calling lower "
+					"writepage(); rc = [%d]\n", rc);
+			goto out;
+		}
+	}
+out:
+	return rc;
+}
+
+static int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx,
+				 struct page **lower_page,
+				 struct inode *lower_inode,
+				 unsigned long lower_page_idx,
+				 int byte_offset_in_page)
+{
+	int rc = 0;
+
+	if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
+		/* TODO: Limit this to only the data extents that are
+		 * needed */
+		rc = ecryptfs_get_lower_page(lower_page, lower_inode,
+					     ctx->param.lower_file,
+					     lower_page_idx,
+					     byte_offset_in_page,
+					     (PAGE_CACHE_SIZE
+					      - byte_offset_in_page));
+		if (rc) {
+			ecryptfs_printk(
+				KERN_ERR, "Error attempting to grab, map, "
+				"and prepare_write lower page with index "
+				"[0x%.16x]; rc = [%d]\n", lower_page_idx, rc);
+			goto out;
+		}
+	} else {
+		rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL,
+						      lower_inode,
+						      lower_page_idx);
+		if (rc) {
+			ecryptfs_printk(
+				KERN_ERR, "Error attempting to grab and map "
+				"lower page with index [0x%.16x]; rc = [%d]\n",
+				lower_page_idx, rc);
+			goto out;
+		}
+	}
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_encrypt_page
+ * @ctx: The context of the page
+ *
+ * Encrypt an eCryptfs page. This is done on a per-extent basis. Note
+ * that eCryptfs pages may straddle the lower pages -- for instance,
+ * if the file was created on a machine with an 8K page size
+ * (resulting in an 8K header), and then the file is copied onto a
+ * host with a 32K page size, then when reading page 0 of the eCryptfs
+ * file, 24K of page 0 of the lower file will be read and decrypted,
+ * and then 8K of page 1 of the lower file will be read and decrypted.
+ *
+ * The actual operations performed on each page depends on the
+ * contents of the ecryptfs_page_crypt_context struct.
+ *
+ * Returns zero on success; negative on error
+ */
+int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx)
+{
+	char extent_iv[ECRYPTFS_MAX_IV_BYTES];
+	unsigned long base_extent;
+	unsigned long extent_offset = 0;
+	unsigned long lower_page_idx = 0;
+	unsigned long prior_lower_page_idx = 0;
+	struct page *lower_page;
+	struct inode *lower_inode;
+	struct ecryptfs_inode_info *inode_info;
+	struct ecryptfs_crypt_stat *crypt_stat;
+	int rc = 0;
+	int lower_byte_offset = 0;
+	int orig_byte_offset = 0;
+	int num_extents_per_page;
+#define ECRYPTFS_PAGE_STATE_UNREAD    0
+#define ECRYPTFS_PAGE_STATE_READ      1
+#define ECRYPTFS_PAGE_STATE_MODIFIED  2
+#define ECRYPTFS_PAGE_STATE_WRITTEN   3
+	int page_state;
+
+	lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host);
+	inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host);
+	crypt_stat = &inode_info->crypt_stat;
+	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) {
+		rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode,
+						 ctx->param.lower_file);
+		if (rc)
+			ecryptfs_printk(KERN_ERR, "Error attempting to copy "
+					"page at index [0x%.16x]\n",
+					ctx->page->index);
+		goto out;
+	}
+	num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
+	base_extent = (ctx->page->index * num_extents_per_page);
+	page_state = ECRYPTFS_PAGE_STATE_UNREAD;
+	while (extent_offset < num_extents_per_page) {
+		ecryptfs_extent_to_lwr_pg_idx_and_offset(
+			&lower_page_idx, &lower_byte_offset, crypt_stat,
+			(base_extent + extent_offset));
+		if (prior_lower_page_idx != lower_page_idx
+		    && page_state == ECRYPTFS_PAGE_STATE_MODIFIED) {
+			rc = ecryptfs_write_out_page(ctx, lower_page,
+						     lower_inode,
+						     orig_byte_offset,
+						     (PAGE_CACHE_SIZE
+						      - orig_byte_offset));
+			if (rc) {
+				ecryptfs_printk(KERN_ERR, "Error attempting "
+						"to write out page; rc = [%d]"
+						"\n", rc);
+				goto out;
+			}
+			page_state = ECRYPTFS_PAGE_STATE_WRITTEN;
+		}
+		if (page_state == ECRYPTFS_PAGE_STATE_UNREAD
+		    || page_state == ECRYPTFS_PAGE_STATE_WRITTEN) {
+			rc = ecryptfs_read_in_page(ctx, &lower_page,
+						   lower_inode, lower_page_idx,
+						   lower_byte_offset);
+			if (rc) {
+				ecryptfs_printk(KERN_ERR, "Error attempting "
+						"to read in lower page with "
+						"index [0x%.16x]; rc = [%d]\n",
+						lower_page_idx, rc);
+				goto out;
+			}
+			orig_byte_offset = lower_byte_offset;
+			prior_lower_page_idx = lower_page_idx;
+			page_state = ECRYPTFS_PAGE_STATE_READ;
+		}
+		BUG_ON(!(page_state == ECRYPTFS_PAGE_STATE_MODIFIED
+			 || page_state == ECRYPTFS_PAGE_STATE_READ));
+		rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
+					(base_extent + extent_offset));
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error attempting to "
+					"derive IV for extent [0x%.16x]; "
+					"rc = [%d]\n",
+					(base_extent + extent_offset), rc);
+			goto out;
+		}
+		if (unlikely(ecryptfs_verbosity > 0)) {
+			ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
+					"with iv:\n");
+			ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+			ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+					"encryption:\n");
+			ecryptfs_dump_hex((char *)
+					  (page_address(ctx->page)
+					   + (extent_offset
+					      * crypt_stat->extent_size)), 8);
+		}
+		rc = ecryptfs_encrypt_page_offset(
+			crypt_stat, lower_page, lower_byte_offset, ctx->page,
+			(extent_offset * crypt_stat->extent_size),
+			crypt_stat->extent_size, extent_iv);
+		ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
+				"rc = [%d]\n",
+				(base_extent + extent_offset), rc);
+		if (unlikely(ecryptfs_verbosity > 0)) {
+			ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+					"encryption:\n");
+			ecryptfs_dump_hex((char *)(page_address(lower_page)
+						   + lower_byte_offset), 8);
+		}
+		page_state = ECRYPTFS_PAGE_STATE_MODIFIED;
+		extent_offset++;
+	}
+	BUG_ON(orig_byte_offset != 0);
+	rc = ecryptfs_write_out_page(ctx, lower_page, lower_inode, 0,
+				     (lower_byte_offset
+				      + crypt_stat->extent_size));
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error attempting to write out "
+				"page; rc = [%d]\n", rc);
+				goto out;
+	}
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_decrypt_page
+ * @file: The ecryptfs file
+ * @page: The page in ecryptfs to decrypt
+ *
+ * Decrypt an eCryptfs page. This is done on a per-extent basis. Note
+ * that eCryptfs pages may straddle the lower pages -- for instance,
+ * if the file was created on a machine with an 8K page size
+ * (resulting in an 8K header), and then the file is copied onto a
+ * host with a 32K page size, then when reading page 0 of the eCryptfs
+ * file, 24K of page 0 of the lower file will be read and decrypted,
+ * and then 8K of page 1 of the lower file will be read and decrypted.
+ *
+ * Returns zero on success; negative on error
+ */
+int ecryptfs_decrypt_page(struct file *file, struct page *page)
+{
+	char extent_iv[ECRYPTFS_MAX_IV_BYTES];
+	unsigned long base_extent;
+	unsigned long extent_offset = 0;
+	unsigned long lower_page_idx = 0;
+	unsigned long prior_lower_page_idx = 0;
+	struct page *lower_page;
+	char *lower_page_virt = NULL;
+	struct inode *lower_inode;
+	struct ecryptfs_crypt_stat *crypt_stat;
+	int rc = 0;
+	int byte_offset;
+	int num_extents_per_page;
+	int page_state;
+
+	crypt_stat = &(ecryptfs_inode_to_private(
+			       page->mapping->host)->crypt_stat);
+	lower_inode = ecryptfs_inode_to_lower(page->mapping->host);
+	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) {
+		rc = ecryptfs_do_readpage(file, page, page->index);
+		if (rc)
+			ecryptfs_printk(KERN_ERR, "Error attempting to copy "
+					"page at index [0x%.16x]\n",
+					page->index);
+		goto out;
+	}
+	num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
+	base_extent = (page->index * num_extents_per_page);
+	lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache,
+					   SLAB_KERNEL);
+	if (!lower_page_virt) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR, "Error getting page for encrypted "
+				"lower page(s)\n");
+		goto out;
+	}
+	lower_page = virt_to_page(lower_page_virt);
+	page_state = ECRYPTFS_PAGE_STATE_UNREAD;
+	while (extent_offset < num_extents_per_page) {
+		ecryptfs_extent_to_lwr_pg_idx_and_offset(
+			&lower_page_idx, &byte_offset, crypt_stat,
+			(base_extent + extent_offset));
+		if (prior_lower_page_idx != lower_page_idx
+		    || page_state == ECRYPTFS_PAGE_STATE_UNREAD) {
+			rc = ecryptfs_do_readpage(file, lower_page,
+						  lower_page_idx);
+			if (rc) {
+				ecryptfs_printk(KERN_ERR, "Error reading "
+						"lower encrypted page; rc = "
+						"[%d]\n", rc);
+				goto out;
+			}
+			prior_lower_page_idx = lower_page_idx;
+			page_state = ECRYPTFS_PAGE_STATE_READ;
+		}
+		rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
+					(base_extent + extent_offset));
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error attempting to "
+					"derive IV for extent [0x%.16x]; rc = "
+					"[%d]\n",
+					(base_extent + extent_offset), rc);
+			goto out;
+		}
+		if (unlikely(ecryptfs_verbosity > 0)) {
+			ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
+					"with iv:\n");
+			ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+			ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+					"decryption:\n");
+			ecryptfs_dump_hex((lower_page_virt + byte_offset), 8);
+		}
+		rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
+						  (extent_offset
+						   * crypt_stat->extent_size),
+						  lower_page, byte_offset,
+						  crypt_stat->extent_size,
+						  extent_iv);
+		if (rc != crypt_stat->extent_size) {
+			ecryptfs_printk(KERN_ERR, "Error attempting to "
+					"decrypt extent [0x%.16x]\n",
+					(base_extent + extent_offset));
+			goto out;
+		}
+		rc = 0;
+		if (unlikely(ecryptfs_verbosity > 0)) {
+			ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+					"decryption:\n");
+			ecryptfs_dump_hex((char *)(page_address(page)
+						   + byte_offset), 8);
+		}
+		extent_offset++;
+	}
+out:
+	if (lower_page_virt)
+		kmem_cache_free(ecryptfs_lower_page_cache, lower_page_virt);
+	return rc;
+}
+
+/**
+ * decrypt_scatterlist
+ *
+ * Returns the number of bytes decrypted; negative value on error
+ */
+static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
+			       struct scatterlist *dest_sg,
+			       struct scatterlist *src_sg, int size,
+			       unsigned char *iv)
+{
+	int rc = 0;
+
+	/* Consider doing this once, when the file is opened */
+	mutex_lock(&crypt_stat->cs_tfm_mutex);
+	rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
+				  crypt_stat->key_size);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
+				rc);
+		mutex_unlock(&crypt_stat->cs_tfm_mutex);
+		rc = -EINVAL;
+		goto out;
+	}
+	ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
+	rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size,
+				      iv);
+	mutex_unlock(&crypt_stat->cs_tfm_mutex);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
+				rc);
+		goto out;
+	}
+	rc = size;
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_encrypt_page_offset
+ *
+ * Returns the number of bytes encrypted
+ */
+static int
+ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+			     struct page *dst_page, int dst_offset,
+			     struct page *src_page, int src_offset, int size,
+			     unsigned char *iv)
+{
+	struct scatterlist src_sg, dst_sg;
+
+	src_sg.page = src_page;
+	src_sg.offset = src_offset;
+	src_sg.length = size;
+	dst_sg.page = dst_page;
+	dst_sg.offset = dst_offset;
+	dst_sg.length = size;
+	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
+}
+
+/**
+ * ecryptfs_decrypt_page_offset
+ *
+ * Returns the number of bytes decrypted
+ */
+static int
+ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+			     struct page *dst_page, int dst_offset,
+			     struct page *src_page, int src_offset, int size,
+			     unsigned char *iv)
+{
+	struct scatterlist src_sg, dst_sg;
+
+	src_sg.page = src_page;
+	src_sg.offset = src_offset;
+	src_sg.length = size;
+	dst_sg.page = dst_page;
+	dst_sg.offset = dst_offset;
+	dst_sg.length = size;
+	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
+}
+
+#define ECRYPTFS_MAX_SCATTERLIST_LEN 4
+
+/**
+ * ecryptfs_init_crypt_ctx
+ * @crypt_stat: Uninitilized crypt stats structure
+ *
+ * Initialize the crypto context.
+ *
+ * TODO: Performance: Keep a cache of initialized cipher contexts;
+ * only init if needed
+ */
+int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	int rc = -EINVAL;
+
+	if (!crypt_stat->cipher) {
+		ecryptfs_printk(KERN_ERR, "No cipher specified\n");
+		goto out;
+	}
+	ecryptfs_printk(KERN_DEBUG,
+			"Initializing cipher [%s]; strlen = [%d]; "
+			"key_size_bits = [%d]\n",
+			crypt_stat->cipher, (int)strlen(crypt_stat->cipher),
+			crypt_stat->key_size << 3);
+	if (crypt_stat->tfm) {
+		rc = 0;
+		goto out;
+	}
+	mutex_lock(&crypt_stat->cs_tfm_mutex);
+	crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
+					   ECRYPTFS_DEFAULT_CHAINING_MODE
+					   | CRYPTO_TFM_REQ_WEAK_KEY);
+	mutex_unlock(&crypt_stat->cs_tfm_mutex);
+	if (!crypt_stat->tfm) {
+		ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
+				"Error initializing cipher [%s]\n",
+				crypt_stat->cipher);
+		goto out;
+	}
+	rc = 0;
+out:
+	return rc;
+}
+
+static void set_extent_mask_and_shift(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	int extent_size_tmp;
+
+	crypt_stat->extent_mask = 0xFFFFFFFF;
+	crypt_stat->extent_shift = 0;
+	if (crypt_stat->extent_size == 0)
+		return;
+	extent_size_tmp = crypt_stat->extent_size;
+	while ((extent_size_tmp & 0x01) == 0) {
+		extent_size_tmp >>= 1;
+		crypt_stat->extent_mask <<= 1;
+		crypt_stat->extent_shift++;
+	}
+}
+
+void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	/* Default values; may be overwritten as we are parsing the
+	 * packets. */
+	crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE;
+	set_extent_mask_and_shift(crypt_stat);
+	crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
+	if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
+		crypt_stat->header_extent_size =
+			ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
+	} else
+		crypt_stat->header_extent_size = PAGE_CACHE_SIZE;
+	crypt_stat->num_header_extents_at_front = 1;
+}
+
+/**
+ * ecryptfs_compute_root_iv
+ * @crypt_stats
+ *
+ * On error, sets the root IV to all 0's.
+ */
+int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	int rc = 0;
+	char dst[MD5_DIGEST_SIZE];
+
+	BUG_ON(crypt_stat->iv_bytes > MD5_DIGEST_SIZE);
+	BUG_ON(crypt_stat->iv_bytes <= 0);
+	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID)) {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_WARNING, "Session key not valid; "
+				"cannot generate root IV\n");
+		goto out;
+	}
+	rc = ecryptfs_calculate_md5(dst, crypt_stat, crypt_stat->key,
+				    crypt_stat->key_size);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "Error attempting to compute "
+				"MD5 while generating root IV\n");
+		goto out;
+	}
+	memcpy(crypt_stat->root_iv, dst, crypt_stat->iv_bytes);
+out:
+	if (rc) {
+		memset(crypt_stat->root_iv, 0, crypt_stat->iv_bytes);
+		ECRYPTFS_SET_FLAG(crypt_stat->flags,
+				  ECRYPTFS_SECURITY_WARNING);
+	}
+	return rc;
+}
+
+static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	get_random_bytes(crypt_stat->key, crypt_stat->key_size);
+	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+	ecryptfs_compute_root_iv(crypt_stat);
+	if (unlikely(ecryptfs_verbosity > 0)) {
+		ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n");
+		ecryptfs_dump_hex(crypt_stat->key,
+				  crypt_stat->key_size);
+	}
+}
+
+/**
+ * ecryptfs_set_default_crypt_stat_vals
+ * @crypt_stat
+ *
+ * Default values in the event that policy does not override them.
+ */
+static void ecryptfs_set_default_crypt_stat_vals(
+	struct ecryptfs_crypt_stat *crypt_stat,
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+	ecryptfs_set_default_sizes(crypt_stat);
+	strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER);
+	crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES;
+	ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+	crypt_stat->file_version = ECRYPTFS_FILE_VERSION;
+	crypt_stat->mount_crypt_stat = mount_crypt_stat;
+}
+
+/**
+ * ecryptfs_new_file_context
+ * @ecryptfs_dentry
+ *
+ * If the crypto context for the file has not yet been established,
+ * this is where we do that.  Establishing a new crypto context
+ * involves the following decisions:
+ *  - What cipher to use?
+ *  - What set of authentication tokens to use?
+ * Here we just worry about getting enough information into the
+ * authentication tokens so that we know that they are available.
+ * We associate the available authentication tokens with the new file
+ * via the set of signatures in the crypt_stat struct.  Later, when
+ * the headers are actually written out, we may again defer to
+ * userspace to perform the encryption of the session key; for the
+ * foreseeable future, this will be the case with public key packets.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+/* Associate an authentication token(s) with the file */
+int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
+{
+	int rc = 0;
+	struct ecryptfs_crypt_stat *crypt_stat =
+	    &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+	    &ecryptfs_superblock_to_private(
+		    ecryptfs_dentry->d_sb)->mount_crypt_stat;
+	int cipher_name_len;
+
+	ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat);
+	/* See if there are mount crypt options */
+	if (mount_crypt_stat->global_auth_tok) {
+		ecryptfs_printk(KERN_DEBUG, "Initializing context for new "
+				"file using mount_crypt_stat\n");
+		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+		memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++],
+		       mount_crypt_stat->global_auth_tok_sig,
+		       ECRYPTFS_SIG_SIZE_HEX);
+		cipher_name_len =
+		    strlen(mount_crypt_stat->global_default_cipher_name);
+		memcpy(crypt_stat->cipher,
+		       mount_crypt_stat->global_default_cipher_name,
+		       cipher_name_len);
+		crypt_stat->cipher[cipher_name_len] = '\0';
+		crypt_stat->key_size =
+			mount_crypt_stat->global_default_cipher_key_size;
+		ecryptfs_generate_new_key(crypt_stat);
+	} else
+		/* We should not encounter this scenario since we
+		 * should detect lack of global_auth_tok at mount time
+		 * TODO: Applies to 0.1 release only; remove in future
+		 * release */
+		BUG();
+	rc = ecryptfs_init_crypt_ctx(crypt_stat);
+	if (rc)
+		ecryptfs_printk(KERN_ERR, "Error initializing cryptographic "
+				"context for cipher [%s]: rc = [%d]\n",
+				crypt_stat->cipher, rc);
+	return rc;
+}
+
+/**
+ * contains_ecryptfs_marker - check for the ecryptfs marker
+ * @data: The data block in which to check
+ *
+ * Returns one if marker found; zero if not found
+ */
+int contains_ecryptfs_marker(char *data)
+{
+	u32 m_1, m_2;
+
+	memcpy(&m_1, data, 4);
+	m_1 = be32_to_cpu(m_1);
+	memcpy(&m_2, (data + 4), 4);
+	m_2 = be32_to_cpu(m_2);
+	if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2)
+		return 1;
+	ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; "
+			"MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2,
+			MAGIC_ECRYPTFS_MARKER);
+	ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = "
+			"[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER));
+	return 0;
+}
+
+struct ecryptfs_flag_map_elem {
+	u32 file_flag;
+	u32 local_flag;
+};
+
+/* Add support for additional flags by adding elements here. */
+static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = {
+	{0x00000001, ECRYPTFS_ENABLE_HMAC},
+	{0x00000002, ECRYPTFS_ENCRYPTED}
+};
+
+/**
+ * ecryptfs_process_flags
+ * @crypt_stat
+ * @page_virt: Source data to be parsed
+ * @bytes_read: Updated with the number of bytes read
+ *
+ * Returns zero on success; non-zero if the flag set is invalid
+ */
+static int ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat,
+				  char *page_virt, int *bytes_read)
+{
+	int rc = 0;
+	int i;
+	u32 flags;
+
+	memcpy(&flags, page_virt, 4);
+	flags = be32_to_cpu(flags);
+	for (i = 0; i < ((sizeof(ecryptfs_flag_map)
+			  / sizeof(struct ecryptfs_flag_map_elem))); i++)
+		if (flags & ecryptfs_flag_map[i].file_flag) {
+			ECRYPTFS_SET_FLAG(crypt_stat->flags,
+					  ecryptfs_flag_map[i].local_flag);
+		} else
+			ECRYPTFS_CLEAR_FLAG(crypt_stat->flags,
+					    ecryptfs_flag_map[i].local_flag);
+	/* Version is in top 8 bits of the 32-bit flag vector */
+	crypt_stat->file_version = ((flags >> 24) & 0xFF);
+	(*bytes_read) = 4;
+	return rc;
+}
+
+/**
+ * write_ecryptfs_marker
+ * @page_virt: The pointer to in a page to begin writing the marker
+ * @written: Number of bytes written
+ *
+ * Marker = 0x3c81b7f5
+ */
+static void write_ecryptfs_marker(char *page_virt, size_t *written)
+{
+	u32 m_1, m_2;
+
+	get_random_bytes(&m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
+	m_2 = (m_1 ^ MAGIC_ECRYPTFS_MARKER);
+	m_1 = cpu_to_be32(m_1);
+	memcpy(page_virt, &m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
+	m_2 = cpu_to_be32(m_2);
+	memcpy(page_virt + (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2), &m_2,
+	       (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
+	(*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
+}
+
+static void
+write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
+		     size_t *written)
+{
+	u32 flags = 0;
+	int i;
+
+	for (i = 0; i < ((sizeof(ecryptfs_flag_map)
+			  / sizeof(struct ecryptfs_flag_map_elem))); i++)
+		if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+					ecryptfs_flag_map[i].local_flag))
+			flags |= ecryptfs_flag_map[i].file_flag;
+	/* Version is in top 8 bits of the 32-bit flag vector */
+	flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000);
+	flags = cpu_to_be32(flags);
+	memcpy(page_virt, &flags, 4);
+	(*written) = 4;
+}
+
+struct ecryptfs_cipher_code_str_map_elem {
+	char cipher_str[16];
+	u16 cipher_code;
+};
+
+/* Add support for additional ciphers by adding elements here. The
+ * cipher_code is whatever OpenPGP applicatoins use to identify the
+ * ciphers. List in order of probability. */
+static struct ecryptfs_cipher_code_str_map_elem
+ecryptfs_cipher_code_str_map[] = {
+	{"aes",RFC2440_CIPHER_AES_128 },
+	{"blowfish", RFC2440_CIPHER_BLOWFISH},
+	{"des3_ede", RFC2440_CIPHER_DES3_EDE},
+	{"cast5", RFC2440_CIPHER_CAST_5},
+	{"twofish", RFC2440_CIPHER_TWOFISH},
+	{"cast6", RFC2440_CIPHER_CAST_6},
+	{"aes", RFC2440_CIPHER_AES_192},
+	{"aes", RFC2440_CIPHER_AES_256}
+};
+
+/**
+ * ecryptfs_code_for_cipher_string
+ * @str: The string representing the cipher name
+ *
+ * Returns zero on no match, or the cipher code on match
+ */
+u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	int i;
+	u16 code = 0;
+	struct ecryptfs_cipher_code_str_map_elem *map =
+		ecryptfs_cipher_code_str_map;
+
+	if (strcmp(crypt_stat->cipher, "aes") == 0) {
+		switch (crypt_stat->key_size) {
+		case 16:
+			code = RFC2440_CIPHER_AES_128;
+			break;
+		case 24:
+			code = RFC2440_CIPHER_AES_192;
+			break;
+		case 32:
+			code = RFC2440_CIPHER_AES_256;
+		}
+	} else {
+		for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++)
+			if (strcmp(crypt_stat->cipher, map[i].cipher_str) == 0){
+				code = map[i].cipher_code;
+				break;
+			}
+	}
+	return code;
+}
+
+/**
+ * ecryptfs_cipher_code_to_string
+ * @str: Destination to write out the cipher name
+ * @cipher_code: The code to convert to cipher name string
+ *
+ * Returns zero on success
+ */
+int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
+{
+	int rc = 0;
+	int i;
+
+	str[0] = '\0';
+	for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++)
+		if (cipher_code == ecryptfs_cipher_code_str_map[i].cipher_code)
+			strcpy(str, ecryptfs_cipher_code_str_map[i].cipher_str);
+	if (str[0] == '\0') {
+		ecryptfs_printk(KERN_WARNING, "Cipher code not recognized: "
+				"[%d]\n", cipher_code);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+/**
+ * ecryptfs_read_header_region
+ * @data
+ * @dentry
+ * @nd
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_read_header_region(char *data, struct dentry *dentry,
+				struct vfsmount *mnt)
+{
+	struct file *file;
+	mm_segment_t oldfs;
+	int rc;
+
+	mnt = mntget(mnt);
+	file = dentry_open(dentry, mnt, O_RDONLY);
+	if (IS_ERR(file)) {
+		ecryptfs_printk(KERN_DEBUG, "Error opening file to "
+				"read header region\n");
+		mntput(mnt);
+		rc = PTR_ERR(file);
+		goto out;
+	}
+	file->f_pos = 0;
+	oldfs = get_fs();
+	set_fs(get_ds());
+	/* For releases 0.1 and 0.2, all of the header information
+	 * fits in the first data extent-sized region. */
+	rc = file->f_op->read(file, (char __user *)data,
+			      ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos);
+	set_fs(oldfs);
+	fput(file);
+	rc = 0;
+out:
+	return rc;
+}
+
+static void
+write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat,
+		      size_t *written)
+{
+	u32 header_extent_size;
+	u16 num_header_extents_at_front;
+
+	header_extent_size = (u32)crypt_stat->header_extent_size;
+	num_header_extents_at_front =
+		(u16)crypt_stat->num_header_extents_at_front;
+	header_extent_size = cpu_to_be32(header_extent_size);
+	memcpy(virt, &header_extent_size, 4);
+	virt += 4;
+	num_header_extents_at_front = cpu_to_be16(num_header_extents_at_front);
+	memcpy(virt, &num_header_extents_at_front, 2);
+	(*written) = 6;
+}
+
+struct kmem_cache *ecryptfs_header_cache_0;
+struct kmem_cache *ecryptfs_header_cache_1;
+struct kmem_cache *ecryptfs_header_cache_2;
+
+/**
+ * ecryptfs_write_headers_virt
+ * @page_virt
+ * @crypt_stat
+ * @ecryptfs_dentry
+ *
+ * Format version: 1
+ *
+ *   Header Extent:
+ *     Octets 0-7:        Unencrypted file size (big-endian)
+ *     Octets 8-15:       eCryptfs special marker
+ *     Octets 16-19:      Flags
+ *      Octet 16:         File format version number (between 0 and 255)
+ *      Octets 17-18:     Reserved
+ *      Octet 19:         Bit 1 (lsb): Reserved
+ *                        Bit 2: Encrypted?
+ *                        Bits 3-8: Reserved
+ *     Octets 20-23:      Header extent size (big-endian)
+ *     Octets 24-25:      Number of header extents at front of file
+ *                        (big-endian)
+ *     Octet  26:         Begin RFC 2440 authentication token packet set
+ *   Data Extent 0:
+ *     Lower data (CBC encrypted)
+ *   Data Extent 1:
+ *     Lower data (CBC encrypted)
+ *   ...
+ *
+ * Returns zero on success
+ */
+int ecryptfs_write_headers_virt(char *page_virt,
+				struct ecryptfs_crypt_stat *crypt_stat,
+				struct dentry *ecryptfs_dentry)
+{
+	int rc;
+	size_t written;
+	size_t offset;
+
+	offset = ECRYPTFS_FILE_SIZE_BYTES;
+	write_ecryptfs_marker((page_virt + offset), &written);
+	offset += written;
+	write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
+	offset += written;
+	write_header_metadata((page_virt + offset), crypt_stat, &written);
+	offset += written;
+	rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat,
+					      ecryptfs_dentry, &written,
+					      PAGE_CACHE_SIZE - offset);
+	if (rc)
+		ecryptfs_printk(KERN_WARNING, "Error generating key packet "
+				"set; rc = [%d]\n", rc);
+	return rc;
+}
+
+/**
+ * ecryptfs_write_headers
+ * @lower_file: The lower file struct, which was returned from dentry_open
+ *
+ * Write the file headers out.  This will likely involve a userspace
+ * callout, in which the session key is encrypted with one or more
+ * public keys and/or the passphrase necessary to do the encryption is
+ * retrieved via a prompt.  Exactly what happens at this point should
+ * be policy-dependent.
+ *
+ * Returns zero on success; non-zero on error
+ */
+int ecryptfs_write_headers(struct dentry *ecryptfs_dentry,
+			   struct file *lower_file)
+{
+	mm_segment_t oldfs;
+	struct ecryptfs_crypt_stat *crypt_stat;
+	char *page_virt;
+	int current_header_page;
+	int header_pages;
+	int rc = 0;
+
+	crypt_stat = &ecryptfs_inode_to_private(
+		ecryptfs_dentry->d_inode)->crypt_stat;
+	if (likely(ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+				       ECRYPTFS_ENCRYPTED))) {
+		if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+					 ECRYPTFS_KEY_VALID)) {
+			ecryptfs_printk(KERN_DEBUG, "Key is "
+					"invalid; bailing out\n");
+			rc = -EINVAL;
+			goto out;
+		}
+	} else {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_WARNING,
+				"Called with crypt_stat->encrypted == 0\n");
+		goto out;
+	}
+	/* Released in this function */
+	page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, SLAB_USER);
+	if (!page_virt) {
+		ecryptfs_printk(KERN_ERR, "Out of memory\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	memset(page_virt, 0, PAGE_CACHE_SIZE);
+	rc = ecryptfs_write_headers_virt(page_virt, crypt_stat,
+					 ecryptfs_dentry);
+	if (unlikely(rc)) {
+		ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n");
+		memset(page_virt, 0, PAGE_CACHE_SIZE);
+		goto out_free;
+	}
+	ecryptfs_printk(KERN_DEBUG,
+			"Writing key packet set to underlying file\n");
+	lower_file->f_pos = 0;
+	oldfs = get_fs();
+	set_fs(get_ds());
+	ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->"
+			"write() w/ header page; lower_file->f_pos = "
+			"[0x%.16x]\n", lower_file->f_pos);
+	lower_file->f_op->write(lower_file, (char __user *)page_virt,
+				PAGE_CACHE_SIZE, &lower_file->f_pos);
+	header_pages = ((crypt_stat->header_extent_size
+			 * crypt_stat->num_header_extents_at_front)
+			/ PAGE_CACHE_SIZE);
+	memset(page_virt, 0, PAGE_CACHE_SIZE);
+	current_header_page = 1;
+	while (current_header_page < header_pages) {
+		ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->"
+				"write() w/ zero'd page; lower_file->f_pos = "
+				"[0x%.16x]\n", lower_file->f_pos);
+		lower_file->f_op->write(lower_file, (char __user *)page_virt,
+					PAGE_CACHE_SIZE, &lower_file->f_pos);
+		current_header_page++;
+	}
+	set_fs(oldfs);
+	ecryptfs_printk(KERN_DEBUG,
+			"Done writing key packet set to underlying file.\n");
+out_free:
+	kmem_cache_free(ecryptfs_header_cache_0, page_virt);
+out:
+	return rc;
+}
+
+static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
+				 char *virt, int *bytes_read)
+{
+	int rc = 0;
+	u32 header_extent_size;
+	u16 num_header_extents_at_front;
+
+	memcpy(&header_extent_size, virt, 4);
+	header_extent_size = be32_to_cpu(header_extent_size);
+	virt += 4;
+	memcpy(&num_header_extents_at_front, virt, 2);
+	num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front);
+	crypt_stat->header_extent_size = (int)header_extent_size;
+	crypt_stat->num_header_extents_at_front =
+		(int)num_header_extents_at_front;
+	(*bytes_read) = 6;
+	if ((crypt_stat->header_extent_size
+	     * crypt_stat->num_header_extents_at_front)
+	    < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_WARNING, "Invalid header extent size: "
+				"[%d]\n", crypt_stat->header_extent_size);
+	}
+	return rc;
+}
+
+/**
+ * set_default_header_data
+ *
+ * For version 0 file format; this function is only for backwards
+ * compatibility for files created with the prior versions of
+ * eCryptfs.
+ */
+static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	crypt_stat->header_extent_size = 4096;
+	crypt_stat->num_header_extents_at_front = 1;
+}
+
+/**
+ * ecryptfs_read_headers_virt
+ *
+ * Read/parse the header data. The header format is detailed in the
+ * comment block for the ecryptfs_write_headers_virt() function.
+ *
+ * Returns zero on success
+ */
+static int ecryptfs_read_headers_virt(char *page_virt,
+				      struct ecryptfs_crypt_stat *crypt_stat,
+				      struct dentry *ecryptfs_dentry)
+{
+	int rc = 0;
+	int offset;
+	int bytes_read;
+
+	ecryptfs_set_default_sizes(crypt_stat);
+	crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private(
+		ecryptfs_dentry->d_sb)->mount_crypt_stat;
+	offset = ECRYPTFS_FILE_SIZE_BYTES;
+	rc = contains_ecryptfs_marker(page_virt + offset);
+	if (rc == 0) {
+		rc = -EINVAL;
+		goto out;
+	}
+	offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
+	rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset),
+				    &bytes_read);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "Error processing flags\n");
+		goto out;
+	}
+	if (crypt_stat->file_version > ECRYPTFS_SUPPORTED_FILE_VERSION) {
+		ecryptfs_printk(KERN_WARNING, "File version is [%d]; only "
+				"file version [%d] is supported by this "
+				"version of eCryptfs\n",
+				crypt_stat->file_version,
+				ECRYPTFS_SUPPORTED_FILE_VERSION);
+		rc = -EINVAL;
+		goto out;
+	}
+	offset += bytes_read;
+	if (crypt_stat->file_version >= 1) {
+		rc = parse_header_metadata(crypt_stat, (page_virt + offset),
+					   &bytes_read);
+		if (rc) {
+			ecryptfs_printk(KERN_WARNING, "Error reading header "
+					"metadata; rc = [%d]\n", rc);
+		}
+		offset += bytes_read;
+	} else
+		set_default_header_data(crypt_stat);
+	rc = ecryptfs_parse_packet_set(crypt_stat, (page_virt + offset),
+				       ecryptfs_dentry);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_read_headers
+ *
+ * Returns zero if valid headers found and parsed; non-zero otherwise
+ */
+int ecryptfs_read_headers(struct dentry *ecryptfs_dentry,
+			  struct file *lower_file)
+{
+	int rc = 0;
+	char *page_virt = NULL;
+	mm_segment_t oldfs;
+	ssize_t bytes_read;
+	struct ecryptfs_crypt_stat *crypt_stat =
+	    &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+
+	/* Read the first page from the underlying file */
+	page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, SLAB_USER);
+	if (!page_virt) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n");
+		goto out;
+	}
+	lower_file->f_pos = 0;
+	oldfs = get_fs();
+	set_fs(get_ds());
+	bytes_read = lower_file->f_op->read(lower_file,
+					    (char __user *)page_virt,
+					    ECRYPTFS_DEFAULT_EXTENT_SIZE,
+					    &lower_file->f_pos);
+	set_fs(oldfs);
+	if (bytes_read != ECRYPTFS_DEFAULT_EXTENT_SIZE) {
+		rc = -EINVAL;
+		goto out;
+	}
+	rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
+					ecryptfs_dentry);
+	if (rc) {
+		ecryptfs_printk(KERN_DEBUG, "Valid eCryptfs headers not "
+				"found\n");
+		rc = -EINVAL;
+	}
+out:
+	if (page_virt) {
+		memset(page_virt, 0, PAGE_CACHE_SIZE);
+		kmem_cache_free(ecryptfs_header_cache_1, page_virt);
+	}
+	return rc;
+}
+
+/**
+ * ecryptfs_encode_filename - converts a plaintext file name to cipher text
+ * @crypt_stat: The crypt_stat struct associated with the file anem to encode
+ * @name: The plaintext name
+ * @length: The length of the plaintext
+ * @encoded_name: The encypted name
+ *
+ * Encrypts and encodes a filename into something that constitutes a
+ * valid filename for a filesystem, with printable characters.
+ *
+ * We assume that we have a properly initialized crypto context,
+ * pointed to by crypt_stat->tfm.
+ *
+ * TODO: Implement filename decoding and decryption here, in place of
+ * memcpy. We are keeping the framework around for now to (1)
+ * facilitate testing of the components needed to implement filename
+ * encryption and (2) to provide a code base from which other
+ * developers in the community can easily implement this feature.
+ *
+ * Returns the length of encoded filename; negative if error
+ */
+int
+ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+			 const char *name, int length, char **encoded_name)
+{
+	int error = 0;
+
+	(*encoded_name) = kmalloc(length + 2, GFP_KERNEL);
+	if (!(*encoded_name)) {
+		error = -ENOMEM;
+		goto out;
+	}
+	/* TODO: Filename encryption is a scheduled feature for a
+	 * future version of eCryptfs. This function is here only for
+	 * the purpose of providing a framework for other developers
+	 * to easily implement filename encryption. Hint: Replace this
+	 * memcpy() with a call to encrypt and encode the
+	 * filename, the set the length accordingly. */
+	memcpy((void *)(*encoded_name), (void *)name, length);
+	(*encoded_name)[length] = '\0';
+	error = length + 1;
+out:
+	return error;
+}
+
+/**
+ * ecryptfs_decode_filename - converts the cipher text name to plaintext
+ * @crypt_stat: The crypt_stat struct associated with the file
+ * @name: The filename in cipher text
+ * @length: The length of the cipher text name
+ * @decrypted_name: The plaintext name
+ *
+ * Decodes and decrypts the filename.
+ *
+ * We assume that we have a properly initialized crypto context,
+ * pointed to by crypt_stat->tfm.
+ *
+ * TODO: Implement filename decoding and decryption here, in place of
+ * memcpy. We are keeping the framework around for now to (1)
+ * facilitate testing of the components needed to implement filename
+ * encryption and (2) to provide a code base from which other
+ * developers in the community can easily implement this feature.
+ *
+ * Returns the length of decoded filename; negative if error
+ */
+int
+ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+			 const char *name, int length, char **decrypted_name)
+{
+	int error = 0;
+
+	(*decrypted_name) = kmalloc(length + 2, GFP_KERNEL);
+	if (!(*decrypted_name)) {
+		error = -ENOMEM;
+		goto out;
+	}
+	/* TODO: Filename encryption is a scheduled feature for a
+	 * future version of eCryptfs. This function is here only for
+	 * the purpose of providing a framework for other developers
+	 * to easily implement filename encryption. Hint: Replace this
+	 * memcpy() with a call to decode and decrypt the
+	 * filename, the set the length accordingly. */
+	memcpy((void *)(*decrypted_name), (void *)name, length);
+	(*decrypted_name)[length + 1] = '\0';	/* Only for convenience
+						 * in printing out the
+						 * string in debug
+						 * messages */
+	error = length;
+out:
+	return error;
+}
+
+/**
+ * ecryptfs_process_cipher - Perform cipher initialization.
+ * @tfm: Crypto context set by this function
+ * @key_tfm: Crypto context for key material, set by this function
+ * @cipher_name: Name of the cipher.
+ * @key_size: Size of the key in bytes.
+ *
+ * Returns zero on success. Any crypto_tfm structs allocated here
+ * should be released by other functions, such as on a superblock put
+ * event, regardless of whether this function succeeds for fails.
+ */
+int
+ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
+			char *cipher_name, size_t key_size)
+{
+	char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
+	int rc;
+
+	*tfm = *key_tfm = NULL;
+	if (key_size > ECRYPTFS_MAX_KEY_BYTES) {
+		rc = -EINVAL;
+		printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum "
+		       "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES);
+		goto out;
+	}
+	*tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE
+					      | CRYPTO_TFM_REQ_WEAK_KEY));
+	if (!(*tfm)) {
+		rc = -EINVAL;
+		printk(KERN_ERR "Unable to allocate crypto cipher with name "
+		       "[%s]\n", cipher_name);
+		goto out;
+	}
+	*key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY);
+	if (!(*key_tfm)) {
+		rc = -EINVAL;
+		printk(KERN_ERR "Unable to allocate crypto cipher with name "
+		       "[%s]\n", cipher_name);
+		goto out;
+	}
+	if (key_size < crypto_tfm_alg_min_keysize(*tfm)) {
+		rc = -EINVAL;
+		printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
+		       "supported by cipher [%s] is [%d]\n", key_size,
+		       cipher_name, crypto_tfm_alg_min_keysize(*tfm));
+		goto out;
+	}
+	if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) {
+		rc = -EINVAL;
+		printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
+		       "supported by cipher [%s] is [%d]\n", key_size,
+		       cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
+		goto out;
+	}
+	if (key_size > crypto_tfm_alg_max_keysize(*tfm)) {
+		rc = -EINVAL;
+		printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
+		       "supported by cipher [%s] is [%d]\n", key_size,
+		       cipher_name, crypto_tfm_alg_min_keysize(*tfm));
+		goto out;
+	}
+	if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) {
+		rc = -EINVAL;
+		printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
+		       "supported by cipher [%s] is [%d]\n", key_size,
+		       cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
+		goto out;
+	}
+	get_random_bytes(dummy_key, key_size);
+	rc = crypto_cipher_setkey(*tfm, dummy_key, key_size);
+	if (rc) {
+		printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
+		       "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+		rc = -EINVAL;
+		goto out;
+	}
+	rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size);
+	if (rc) {
+		printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
+		       "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+		rc = -EINVAL;
+		goto out;
+	}
+out:
+	return rc;
+}
diff --git a/fs/ecryptfs/debug.c b/fs/ecryptfs/debug.c
new file mode 100644
index 0000000..61f8e89
--- /dev/null
+++ b/fs/ecryptfs/debug.c
@@ -0,0 +1,123 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * Functions only useful for debugging.
+ *
+ * Copyright (C) 2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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 "ecryptfs_kernel.h"
+
+/**
+ * ecryptfs_dump_auth_tok - debug function to print auth toks
+ *
+ * This function will print the contents of an ecryptfs authentication
+ * token.
+ */
+void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok)
+{
+	char salt[ECRYPTFS_SALT_SIZE * 2 + 1];
+	char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+
+	ecryptfs_printk(KERN_DEBUG, "Auth tok at mem loc [%p]:\n",
+			auth_tok);
+	if (ECRYPTFS_CHECK_FLAG(auth_tok->flags, ECRYPTFS_PRIVATE_KEY)) {
+		ecryptfs_printk(KERN_DEBUG, " * private key type\n");
+		ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT "
+				"IN ECRYPTFS VERSION 0.1)\n");
+	} else {
+		ecryptfs_printk(KERN_DEBUG, " * passphrase type\n");
+		ecryptfs_to_hex(salt, auth_tok->token.password.salt,
+				ECRYPTFS_SALT_SIZE);
+		salt[ECRYPTFS_SALT_SIZE * 2] = '\0';
+		ecryptfs_printk(KERN_DEBUG, " * salt = [%s]\n", salt);
+		if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
+					ECRYPTFS_PERSISTENT_PASSWORD)) {
+			ecryptfs_printk(KERN_DEBUG, " * persistent\n");
+		}
+		memcpy(sig, auth_tok->token.password.signature,
+		       ECRYPTFS_SIG_SIZE_HEX);
+		sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+		ecryptfs_printk(KERN_DEBUG, " * signature = [%s]\n", sig);
+	}
+	ecryptfs_printk(KERN_DEBUG, " * session_key.flags = [0x%x]\n",
+			auth_tok->session_key.flags);
+	if (auth_tok->session_key.flags
+	    & ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT)
+		ecryptfs_printk(KERN_DEBUG,
+				" * Userspace decrypt request set\n");
+	if (auth_tok->session_key.flags
+	    & ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT)
+		ecryptfs_printk(KERN_DEBUG,
+				" * Userspace encrypt request set\n");
+	if (auth_tok->session_key.flags & ECRYPTFS_CONTAINS_DECRYPTED_KEY) {
+		ecryptfs_printk(KERN_DEBUG, " * Contains decrypted key\n");
+		ecryptfs_printk(KERN_DEBUG,
+				" * session_key.decrypted_key_size = [0x%x]\n",
+				auth_tok->session_key.decrypted_key_size);
+		ecryptfs_printk(KERN_DEBUG, " * Decrypted session key "
+				"dump:\n");
+		if (ecryptfs_verbosity > 0)
+			ecryptfs_dump_hex(auth_tok->session_key.decrypted_key,
+					  ECRYPTFS_DEFAULT_KEY_BYTES);
+	}
+	if (auth_tok->session_key.flags & ECRYPTFS_CONTAINS_ENCRYPTED_KEY) {
+		ecryptfs_printk(KERN_DEBUG, " * Contains encrypted key\n");
+		ecryptfs_printk(KERN_DEBUG,
+				" * session_key.encrypted_key_size = [0x%x]\n",
+				auth_tok->session_key.encrypted_key_size);
+		ecryptfs_printk(KERN_DEBUG, " * Encrypted session key "
+				"dump:\n");
+		if (ecryptfs_verbosity > 0)
+			ecryptfs_dump_hex(auth_tok->session_key.encrypted_key,
+					  auth_tok->session_key.
+					  encrypted_key_size);
+	}
+}
+
+/**
+ * ecryptfs_dump_hex - debug hex printer
+ * @data: string of bytes to be printed
+ * @bytes: number of bytes to print
+ *
+ * Dump hexadecimal representation of char array
+ */
+void ecryptfs_dump_hex(char *data, int bytes)
+{
+	int i = 0;
+	int add_newline = 1;
+
+	if (ecryptfs_verbosity < 1)
+		return;
+	if (bytes != 0) {
+		printk(KERN_DEBUG "0x%.2x.", (unsigned char)data[i]);
+		i++;
+	}
+	while (i < bytes) {
+		printk("0x%.2x.", (unsigned char)data[i]);
+		i++;
+		if (i % 16 == 0) {
+			printk("\n");
+			add_newline = 0;
+		} else
+			add_newline = 1;
+	}
+	if (add_newline)
+		printk("\n");
+}
+
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
new file mode 100644
index 0000000..f0d2a43
--- /dev/null
+++ b/fs/ecryptfs/dentry.c
@@ -0,0 +1,87 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/dcache.h>
+#include <linux/namei.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * ecryptfs_d_revalidate - revalidate an ecryptfs dentry
+ * @dentry: The ecryptfs dentry
+ * @nd: The associated nameidata
+ *
+ * Called when the VFS needs to revalidate a dentry. This
+ * is called whenever a name lookup finds a dentry in the
+ * dcache. Most filesystems leave this as NULL, because all their
+ * dentries in the dcache are valid.
+ *
+ * Returns 1 if valid, 0 otherwise.
+ *
+ */
+static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+	struct dentry *dentry_save;
+	struct vfsmount *vfsmount_save;
+	int rc = 1;
+
+	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
+		goto out;
+	dentry_save = nd->dentry;
+	vfsmount_save = nd->mnt;
+	nd->dentry = lower_dentry;
+	nd->mnt = lower_mnt;
+	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
+	nd->dentry = dentry_save;
+	nd->mnt = vfsmount_save;
+out:
+	return rc;
+}
+
+struct kmem_cache *ecryptfs_dentry_info_cache;
+
+/**
+ * ecryptfs_d_release
+ * @dentry: The ecryptfs dentry
+ *
+ * Called when a dentry is really deallocated.
+ */
+static void ecryptfs_d_release(struct dentry *dentry)
+{
+	struct dentry *lower_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	if (ecryptfs_dentry_to_private(dentry))
+		kmem_cache_free(ecryptfs_dentry_info_cache,
+				ecryptfs_dentry_to_private(dentry));
+	if (lower_dentry)
+		dput(lower_dentry);
+	return;
+}
+
+struct dentry_operations ecryptfs_dops = {
+	.d_revalidate = ecryptfs_d_revalidate,
+	.d_release = ecryptfs_d_release,
+};
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
new file mode 100644
index 0000000..872c995
--- /dev/null
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -0,0 +1,482 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * Kernel declarations.
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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 ECRYPTFS_KERNEL_H
+#define ECRYPTFS_KERNEL_H
+
+#include <keys/user-type.h>
+#include <linux/fs.h>
+#include <linux/scatterlist.h>
+
+/* Version verification for shared data structures w/ userspace */
+#define ECRYPTFS_VERSION_MAJOR 0x00
+#define ECRYPTFS_VERSION_MINOR 0x04
+#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x01
+/* These flags indicate which features are supported by the kernel
+ * module; userspace tools such as the mount helper read
+ * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
+ * how to behave. */
+#define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001
+#define ECRYPTFS_VERSIONING_PUBKEY 0x00000002
+#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
+#define ECRYPTFS_VERSIONING_POLICY 0x00000008
+#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
+                                  | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH)
+
+#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
+#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
+#define ECRYPTFS_SALT_SIZE 8
+#define ECRYPTFS_SALT_SIZE_HEX (ECRYPTFS_SALT_SIZE*2)
+/* The original signature size is only for what is stored on disk; all
+ * in-memory representations are expanded hex, so it better adapted to
+ * be passed around or referenced on the command line */
+#define ECRYPTFS_SIG_SIZE 8
+#define ECRYPTFS_SIG_SIZE_HEX (ECRYPTFS_SIG_SIZE*2)
+#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_SIG_SIZE_HEX
+#define ECRYPTFS_MAX_KEY_BYTES 64
+#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
+#define ECRYPTFS_DEFAULT_IV_BYTES 16
+#define ECRYPTFS_FILE_VERSION 0x01
+#define ECRYPTFS_DEFAULT_HEADER_EXTENT_SIZE 8192
+#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
+#define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192
+
+#define RFC2440_CIPHER_DES3_EDE 0x02
+#define RFC2440_CIPHER_CAST_5 0x03
+#define RFC2440_CIPHER_BLOWFISH 0x04
+#define RFC2440_CIPHER_AES_128 0x07
+#define RFC2440_CIPHER_AES_192 0x08
+#define RFC2440_CIPHER_AES_256 0x09
+#define RFC2440_CIPHER_TWOFISH 0x0a
+#define RFC2440_CIPHER_CAST_6 0x0b
+
+#define ECRYPTFS_SET_FLAG(flag_bit_vector, flag) (flag_bit_vector |= (flag))
+#define ECRYPTFS_CLEAR_FLAG(flag_bit_vector, flag) (flag_bit_vector &= ~(flag))
+#define ECRYPTFS_CHECK_FLAG(flag_bit_vector, flag) (flag_bit_vector & (flag))
+
+/**
+ * For convenience, we may need to pass around the encrypted session
+ * key between kernel and userspace because the authentication token
+ * may not be extractable.  For example, the TPM may not release the
+ * private key, instead requiring the encrypted data and returning the
+ * decrypted data.
+ */
+struct ecryptfs_session_key {
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002
+#define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004
+#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008
+	u32 flags;
+	u32 encrypted_key_size;
+	u32 decrypted_key_size;
+	u8 encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+	u8 decrypted_key[ECRYPTFS_MAX_KEY_BYTES];
+};
+
+struct ecryptfs_password {
+	u32 password_bytes;
+	s32 hash_algo;
+	u32 hash_iterations;
+	u32 session_key_encryption_key_bytes;
+#define ECRYPTFS_PERSISTENT_PASSWORD 0x01
+#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02
+	u32 flags;
+	/* Iterated-hash concatenation of salt and passphrase */
+	u8 session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+	u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+	/* Always in expanded hex */
+	u8 salt[ECRYPTFS_SALT_SIZE];
+};
+
+enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY};
+
+/* May be a password or a private key */
+struct ecryptfs_auth_tok {
+	u16 version; /* 8-bit major and 8-bit minor */
+	u16 token_type;
+	u32 flags;
+	struct ecryptfs_session_key session_key;
+	u8 reserved[32];
+	union {
+		struct ecryptfs_password password;
+		/* Private key is in future eCryptfs releases */
+	} token;
+} __attribute__ ((packed));
+
+void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok);
+extern void ecryptfs_to_hex(char *dst, char *src, size_t src_size);
+extern void ecryptfs_from_hex(char *dst, char *src, int dst_size);
+
+struct ecryptfs_key_record {
+	unsigned char type;
+	size_t enc_key_size;
+	unsigned char sig[ECRYPTFS_SIG_SIZE];
+	unsigned char enc_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+};
+
+struct ecryptfs_auth_tok_list {
+	struct ecryptfs_auth_tok *auth_tok;
+	struct list_head list;
+};
+
+struct ecryptfs_crypt_stat;
+struct ecryptfs_mount_crypt_stat;
+
+struct ecryptfs_page_crypt_context {
+	struct page *page;
+#define ECRYPTFS_PREPARE_COMMIT_MODE 0
+#define ECRYPTFS_WRITEPAGE_MODE      1
+	unsigned int mode;
+	union {
+		struct file *lower_file;
+		struct writeback_control *wbc;
+	} param;
+};
+
+static inline struct ecryptfs_auth_tok *
+ecryptfs_get_key_payload_data(struct key *key)
+{
+	return (struct ecryptfs_auth_tok *)
+		(((struct user_key_payload*)key->payload.data)->data);
+}
+
+#define ECRYPTFS_SUPER_MAGIC 0xf15f
+#define ECRYPTFS_MAX_KEYSET_SIZE 1024
+#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32
+#define ECRYPTFS_MAX_NUM_ENC_KEYS 64
+#define ECRYPTFS_MAX_NUM_KEYSIGS 2 /* TODO: Make this a linked list */
+#define ECRYPTFS_MAX_IV_BYTES 16	/* 128 bits */
+#define ECRYPTFS_SALT_BYTES 2
+#define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5
+#define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8	/* 4*2 */
+#define ECRYPTFS_FILE_SIZE_BYTES 8
+#define ECRYPTFS_DEFAULT_CIPHER "aes"
+#define ECRYPTFS_DEFAULT_KEY_BYTES 16
+#define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC
+#define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
+#define ECRYPTFS_TAG_11_PACKET_TYPE 0xED
+#define MD5_DIGEST_SIZE 16
+
+/**
+ * This is the primary struct associated with each encrypted file.
+ *
+ * TODO: cache align/pack?
+ */
+struct ecryptfs_crypt_stat {
+#define ECRYPTFS_STRUCT_INITIALIZED 0x00000001
+#define ECRYPTFS_POLICY_APPLIED     0x00000002
+#define ECRYPTFS_NEW_FILE           0x00000004
+#define ECRYPTFS_ENCRYPTED          0x00000008
+#define ECRYPTFS_SECURITY_WARNING   0x00000010
+#define ECRYPTFS_ENABLE_HMAC        0x00000020
+#define ECRYPTFS_ENCRYPT_IV_PAGES   0x00000040
+#define ECRYPTFS_KEY_VALID          0x00000080
+	u32 flags;
+	unsigned int file_version;
+	size_t iv_bytes;
+	size_t num_keysigs;
+	size_t header_extent_size;
+	size_t num_header_extents_at_front;
+	size_t extent_size; /* Data extent size; default is 4096 */
+	size_t key_size;
+	size_t extent_shift;
+	unsigned int extent_mask;
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+	struct crypto_tfm *tfm;
+	struct crypto_tfm *md5_tfm; /* Crypto context for generating
+				     * the initialization vectors */
+	unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
+	unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
+	unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
+	unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX];
+	struct mutex cs_tfm_mutex;
+	struct mutex cs_md5_tfm_mutex;
+	struct mutex cs_mutex;
+};
+
+/* inode private data. */
+struct ecryptfs_inode_info {
+	struct inode vfs_inode;
+	struct inode *wii_inode;
+	struct ecryptfs_crypt_stat crypt_stat;
+};
+
+/* dentry private data. Each dentry must keep track of a lower
+ * vfsmount too. */
+struct ecryptfs_dentry_info {
+	struct dentry *wdi_dentry;
+	struct vfsmount *lower_mnt;
+	struct ecryptfs_crypt_stat *crypt_stat;
+};
+
+/**
+ * This struct is to enable a mount-wide passphrase/salt combo. This
+ * is more or less a stopgap to provide similar functionality to other
+ * crypto filesystems like EncFS or CFS until full policy support is
+ * implemented in eCryptfs.
+ */
+struct ecryptfs_mount_crypt_stat {
+	/* Pointers to memory we do not own, do not free these */
+#define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001
+	u32 flags;
+	struct ecryptfs_auth_tok *global_auth_tok;
+	struct key *global_auth_tok_key;
+	size_t global_default_cipher_key_size;
+	struct crypto_tfm *global_key_tfm;
+	struct mutex global_key_tfm_mutex;
+	unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+						 + 1];
+	unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+};
+
+/* superblock private data. */
+struct ecryptfs_sb_info {
+	struct super_block *wsi_sb;
+	struct ecryptfs_mount_crypt_stat mount_crypt_stat;
+};
+
+/* file private data. */
+struct ecryptfs_file_info {
+	struct file *wfi_file;
+	struct ecryptfs_crypt_stat *crypt_stat;
+};
+
+/* auth_tok <=> encrypted_session_key mappings */
+struct ecryptfs_auth_tok_list_item {
+	unsigned char encrypted_session_key[ECRYPTFS_MAX_KEY_BYTES];
+	struct list_head list;
+	struct ecryptfs_auth_tok auth_tok;
+};
+
+static inline struct ecryptfs_file_info *
+ecryptfs_file_to_private(struct file *file)
+{
+	return (struct ecryptfs_file_info *)file->private_data;
+}
+
+static inline void
+ecryptfs_set_file_private(struct file *file,
+			  struct ecryptfs_file_info *file_info)
+{
+	file->private_data = file_info;
+}
+
+static inline struct file *ecryptfs_file_to_lower(struct file *file)
+{
+	return ((struct ecryptfs_file_info *)file->private_data)->wfi_file;
+}
+
+static inline void
+ecryptfs_set_file_lower(struct file *file, struct file *lower_file)
+{
+	((struct ecryptfs_file_info *)file->private_data)->wfi_file =
+		lower_file;
+}
+
+static inline struct ecryptfs_inode_info *
+ecryptfs_inode_to_private(struct inode *inode)
+{
+	return container_of(inode, struct ecryptfs_inode_info, vfs_inode);
+}
+
+static inline struct inode *ecryptfs_inode_to_lower(struct inode *inode)
+{
+	return ecryptfs_inode_to_private(inode)->wii_inode;
+}
+
+static inline void
+ecryptfs_set_inode_lower(struct inode *inode, struct inode *lower_inode)
+{
+	ecryptfs_inode_to_private(inode)->wii_inode = lower_inode;
+}
+
+static inline struct ecryptfs_sb_info *
+ecryptfs_superblock_to_private(struct super_block *sb)
+{
+	return (struct ecryptfs_sb_info *)sb->s_fs_info;
+}
+
+static inline void
+ecryptfs_set_superblock_private(struct super_block *sb,
+				struct ecryptfs_sb_info *sb_info)
+{
+	sb->s_fs_info = sb_info;
+}
+
+static inline struct super_block *
+ecryptfs_superblock_to_lower(struct super_block *sb)
+{
+	return ((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb;
+}
+
+static inline void
+ecryptfs_set_superblock_lower(struct super_block *sb,
+			      struct super_block *lower_sb)
+{
+	((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb = lower_sb;
+}
+
+static inline struct ecryptfs_dentry_info *
+ecryptfs_dentry_to_private(struct dentry *dentry)
+{
+	return (struct ecryptfs_dentry_info *)dentry->d_fsdata;
+}
+
+static inline void
+ecryptfs_set_dentry_private(struct dentry *dentry,
+			    struct ecryptfs_dentry_info *dentry_info)
+{
+	dentry->d_fsdata = dentry_info;
+}
+
+static inline struct dentry *
+ecryptfs_dentry_to_lower(struct dentry *dentry)
+{
+	return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry;
+}
+
+static inline void
+ecryptfs_set_dentry_lower(struct dentry *dentry, struct dentry *lower_dentry)
+{
+	((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry =
+		lower_dentry;
+}
+
+static inline struct vfsmount *
+ecryptfs_dentry_to_lower_mnt(struct dentry *dentry)
+{
+	return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt;
+}
+
+static inline void
+ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt)
+{
+	((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt =
+		lower_mnt;
+}
+
+#define ecryptfs_printk(type, fmt, arg...) \
+        __ecryptfs_printk(type "%s: " fmt, __FUNCTION__, ## arg);
+void __ecryptfs_printk(const char *fmt, ...);
+
+extern const struct file_operations ecryptfs_main_fops;
+extern const struct file_operations ecryptfs_dir_fops;
+extern struct inode_operations ecryptfs_main_iops;
+extern struct inode_operations ecryptfs_dir_iops;
+extern struct inode_operations ecryptfs_symlink_iops;
+extern struct super_operations ecryptfs_sops;
+extern struct dentry_operations ecryptfs_dops;
+extern struct address_space_operations ecryptfs_aops;
+extern int ecryptfs_verbosity;
+
+extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
+extern struct kmem_cache *ecryptfs_file_info_cache;
+extern struct kmem_cache *ecryptfs_dentry_info_cache;
+extern struct kmem_cache *ecryptfs_inode_info_cache;
+extern struct kmem_cache *ecryptfs_sb_info_cache;
+extern struct kmem_cache *ecryptfs_header_cache_0;
+extern struct kmem_cache *ecryptfs_header_cache_1;
+extern struct kmem_cache *ecryptfs_header_cache_2;
+extern struct kmem_cache *ecryptfs_lower_page_cache;
+
+int ecryptfs_interpose(struct dentry *hidden_dentry,
+		       struct dentry *this_dentry, struct super_block *sb,
+		       int flag);
+int ecryptfs_fill_zeros(struct file *file, loff_t new_length);
+int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+			     const char *name, int length,
+			     char **decrypted_name);
+int ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+			     const char *name, int length,
+			     char **encoded_name);
+struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry);
+void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src);
+void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src);
+void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src);
+void ecryptfs_dump_hex(char *data, int bytes);
+int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
+			int sg_size);
+int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_rotate_iv(unsigned char *iv);
+void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_destruct_mount_crypt_stat(
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
+int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_write_inode_size_to_header(struct file *lower_file,
+					struct inode *lower_inode,
+					struct inode *inode);
+int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
+			    struct file *lower_file,
+			    unsigned long lower_page_index, int byte_offset,
+			    int region_bytes);
+int
+ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
+			   struct file *lower_file, int byte_offset,
+			   int region_size);
+int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
+				struct file *lower_file);
+int ecryptfs_do_readpage(struct file *file, struct page *page,
+			 pgoff_t lower_page_index);
+int ecryptfs_grab_and_map_lower_page(struct page **lower_page,
+				     char **lower_virt,
+				     struct inode *lower_inode,
+				     unsigned long lower_page_index);
+int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
+					      struct inode *lower_inode,
+					      struct writeback_control *wbc);
+int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx);
+int ecryptfs_decrypt_page(struct file *file, struct page *page);
+int ecryptfs_write_headers(struct dentry *ecryptfs_dentry,
+			   struct file *lower_file);
+int ecryptfs_write_headers_virt(char *page_virt,
+				struct ecryptfs_crypt_stat *crypt_stat,
+				struct dentry *ecryptfs_dentry);
+int ecryptfs_read_headers(struct dentry *ecryptfs_dentry,
+			  struct file *lower_file);
+int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+int contains_ecryptfs_marker(char *data);
+int ecryptfs_read_header_region(char *data, struct dentry *dentry,
+				struct vfsmount *mnt);
+u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code);
+void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_generate_key_packet_set(char *dest_base,
+				     struct ecryptfs_crypt_stat *crypt_stat,
+				     struct dentry *ecryptfs_dentry,
+				     size_t *len, size_t max);
+int process_request_key_err(long err_code);
+int
+ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
+			  unsigned char *src, struct dentry *ecryptfs_dentry);
+int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
+int
+ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
+			char *cipher_name, size_t key_size);
+int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
+int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
+void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
+
+#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
new file mode 100644
index 0000000..c8550c9
--- /dev/null
+++ b/fs/ecryptfs/file.c
@@ -0,0 +1,440 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2004 Erez Zadok
+ * Copyright (C) 2001-2004 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
+ *   		Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/file.h>
+#include <linux/poll.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/security.h>
+#include <linux/smp_lock.h>
+#include <linux/compat.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * ecryptfs_llseek
+ * @file: File we are seeking in
+ * @offset: The offset to seek to
+ * @origin: 2 - offset from i_size; 1 - offset from f_pos
+ *
+ * Returns the position we have seeked to, or negative on error
+ */
+static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin)
+{
+	loff_t rv;
+	loff_t new_end_pos;
+	int rc;
+	int expanding_file = 0;
+	struct inode *inode = file->f_mapping->host;
+
+	/* If our offset is past the end of our file, we're going to
+	 * need to grow it so we have a valid length of 0's */
+	new_end_pos = offset;
+	switch (origin) {
+	case 2:
+		new_end_pos += i_size_read(inode);
+		expanding_file = 1;
+		break;
+	case 1:
+		new_end_pos += file->f_pos;
+		if (new_end_pos > i_size_read(inode)) {
+			ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
+					"> i_size_read(inode)(=[0x%.16x])\n",
+					new_end_pos, i_size_read(inode));
+			expanding_file = 1;
+		}
+		break;
+	default:
+		if (new_end_pos > i_size_read(inode)) {
+			ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
+					"> i_size_read(inode)(=[0x%.16x])\n",
+					new_end_pos, i_size_read(inode));
+			expanding_file = 1;
+		}
+	}
+	ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos);
+	if (expanding_file) {
+		rc = ecryptfs_truncate(file->f_dentry, new_end_pos);
+		if (rc) {
+			rv = rc;
+			ecryptfs_printk(KERN_ERR, "Error on attempt to "
+					"truncate to (higher) offset [0x%.16x];"
+					" rc = [%d]\n", new_end_pos, rc);
+			goto out;
+		}
+	}
+	rv = generic_file_llseek(file, offset, origin);
+out:
+	return rv;
+}
+
+/**
+ * ecryptfs_read_update_atime
+ *
+ * generic_file_read updates the atime of upper layer inode.  But, it
+ * doesn't give us a chance to update the atime of the lower layer
+ * inode.  This function is a wrapper to generic_file_read.  It
+ * updates the atime of the lower level inode if generic_file_read
+ * returns without any errors. This is to be used only for file reads.
+ * The function to be used for directory reads is ecryptfs_read.
+ */
+static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
+				const struct iovec *iov,
+				unsigned long nr_segs, loff_t pos)
+{
+	int rc;
+	struct dentry *lower_dentry;
+	struct vfsmount *lower_vfsmount;
+	struct file *file = iocb->ki_filp;
+
+	rc = generic_file_aio_read(iocb, iov, nr_segs, pos);
+	/*
+	 * Even though this is a async interface, we need to wait
+	 * for IO to finish to update atime
+	 */
+	if (-EIOCBQUEUED == rc)
+		rc = wait_on_sync_kiocb(iocb);
+	if (rc >= 0) {
+		lower_dentry = ecryptfs_dentry_to_lower(file->f_dentry);
+		lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_dentry);
+		touch_atime(lower_vfsmount, lower_dentry);
+	}
+	return rc;
+}
+
+struct ecryptfs_getdents_callback {
+	void *dirent;
+	struct dentry *dentry;
+	filldir_t filldir;
+	int err;
+	int filldir_called;
+	int entries_written;
+};
+
+/* Inspired by generic filldir in fs/readir.c */
+static int
+ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset,
+		 u64 ino, unsigned int d_type)
+{
+	struct ecryptfs_crypt_stat *crypt_stat;
+	struct ecryptfs_getdents_callback *buf =
+	    (struct ecryptfs_getdents_callback *)dirent;
+	int rc;
+	int decoded_length;
+	char *decoded_name;
+
+	crypt_stat = ecryptfs_dentry_to_private(buf->dentry)->crypt_stat;
+	buf->filldir_called++;
+	decoded_length = ecryptfs_decode_filename(crypt_stat, name, namelen,
+						  &decoded_name);
+	if (decoded_length < 0) {
+		rc = decoded_length;
+		goto out;
+	}
+	rc = buf->filldir(buf->dirent, decoded_name, decoded_length, offset,
+			  ino, d_type);
+	kfree(decoded_name);
+	if (rc >= 0)
+		buf->entries_written++;
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_readdir
+ * @file: The ecryptfs file struct
+ * @dirent: Directory entry
+ * @filldir: The filldir callback function
+ */
+static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
+{
+	int rc;
+	struct file *lower_file;
+	struct inode *inode;
+	struct ecryptfs_getdents_callback buf;
+
+	lower_file = ecryptfs_file_to_lower(file);
+	lower_file->f_pos = file->f_pos;
+	inode = file->f_dentry->d_inode;
+	memset(&buf, 0, sizeof(buf));
+	buf.dirent = dirent;
+	buf.dentry = file->f_dentry;
+	buf.filldir = filldir;
+retry:
+	buf.filldir_called = 0;
+	buf.entries_written = 0;
+	buf.err = 0;
+	rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf);
+	if (buf.err)
+		rc = buf.err;
+	if (buf.filldir_called && !buf.entries_written)
+		goto retry;
+	file->f_pos = lower_file->f_pos;
+	if (rc >= 0)
+		ecryptfs_copy_attr_atime(inode, lower_file->f_dentry->d_inode);
+	return rc;
+}
+
+struct kmem_cache *ecryptfs_file_info_cache;
+
+/**
+ * ecryptfs_open
+ * @inode: inode speciying file to open
+ * @file: Structure to return filled in
+ *
+ * Opens the file specified by inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	struct ecryptfs_crypt_stat *crypt_stat = NULL;
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+	struct dentry *ecryptfs_dentry = file->f_dentry;
+	/* Private value of ecryptfs_dentry allocated in
+	 * ecryptfs_lookup() */
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+	struct inode *lower_inode = NULL;
+	struct file *lower_file = NULL;
+	struct vfsmount *lower_mnt;
+	struct ecryptfs_file_info *file_info;
+	int lower_flags;
+
+	/* Released in ecryptfs_release or end of function if failure */
+	file_info = kmem_cache_alloc(ecryptfs_file_info_cache, SLAB_KERNEL);
+	ecryptfs_set_file_private(file, file_info);
+	if (!file_info) {
+		ecryptfs_printk(KERN_ERR,
+				"Error attempting to allocate memory\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	memset(file_info, 0, sizeof(*file_info));
+	lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+	crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
+	mount_crypt_stat = &ecryptfs_superblock_to_private(
+		ecryptfs_dentry->d_sb)->mount_crypt_stat;
+	mutex_lock(&crypt_stat->cs_mutex);
+	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) {
+		ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n");
+		/* Policy code enabled in future release */
+		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED);
+		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+	}
+	mutex_unlock(&crypt_stat->cs_mutex);
+	/* This mntget & dget is undone via fput when the file is released */
+	dget(lower_dentry);
+	lower_flags = file->f_flags;
+	if ((lower_flags & O_ACCMODE) == O_WRONLY)
+		lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
+	if (file->f_flags & O_APPEND)
+		lower_flags &= ~O_APPEND;
+	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
+	mntget(lower_mnt);
+	/* Corresponding fput() in ecryptfs_release() */
+	lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags);
+	if (IS_ERR(lower_file)) {
+		rc = PTR_ERR(lower_file);
+		ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
+		goto out_puts;
+	}
+	ecryptfs_set_file_lower(file, lower_file);
+	/* Isn't this check the same as the one in lookup? */
+	lower_inode = lower_dentry->d_inode;
+	if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
+		ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
+		ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+		rc = 0;
+		goto out;
+	}
+	mutex_lock(&crypt_stat->cs_mutex);
+	if (i_size_read(lower_inode) < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
+		if (!(mount_crypt_stat->flags
+		      & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
+			rc = -EIO;
+			printk(KERN_WARNING "Attempt to read file that is "
+			       "not in a valid eCryptfs format, and plaintext "
+			       "passthrough mode is not enabled; returning "
+			       "-EIO\n");
+			mutex_unlock(&crypt_stat->cs_mutex);
+			goto out_puts;
+		}
+		crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
+		rc = 0;
+		mutex_unlock(&crypt_stat->cs_mutex);
+		goto out;
+	} else if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+					ECRYPTFS_POLICY_APPLIED)
+		   || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+					   ECRYPTFS_KEY_VALID)) {
+		rc = ecryptfs_read_headers(ecryptfs_dentry, lower_file);
+		if (rc) {
+			ecryptfs_printk(KERN_DEBUG,
+					"Valid headers not found\n");
+			if (!(mount_crypt_stat->flags
+			      & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
+				rc = -EIO;
+				printk(KERN_WARNING "Attempt to read file that "
+				       "is not in a valid eCryptfs format, "
+				       "and plaintext passthrough mode is not "
+				       "enabled; returning -EIO\n");
+				mutex_unlock(&crypt_stat->cs_mutex);
+				goto out_puts;
+			}
+			ECRYPTFS_CLEAR_FLAG(crypt_stat->flags,
+					    ECRYPTFS_ENCRYPTED);
+			rc = 0;
+			mutex_unlock(&crypt_stat->cs_mutex);
+			goto out;
+		}
+	}
+	mutex_unlock(&crypt_stat->cs_mutex);
+	ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] "
+			"size: [0x%.16x]\n", inode, inode->i_ino,
+			i_size_read(inode));
+	ecryptfs_set_file_lower(file, lower_file);
+	goto out;
+out_puts:
+	mntput(lower_mnt);
+	dput(lower_dentry);
+	kmem_cache_free(ecryptfs_file_info_cache,
+			ecryptfs_file_to_private(file));
+out:
+	return rc;
+}
+
+static int ecryptfs_flush(struct file *file, fl_owner_t td)
+{
+	int rc = 0;
+	struct file *lower_file = NULL;
+
+	lower_file = ecryptfs_file_to_lower(file);
+	if (lower_file->f_op && lower_file->f_op->flush)
+		rc = lower_file->f_op->flush(lower_file, td);
+	return rc;
+}
+
+static int ecryptfs_release(struct inode *inode, struct file *file)
+{
+	struct file *lower_file = ecryptfs_file_to_lower(file);
+	struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
+	struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
+
+	fput(lower_file);
+	inode->i_blocks = lower_inode->i_blocks;
+	kmem_cache_free(ecryptfs_file_info_cache, file_info);
+	return 0;
+}
+
+static int
+ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+	struct file *lower_file = ecryptfs_file_to_lower(file);
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	struct inode *lower_inode = lower_dentry->d_inode;
+	int rc = -EINVAL;
+
+	if (lower_inode->i_fop->fsync) {
+		mutex_lock(&lower_inode->i_mutex);
+		rc = lower_inode->i_fop->fsync(lower_file, lower_dentry,
+					       datasync);
+		mutex_unlock(&lower_inode->i_mutex);
+	}
+	return rc;
+}
+
+static int ecryptfs_fasync(int fd, struct file *file, int flag)
+{
+	int rc = 0;
+	struct file *lower_file = NULL;
+
+	lower_file = ecryptfs_file_to_lower(file);
+	if (lower_file->f_op && lower_file->f_op->fasync)
+		rc = lower_file->f_op->fasync(fd, lower_file, flag);
+	return rc;
+}
+
+static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos,
+				 size_t count, read_actor_t actor, void *target)
+{
+	struct file *lower_file = NULL;
+	int rc = -EINVAL;
+
+	lower_file = ecryptfs_file_to_lower(file);
+	if (lower_file->f_op && lower_file->f_op->sendfile)
+		rc = lower_file->f_op->sendfile(lower_file, ppos, count,
+						actor, target);
+
+	return rc;
+}
+
+static int ecryptfs_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg);
+
+const struct file_operations ecryptfs_dir_fops = {
+	.readdir = ecryptfs_readdir,
+	.ioctl = ecryptfs_ioctl,
+	.mmap = generic_file_mmap,
+	.open = ecryptfs_open,
+	.flush = ecryptfs_flush,
+	.release = ecryptfs_release,
+	.fsync = ecryptfs_fsync,
+	.fasync = ecryptfs_fasync,
+	.sendfile = ecryptfs_sendfile,
+};
+
+const struct file_operations ecryptfs_main_fops = {
+	.llseek = ecryptfs_llseek,
+	.read = do_sync_read,
+	.aio_read = ecryptfs_read_update_atime,
+	.write = do_sync_write,
+	.aio_write = generic_file_aio_write,
+	.readdir = ecryptfs_readdir,
+	.ioctl = ecryptfs_ioctl,
+	.mmap = generic_file_mmap,
+	.open = ecryptfs_open,
+	.flush = ecryptfs_flush,
+	.release = ecryptfs_release,
+	.fsync = ecryptfs_fsync,
+	.fasync = ecryptfs_fasync,
+	.sendfile = ecryptfs_sendfile,
+};
+
+static int
+ecryptfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	       unsigned long arg)
+{
+	int rc = 0;
+	struct file *lower_file = NULL;
+
+	if (ecryptfs_file_to_private(file))
+		lower_file = ecryptfs_file_to_lower(file);
+	if (lower_file && lower_file->f_op && lower_file->f_op->ioctl)
+		rc = lower_file->f_op->ioctl(ecryptfs_inode_to_lower(inode),
+					     lower_file, cmd, arg);
+	else
+		rc = -ENOTTY;
+	return rc;
+}
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
new file mode 100644
index 0000000..efdd2b7
--- /dev/null
+++ b/fs/ecryptfs/inode.c
@@ -0,0 +1,1079 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2004 Erez Zadok
+ * Copyright (C) 2001-2004 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *              Michael C. Thompsion <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/file.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/crypto.h>
+#include "ecryptfs_kernel.h"
+
+static struct dentry *lock_parent(struct dentry *dentry)
+{
+	struct dentry *dir;
+
+	dir = dget(dentry->d_parent);
+	mutex_lock(&(dir->d_inode->i_mutex));
+	return dir;
+}
+
+static void unlock_parent(struct dentry *dentry)
+{
+	mutex_unlock(&(dentry->d_parent->d_inode->i_mutex));
+	dput(dentry->d_parent);
+}
+
+static void unlock_dir(struct dentry *dir)
+{
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(dir);
+}
+
+void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src)
+{
+	i_size_write(dst, i_size_read((struct inode *)src));
+	dst->i_blocks = src->i_blocks;
+}
+
+void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src)
+{
+	dest->i_atime = src->i_atime;
+}
+
+static void ecryptfs_copy_attr_times(struct inode *dest,
+				     const struct inode *src)
+{
+	dest->i_atime = src->i_atime;
+	dest->i_mtime = src->i_mtime;
+	dest->i_ctime = src->i_ctime;
+}
+
+static void ecryptfs_copy_attr_timesizes(struct inode *dest,
+					 const struct inode *src)
+{
+	dest->i_atime = src->i_atime;
+	dest->i_mtime = src->i_mtime;
+	dest->i_ctime = src->i_ctime;
+	ecryptfs_copy_inode_size(dest, src);
+}
+
+void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src)
+{
+	dest->i_mode = src->i_mode;
+	dest->i_nlink = src->i_nlink;
+	dest->i_uid = src->i_uid;
+	dest->i_gid = src->i_gid;
+	dest->i_rdev = src->i_rdev;
+	dest->i_atime = src->i_atime;
+	dest->i_mtime = src->i_mtime;
+	dest->i_ctime = src->i_ctime;
+	dest->i_blkbits = src->i_blkbits;
+	dest->i_flags = src->i_flags;
+}
+
+/**
+ * ecryptfs_create_underlying_file
+ * @lower_dir_inode: inode of the parent in the lower fs of the new file
+ * @lower_dentry: New file's dentry in the lower fs
+ * @ecryptfs_dentry: New file's dentry in ecryptfs
+ * @mode: The mode of the new file
+ * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
+ *
+ * Creates the file in the lower file system.
+ *
+ * Returns zero on success; non-zero on error condition
+ */
+static int
+ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
+				struct dentry *dentry, int mode,
+				struct nameidata *nd)
+{
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+	struct dentry *dentry_save;
+	struct vfsmount *vfsmount_save;
+	int rc;
+
+	dentry_save = nd->dentry;
+	vfsmount_save = nd->mnt;
+	nd->dentry = lower_dentry;
+	nd->mnt = lower_mnt;
+	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
+	nd->dentry = dentry_save;
+	nd->mnt = vfsmount_save;
+	return rc;
+}
+
+/**
+ * ecryptfs_do_create
+ * @directory_inode: inode of the new file's dentry's parent in ecryptfs
+ * @ecryptfs_dentry: New file's dentry in ecryptfs
+ * @mode: The mode of the new file
+ * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
+ *
+ * Creates the underlying file and the eCryptfs inode which will link to
+ * it. It will also update the eCryptfs directory inode to mimic the
+ * stat of the lower directory inode.
+ *
+ * Returns zero on success; non-zero on error condition
+ */
+static int
+ecryptfs_do_create(struct inode *directory_inode,
+		   struct dentry *ecryptfs_dentry, int mode,
+		   struct nameidata *nd)
+{
+	int rc;
+	struct dentry *lower_dentry;
+	struct dentry *lower_dir_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+	lower_dir_dentry = lock_parent(lower_dentry);
+	if (unlikely(IS_ERR(lower_dir_dentry))) {
+		ecryptfs_printk(KERN_ERR, "Error locking directory of "
+				"dentry\n");
+		rc = PTR_ERR(lower_dir_dentry);
+		goto out;
+	}
+	rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
+					     ecryptfs_dentry, mode, nd);
+	if (unlikely(rc)) {
+		ecryptfs_printk(KERN_ERR,
+				"Failure to create underlying file\n");
+		goto out_lock;
+	}
+	rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
+				directory_inode->i_sb, 0);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n");
+		goto out_lock;
+	}
+	ecryptfs_copy_attr_timesizes(directory_inode,
+				     lower_dir_dentry->d_inode);
+out_lock:
+	unlock_dir(lower_dir_dentry);
+out:
+	return rc;
+}
+
+/**
+ * grow_file
+ * @ecryptfs_dentry: the ecryptfs dentry
+ * @lower_file: The lower file
+ * @inode: The ecryptfs inode
+ * @lower_inode: The lower inode
+ *
+ * This is the code which will grow the file to its correct size.
+ */
+static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file,
+		     struct inode *inode, struct inode *lower_inode)
+{
+	int rc = 0;
+	struct file fake_file;
+	struct ecryptfs_file_info tmp_file_info;
+
+	memset(&fake_file, 0, sizeof(fake_file));
+	fake_file.f_dentry = ecryptfs_dentry;
+	memset(&tmp_file_info, 0, sizeof(tmp_file_info));
+	ecryptfs_set_file_private(&fake_file, &tmp_file_info);
+	ecryptfs_set_file_lower(&fake_file, lower_file);
+	rc = ecryptfs_fill_zeros(&fake_file, 1);
+	if (rc) {
+		ECRYPTFS_SET_FLAG(
+			ecryptfs_inode_to_private(inode)->crypt_stat.flags,
+			ECRYPTFS_SECURITY_WARNING);
+		ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros "
+				"in file; rc = [%d]\n", rc);
+		goto out;
+	}
+	i_size_write(inode, 0);
+	ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode);
+	ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags,
+			  ECRYPTFS_NEW_FILE);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_initialize_file
+ *
+ * Cause the file to be changed from a basic empty file to an ecryptfs
+ * file with a header and first data page.
+ *
+ * Returns zero on success
+ */
+static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
+{
+	int rc = 0;
+	int lower_flags;
+	struct ecryptfs_crypt_stat *crypt_stat;
+	struct dentry *lower_dentry;
+	struct dentry *tlower_dentry = NULL;
+	struct file *lower_file;
+	struct inode *inode, *lower_inode;
+	struct vfsmount *lower_mnt;
+
+	lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+	ecryptfs_printk(KERN_DEBUG, "lower_dentry->d_name.name = [%s]\n",
+			lower_dentry->d_name.name);
+	inode = ecryptfs_dentry->d_inode;
+	crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
+	tlower_dentry = dget(lower_dentry);
+	if (!tlower_dentry) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n");
+		goto out;
+	}
+	lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
+#if BITS_PER_LONG != 32
+	lower_flags |= O_LARGEFILE;
+#endif
+	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
+	mntget(lower_mnt);
+	/* Corresponding fput() at end of this function */
+	lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags);
+	if (IS_ERR(lower_file)) {
+		rc = PTR_ERR(lower_file);
+		ecryptfs_printk(KERN_ERR,
+				"Error opening dentry; rc = [%i]\n", rc);
+		goto out;
+	}
+	/* fput(lower_file) should handle the puts if we do this */
+	lower_file->f_dentry = tlower_dentry;
+	lower_file->f_vfsmnt = lower_mnt;
+	lower_inode = tlower_dentry->d_inode;
+	if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
+		ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
+		ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+		goto out_fput;
+	}
+	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE);
+	ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
+	rc = ecryptfs_new_file_context(ecryptfs_dentry);
+	if (rc) {
+		ecryptfs_printk(KERN_DEBUG, "Error creating new file "
+				"context\n");
+		goto out_fput;
+	}
+	rc = ecryptfs_write_headers(ecryptfs_dentry, lower_file);
+	if (rc) {
+		ecryptfs_printk(KERN_DEBUG, "Error writing headers\n");
+		goto out_fput;
+	}
+	rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
+out_fput:
+	fput(lower_file);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_create
+ * @dir: The inode of the directory in which to create the file.
+ * @dentry: The eCryptfs dentry
+ * @mode: The mode of the new file.
+ * @nd: nameidata
+ *
+ * Creates a new file.
+ *
+ * Returns zero on success; non-zero on error condition
+ */
+static int
+ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
+		int mode, struct nameidata *nd)
+{
+	int rc;
+
+	rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd);
+	if (unlikely(rc)) {
+		ecryptfs_printk(KERN_WARNING, "Failed to create file in"
+				"lower filesystem\n");
+		goto out;
+	}
+	/* At this point, a file exists on "disk"; we need to make sure
+	 * that this on disk file is prepared to be an ecryptfs file */
+	rc = ecryptfs_initialize_file(ecryptfs_dentry);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_lookup
+ * @dir: inode
+ * @dentry: The dentry
+ * @nd: nameidata, may be NULL
+ *
+ * Find a file on disk. If the file does not exist, then we'll add it to the
+ * dentry cache and continue on to read it from the disk.
+ */
+static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
+				      struct nameidata *nd)
+{
+	int rc = 0;
+	struct dentry *lower_dir_dentry;
+	struct dentry *lower_dentry;
+	struct vfsmount *lower_mnt;
+	struct dentry *tlower_dentry = NULL;
+	char *encoded_name;
+	unsigned int encoded_namelen;
+	struct ecryptfs_crypt_stat *crypt_stat = NULL;
+	char *page_virt = NULL;
+	struct inode *lower_inode;
+	u64 file_size;
+
+	lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
+	dentry->d_op = &ecryptfs_dops;
+	if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, "."))
+	    || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, "..")))
+		goto out_drop;
+	encoded_namelen = ecryptfs_encode_filename(crypt_stat,
+						   dentry->d_name.name,
+						   dentry->d_name.len,
+						   &encoded_name);
+	if (encoded_namelen < 0) {
+		rc = encoded_namelen;
+		goto out_drop;
+	}
+	ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen "
+			"= [%d]\n", encoded_name, encoded_namelen);
+	lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry,
+				      encoded_namelen - 1);
+	kfree(encoded_name);
+	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
+	if (IS_ERR(lower_dentry)) {
+		ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n");
+		rc = PTR_ERR(lower_dentry);
+		goto out_drop;
+	}
+	ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->"
+       		"d_name.name = [%s]\n", lower_dentry,
+		lower_dentry->d_name.name);
+	lower_inode = lower_dentry->d_inode;
+	ecryptfs_copy_attr_atime(dir, lower_dir_dentry->d_inode);
+	BUG_ON(!atomic_read(&lower_dentry->d_count));
+	ecryptfs_set_dentry_private(dentry,
+				    kmem_cache_alloc(ecryptfs_dentry_info_cache,
+						     SLAB_KERNEL));
+	if (!ecryptfs_dentry_to_private(dentry)) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting "
+				"to allocate ecryptfs_dentry_info struct\n");
+		goto out_dput;
+	}
+	ecryptfs_set_dentry_lower(dentry, lower_dentry);
+	ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt);
+	if (!lower_dentry->d_inode) {
+		/* We want to add because we couldn't find in lower */
+		d_add(dentry, NULL);
+		goto out;
+	}
+	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 1);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error interposing\n");
+		goto out_dput;
+	}
+	if (S_ISDIR(lower_inode->i_mode)) {
+		ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n");
+		goto out;
+	}
+	if (S_ISLNK(lower_inode->i_mode)) {
+		ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n");
+		goto out;
+	}
+	if (!nd) {
+		ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave"
+				"as we *think* we are about to unlink\n");
+		goto out;
+	}
+	tlower_dentry = dget(lower_dentry);
+	if (!tlower_dentry || IS_ERR(tlower_dentry)) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n");
+		goto out_dput;
+	}
+	/* Released in this function */
+	page_virt =
+	    (char *)kmem_cache_alloc(ecryptfs_header_cache_2,
+				     SLAB_USER);
+	if (!page_virt) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR,
+				"Cannot ecryptfs_kmalloc a page\n");
+		goto out_dput;
+	}
+	memset(page_virt, 0, PAGE_CACHE_SIZE);
+	rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt);
+	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
+	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
+		ecryptfs_set_default_sizes(crypt_stat);
+	if (rc) {
+		rc = 0;
+		ecryptfs_printk(KERN_WARNING, "Error reading header region;"
+				" assuming unencrypted\n");
+	} else {
+		if (!contains_ecryptfs_marker(page_virt
+					      + ECRYPTFS_FILE_SIZE_BYTES)) {
+			kmem_cache_free(ecryptfs_header_cache_2, page_virt);
+			goto out;
+		}
+		memcpy(&file_size, page_virt, sizeof(file_size));
+		file_size = be64_to_cpu(file_size);
+		i_size_write(dentry->d_inode, (loff_t)file_size);
+	}
+	kmem_cache_free(ecryptfs_header_cache_2, page_virt);
+	goto out;
+
+out_dput:
+	dput(lower_dentry);
+	if (tlower_dentry)
+		dput(tlower_dentry);
+out_drop:
+	d_drop(dentry);
+out:
+	return ERR_PTR(rc);
+}
+
+static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
+			 struct dentry *new_dentry)
+{
+	struct dentry *lower_old_dentry;
+	struct dentry *lower_new_dentry;
+	struct dentry *lower_dir_dentry;
+	u64 file_size_save;
+	int rc;
+
+	file_size_save = i_size_read(old_dentry->d_inode);
+	lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
+	lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
+	dget(lower_old_dentry);
+	dget(lower_new_dentry);
+	lower_dir_dentry = lock_parent(lower_new_dentry);
+	rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
+		      lower_new_dentry);
+	if (rc || !lower_new_dentry->d_inode)
+		goto out_lock;
+	rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
+	if (rc)
+		goto out_lock;
+	ecryptfs_copy_attr_timesizes(dir, lower_new_dentry->d_inode);
+	old_dentry->d_inode->i_nlink =
+		ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
+	i_size_write(new_dentry->d_inode, file_size_save);
+out_lock:
+	unlock_dir(lower_dir_dentry);
+	dput(lower_new_dentry);
+	dput(lower_old_dentry);
+	if (!new_dentry->d_inode)
+		d_drop(new_dentry);
+	return rc;
+}
+
+static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	int rc = 0;
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
+
+	lock_parent(lower_dentry);
+	rc = vfs_unlink(lower_dir_inode, lower_dentry);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error in vfs_unlink\n");
+		goto out_unlock;
+	}
+	ecryptfs_copy_attr_times(dir, lower_dir_inode);
+	dentry->d_inode->i_nlink =
+		ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink;
+	dentry->d_inode->i_ctime = dir->i_ctime;
+out_unlock:
+	unlock_parent(lower_dentry);
+	return rc;
+}
+
+static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
+			    const char *symname)
+{
+	int rc;
+	struct dentry *lower_dentry;
+	struct dentry *lower_dir_dentry;
+	umode_t mode;
+	char *encoded_symname;
+	unsigned int encoded_symlen;
+	struct ecryptfs_crypt_stat *crypt_stat = NULL;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	dget(lower_dentry);
+	lower_dir_dentry = lock_parent(lower_dentry);
+	mode = S_IALLUGO;
+	encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
+						  strlen(symname),
+						  &encoded_symname);
+	if (encoded_symlen < 0) {
+		rc = encoded_symlen;
+		goto out_lock;
+	}
+	rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
+			 encoded_symname, mode);
+	kfree(encoded_symname);
+	if (rc || !lower_dentry->d_inode)
+		goto out_lock;
+	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+	if (rc)
+		goto out_lock;
+	ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode);
+out_lock:
+	unlock_dir(lower_dir_dentry);
+	dput(lower_dentry);
+	if (!dentry->d_inode)
+		d_drop(dentry);
+	return rc;
+}
+
+static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	int rc;
+	struct dentry *lower_dentry;
+	struct dentry *lower_dir_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	lower_dir_dentry = lock_parent(lower_dentry);
+	rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
+	if (rc || !lower_dentry->d_inode)
+		goto out;
+	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+	if (rc)
+		goto out;
+	ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode);
+	dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
+out:
+	unlock_dir(lower_dir_dentry);
+	if (!dentry->d_inode)
+		d_drop(dentry);
+	return rc;
+}
+
+static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	int rc = 0;
+	struct dentry *tdentry = NULL;
+	struct dentry *lower_dentry;
+	struct dentry *tlower_dentry = NULL;
+	struct dentry *lower_dir_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	if (!(tdentry = dget(dentry))) {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n",
+				dentry);
+		goto out;
+	}
+	lower_dir_dentry = lock_parent(lower_dentry);
+	if (!(tlower_dentry = dget(lower_dentry))) {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry "
+				"[%p]\n", lower_dentry);
+		goto out;
+	}
+	rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
+	if (!rc) {
+		d_delete(tlower_dentry);
+		tlower_dentry = NULL;
+	}
+	ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode);
+	dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
+	unlock_dir(lower_dir_dentry);
+	if (!rc)
+		d_drop(dentry);
+out:
+	if (tdentry)
+		dput(tdentry);
+	if (tlower_dentry)
+		dput(tlower_dentry);
+	return rc;
+}
+
+static int
+ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+{
+	int rc;
+	struct dentry *lower_dentry;
+	struct dentry *lower_dir_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	lower_dir_dentry = lock_parent(lower_dentry);
+	rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
+	if (rc || !lower_dentry->d_inode)
+		goto out;
+	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+	if (rc)
+		goto out;
+	ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode);
+out:
+	unlock_dir(lower_dir_dentry);
+	if (!dentry->d_inode)
+		d_drop(dentry);
+	return rc;
+}
+
+static int
+ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+		struct inode *new_dir, struct dentry *new_dentry)
+{
+	int rc;
+	struct dentry *lower_old_dentry;
+	struct dentry *lower_new_dentry;
+	struct dentry *lower_old_dir_dentry;
+	struct dentry *lower_new_dir_dentry;
+
+	lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
+	lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
+	dget(lower_old_dentry);
+	dget(lower_new_dentry);
+	lower_old_dir_dentry = dget_parent(lower_old_dentry);
+	lower_new_dir_dentry = dget_parent(lower_new_dentry);
+	lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+	rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
+			lower_new_dir_dentry->d_inode, lower_new_dentry);
+	if (rc)
+		goto out_lock;
+	ecryptfs_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
+	if (new_dir != old_dir)
+		ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
+out_lock:
+	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+	dput(lower_new_dentry);
+	dput(lower_old_dentry);
+	return rc;
+}
+
+static int
+ecryptfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz)
+{
+	int rc;
+	struct dentry *lower_dentry;
+	char *decoded_name;
+	char *lower_buf;
+	mm_segment_t old_fs;
+	struct ecryptfs_crypt_stat *crypt_stat;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	if (!lower_dentry->d_inode->i_op ||
+	    !lower_dentry->d_inode->i_op->readlink) {
+		rc = -EINVAL;
+		goto out;
+	}
+	/* Released in this function */
+	lower_buf = kmalloc(bufsiz, GFP_KERNEL);
+	if (lower_buf == NULL) {
+		ecryptfs_printk(KERN_ERR, "Out of memory\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	old_fs = get_fs();
+	set_fs(get_ds());
+	ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ "
+			"lower_dentry->d_name.name = [%s]\n",
+			lower_dentry->d_name.name);
+	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
+						   (char __user *)lower_buf,
+						   bufsiz);
+	set_fs(old_fs);
+	if (rc >= 0) {
+		crypt_stat = NULL;
+		rc = ecryptfs_decode_filename(crypt_stat, lower_buf, rc,
+					      &decoded_name);
+		if (rc == -ENOMEM)
+			goto out_free_lower_buf;
+		if (rc > 0) {
+			ecryptfs_printk(KERN_DEBUG, "Copying [%d] bytes "
+					"to userspace: [%*s]\n", rc,
+					decoded_name);
+			if (copy_to_user(buf, decoded_name, rc))
+				rc = -EFAULT;
+		}
+		kfree(decoded_name);
+		ecryptfs_copy_attr_atime(dentry->d_inode,
+					 lower_dentry->d_inode);
+	}
+out_free_lower_buf:
+	kfree(lower_buf);
+out:
+	return rc;
+}
+
+static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	char *buf;
+	int len = PAGE_SIZE, rc;
+	mm_segment_t old_fs;
+
+	/* Released in ecryptfs_put_link(); only release here on error */
+	buf = kmalloc(len, GFP_KERNEL);
+	if (!buf) {
+		rc = -ENOMEM;
+		goto out;
+	}
+	old_fs = get_fs();
+	set_fs(get_ds());
+	ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ "
+			"dentry->d_name.name = [%s]\n", dentry->d_name.name);
+	rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
+	buf[rc] = '\0';
+	set_fs(old_fs);
+	if (rc < 0)
+		goto out_free;
+	rc = 0;
+	nd_set_link(nd, buf);
+	goto out;
+out_free:
+	kfree(buf);
+out:
+	return ERR_PTR(rc);
+}
+
+static void
+ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
+{
+	/* Free the char* */
+	kfree(nd_get_link(nd));
+}
+
+/**
+ * upper_size_to_lower_size
+ * @crypt_stat: Crypt_stat associated with file
+ * @upper_size: Size of the upper file
+ *
+ * Calculate the requried size of the lower file based on the
+ * specified size of the upper file. This calculation is based on the
+ * number of headers in the underlying file and the extent size.
+ *
+ * Returns Calculated size of the lower file.
+ */
+static loff_t
+upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
+			 loff_t upper_size)
+{
+	loff_t lower_size;
+
+	lower_size = ( crypt_stat->header_extent_size
+		       * crypt_stat->num_header_extents_at_front );
+	if (upper_size != 0) {
+		loff_t num_extents;
+
+		num_extents = upper_size >> crypt_stat->extent_shift;
+		if (upper_size & ~crypt_stat->extent_mask)
+			num_extents++;
+		lower_size += (num_extents * crypt_stat->extent_size);
+	}
+	return lower_size;
+}
+
+/**
+ * ecryptfs_truncate
+ * @dentry: The ecryptfs layer dentry
+ * @new_length: The length to expand the file to
+ *
+ * Function to handle truncations modifying the size of the file. Note
+ * that the file sizes are interpolated. When expanding, we are simply
+ * writing strings of 0's out. When truncating, we need to modify the
+ * underlying file size according to the page index interpolations.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+{
+	int rc = 0;
+	struct inode *inode = dentry->d_inode;
+	struct dentry *lower_dentry;
+	struct vfsmount *lower_mnt;
+	struct file fake_ecryptfs_file, *lower_file = NULL;
+	struct ecryptfs_crypt_stat *crypt_stat;
+	loff_t i_size = i_size_read(inode);
+	loff_t lower_size_before_truncate;
+	loff_t lower_size_after_truncate;
+
+	if (unlikely((new_length == i_size)))
+		goto out;
+	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
+	/* Set up a fake ecryptfs file, this is used to interface with
+	 * the file in the underlying filesystem so that the
+	 * truncation has an effect there as well. */
+	memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file));
+	fake_ecryptfs_file.f_dentry = dentry;
+	/* Released at out_free: label */
+	ecryptfs_set_file_private(&fake_ecryptfs_file,
+				  kmem_cache_alloc(ecryptfs_file_info_cache,
+						   SLAB_KERNEL));
+	if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) {
+		rc = -ENOMEM;
+		goto out;
+	}
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	/* This dget & mntget is released through fput at out_fput: */
+	dget(lower_dentry);
+	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+	mntget(lower_mnt);
+	lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR);
+	if (unlikely(IS_ERR(lower_file))) {
+		rc = PTR_ERR(lower_file);
+		goto out_free;
+	}
+	ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
+	/* Switch on growing or shrinking file */
+	if (new_length > i_size) {
+		rc = ecryptfs_fill_zeros(&fake_ecryptfs_file, new_length);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR,
+					"Problem with fill_zeros\n");
+			goto out_fput;
+		}
+		i_size_write(inode, new_length);
+		rc = ecryptfs_write_inode_size_to_header(lower_file,
+							 lower_dentry->d_inode,
+							 inode);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR,
+					"Problem with ecryptfs_write"
+					"_inode_size\n");
+			goto out_fput;
+		}
+	} else { /* new_length < i_size_read(inode) */
+		vmtruncate(inode, new_length);
+		ecryptfs_write_inode_size_to_header(lower_file,
+						    lower_dentry->d_inode,
+						    inode);
+		/* We are reducing the size of the ecryptfs file, and need to
+		 * know if we need to reduce the size of the lower file. */
+		lower_size_before_truncate =
+		    upper_size_to_lower_size(crypt_stat, i_size);
+		lower_size_after_truncate =
+		    upper_size_to_lower_size(crypt_stat, new_length);
+		if (lower_size_after_truncate < lower_size_before_truncate)
+			vmtruncate(lower_dentry->d_inode,
+				   lower_size_after_truncate);
+	}
+	/* Update the access times */
+	lower_dentry->d_inode->i_mtime = lower_dentry->d_inode->i_ctime
+		= CURRENT_TIME;
+	mark_inode_dirty_sync(inode);
+out_fput:
+	fput(lower_file);
+out_free:
+	if (ecryptfs_file_to_private(&fake_ecryptfs_file))
+		kmem_cache_free(ecryptfs_file_info_cache,
+				ecryptfs_file_to_private(&fake_ecryptfs_file));
+out:
+	return rc;
+}
+
+static int
+ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+	int rc;
+
+        if (nd) {
+		struct vfsmount *vfsmnt_save = nd->mnt;
+		struct dentry *dentry_save = nd->dentry;
+
+		nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry);
+		nd->dentry = ecryptfs_dentry_to_lower(nd->dentry);
+		rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
+		nd->mnt = vfsmnt_save;
+		nd->dentry = dentry_save;
+        } else
+		rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
+        return rc;
+}
+
+/**
+ * ecryptfs_setattr
+ * @dentry: dentry handle to the inode to modify
+ * @ia: Structure with flags of what to change and values
+ *
+ * Updates the metadata of an inode. If the update is to the size
+ * i.e. truncation, then ecryptfs_truncate will handle the size modification
+ * of both the ecryptfs inode and the lower inode.
+ *
+ * All other metadata changes will be passed right to the lower filesystem,
+ * and we will just update our inode to look like the lower.
+ */
+static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
+{
+	int rc = 0;
+	struct dentry *lower_dentry;
+	struct inode *inode;
+	struct inode *lower_inode;
+	struct ecryptfs_crypt_stat *crypt_stat;
+
+	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	inode = dentry->d_inode;
+	lower_inode = ecryptfs_inode_to_lower(inode);
+	if (ia->ia_valid & ATTR_SIZE) {
+		ecryptfs_printk(KERN_DEBUG,
+				"ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n",
+				ia->ia_valid, ATTR_SIZE);
+		rc = ecryptfs_truncate(dentry, ia->ia_size);
+		/* ecryptfs_truncate handles resizing of the lower file */
+		ia->ia_valid &= ~ATTR_SIZE;
+		ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [%x]\n",
+				ia->ia_valid);
+		if (rc < 0)
+			goto out;
+	}
+	rc = notify_change(lower_dentry, ia);
+out:
+	ecryptfs_copy_attr_all(inode, lower_inode);
+	return rc;
+}
+
+static int
+ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+		  size_t size, int flags)
+{
+	int rc = 0;
+	struct dentry *lower_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	if (!lower_dentry->d_inode->i_op->setxattr) {
+		rc = -ENOSYS;
+		goto out;
+	}
+	mutex_lock(&lower_dentry->d_inode->i_mutex);
+	rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, name, value,
+						   size, flags);
+	mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+	return rc;
+}
+
+static ssize_t
+ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
+		  size_t size)
+{
+	int rc = 0;
+	struct dentry *lower_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	if (!lower_dentry->d_inode->i_op->getxattr) {
+		rc = -ENOSYS;
+		goto out;
+	}
+	mutex_lock(&lower_dentry->d_inode->i_mutex);
+	rc = lower_dentry->d_inode->i_op->getxattr(lower_dentry, name, value,
+						   size);
+	mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+	return rc;
+}
+
+static ssize_t
+ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
+{
+	int rc = 0;
+	struct dentry *lower_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	if (!lower_dentry->d_inode->i_op->listxattr) {
+		rc = -ENOSYS;
+		goto out;
+	}
+	mutex_lock(&lower_dentry->d_inode->i_mutex);
+	rc = lower_dentry->d_inode->i_op->listxattr(lower_dentry, list, size);
+	mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+	return rc;
+}
+
+static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
+{
+	int rc = 0;
+	struct dentry *lower_dentry;
+
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	if (!lower_dentry->d_inode->i_op->removexattr) {
+		rc = -ENOSYS;
+		goto out;
+	}
+	mutex_lock(&lower_dentry->d_inode->i_mutex);
+	rc = lower_dentry->d_inode->i_op->removexattr(lower_dentry, name);
+	mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+	return rc;
+}
+
+int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode)
+{
+	if ((ecryptfs_inode_to_lower(inode)
+	     == (struct inode *)candidate_lower_inode))
+		return 1;
+	else
+		return 0;
+}
+
+int ecryptfs_inode_set(struct inode *inode, void *lower_inode)
+{
+	ecryptfs_init_inode(inode, (struct inode *)lower_inode);
+	return 0;
+}
+
+struct inode_operations ecryptfs_symlink_iops = {
+	.readlink = ecryptfs_readlink,
+	.follow_link = ecryptfs_follow_link,
+	.put_link = ecryptfs_put_link,
+	.permission = ecryptfs_permission,
+	.setattr = ecryptfs_setattr,
+	.setxattr = ecryptfs_setxattr,
+	.getxattr = ecryptfs_getxattr,
+	.listxattr = ecryptfs_listxattr,
+	.removexattr = ecryptfs_removexattr
+};
+
+struct inode_operations ecryptfs_dir_iops = {
+	.create = ecryptfs_create,
+	.lookup = ecryptfs_lookup,
+	.link = ecryptfs_link,
+	.unlink = ecryptfs_unlink,
+	.symlink = ecryptfs_symlink,
+	.mkdir = ecryptfs_mkdir,
+	.rmdir = ecryptfs_rmdir,
+	.mknod = ecryptfs_mknod,
+	.rename = ecryptfs_rename,
+	.permission = ecryptfs_permission,
+	.setattr = ecryptfs_setattr,
+	.setxattr = ecryptfs_setxattr,
+	.getxattr = ecryptfs_getxattr,
+	.listxattr = ecryptfs_listxattr,
+	.removexattr = ecryptfs_removexattr
+};
+
+struct inode_operations ecryptfs_main_iops = {
+	.permission = ecryptfs_permission,
+	.setattr = ecryptfs_setattr,
+	.setxattr = ecryptfs_setxattr,
+	.getxattr = ecryptfs_getxattr,
+	.listxattr = ecryptfs_listxattr,
+	.removexattr = ecryptfs_removexattr
+};
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
new file mode 100644
index 0000000..ba45478
--- /dev/null
+++ b/fs/ecryptfs/keystore.c
@@ -0,0 +1,1061 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * In-kernel key management code.  Includes functions to parse and
+ * write authentication token-related packets with the underlying
+ * file.
+ *
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
+ *              Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/string.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/pagemap.h>
+#include <linux/key.h>
+#include <linux/random.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * request_key returned an error instead of a valid key address;
+ * determine the type of error, make appropriate log entries, and
+ * return an error code.
+ */
+int process_request_key_err(long err_code)
+{
+	int rc = 0;
+
+	switch (err_code) {
+	case ENOKEY:
+		ecryptfs_printk(KERN_WARNING, "No key\n");
+		rc = -ENOENT;
+		break;
+	case EKEYEXPIRED:
+		ecryptfs_printk(KERN_WARNING, "Key expired\n");
+		rc = -ETIME;
+		break;
+	case EKEYREVOKED:
+		ecryptfs_printk(KERN_WARNING, "Key revoked\n");
+		rc = -EINVAL;
+		break;
+	default:
+		ecryptfs_printk(KERN_WARNING, "Unknown error code: "
+				"[0x%.16x]\n", err_code);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static void wipe_auth_tok_list(struct list_head *auth_tok_list_head)
+{
+	struct list_head *walker;
+	struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
+
+	walker = auth_tok_list_head->next;
+	while (walker != auth_tok_list_head) {
+		auth_tok_list_item =
+		    list_entry(walker, struct ecryptfs_auth_tok_list_item,
+			       list);
+		walker = auth_tok_list_item->list.next;
+		memset(auth_tok_list_item, 0,
+		       sizeof(struct ecryptfs_auth_tok_list_item));
+		kmem_cache_free(ecryptfs_auth_tok_list_item_cache,
+				auth_tok_list_item);
+	}
+}
+
+struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
+
+/**
+ * parse_packet_length
+ * @data: Pointer to memory containing length at offset
+ * @size: This function writes the decoded size to this memory
+ *        address; zero on error
+ * @length_size: The number of bytes occupied by the encoded length
+ *
+ * Returns Zero on success
+ */
+static int parse_packet_length(unsigned char *data, size_t *size,
+			       size_t *length_size)
+{
+	int rc = 0;
+
+	(*length_size) = 0;
+	(*size) = 0;
+	if (data[0] < 192) {
+		/* One-byte length */
+		(*size) = data[0];
+		(*length_size) = 1;
+	} else if (data[0] < 224) {
+		/* Two-byte length */
+		(*size) = ((data[0] - 192) * 256);
+		(*size) += (data[1] + 192);
+		(*length_size) = 2;
+	} else if (data[0] == 255) {
+		/* Five-byte length; we're not supposed to see this */
+		ecryptfs_printk(KERN_ERR, "Five-byte packet length not "
+				"supported\n");
+		rc = -EINVAL;
+		goto out;
+	} else {
+		ecryptfs_printk(KERN_ERR, "Error parsing packet length\n");
+		rc = -EINVAL;
+		goto out;
+	}
+out:
+	return rc;
+}
+
+/**
+ * write_packet_length
+ * @dest: The byte array target into which to write the
+ *       length. Must have at least 5 bytes allocated.
+ * @size: The length to write.
+ * @packet_size_length: The number of bytes used to encode the
+ *                      packet length is written to this address.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int write_packet_length(char *dest, size_t size,
+			       size_t *packet_size_length)
+{
+	int rc = 0;
+
+	if (size < 192) {
+		dest[0] = size;
+		(*packet_size_length) = 1;
+	} else if (size < 65536) {
+		dest[0] = (((size - 192) / 256) + 192);
+		dest[1] = ((size - 192) % 256);
+		(*packet_size_length) = 2;
+	} else {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_WARNING,
+				"Unsupported packet size: [%d]\n", size);
+	}
+	return rc;
+}
+
+/**
+ * parse_tag_3_packet
+ * @crypt_stat: The cryptographic context to modify based on packet
+ *              contents.
+ * @data: The raw bytes of the packet.
+ * @auth_tok_list: eCryptfs parses packets into authentication tokens;
+ *                 a new authentication token will be placed at the end
+ *                 of this list for this packet.
+ * @new_auth_tok: Pointer to a pointer to memory that this function
+ *                allocates; sets the memory address of the pointer to
+ *                NULL on error. This object is added to the
+ *                auth_tok_list.
+ * @packet_size: This function writes the size of the parsed packet
+ *               into this memory location; zero on error.
+ * @max_packet_size: maximum number of bytes to parse
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
+		   unsigned char *data, struct list_head *auth_tok_list,
+		   struct ecryptfs_auth_tok **new_auth_tok,
+		   size_t *packet_size, size_t max_packet_size)
+{
+	int rc = 0;
+	size_t body_size;
+	struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
+	size_t length_size;
+
+	(*packet_size) = 0;
+	(*new_auth_tok) = NULL;
+
+	/* we check that:
+	 *   one byte for the Tag 3 ID flag
+	 *   two bytes for the body size
+	 * do not exceed the maximum_packet_size
+	 */
+	if (unlikely((*packet_size) + 3 > max_packet_size)) {
+		ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* check for Tag 3 identifyer - one byte */
+	if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) {
+		ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n",
+				ECRYPTFS_TAG_3_PACKET_TYPE);
+		rc = -EINVAL;
+		goto out;
+	}
+	/* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or
+	 * at end of function upon failure */
+	auth_tok_list_item =
+	    kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, SLAB_KERNEL);
+	if (!auth_tok_list_item) {
+		ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	memset(auth_tok_list_item, 0,
+	       sizeof(struct ecryptfs_auth_tok_list_item));
+	(*new_auth_tok) = &auth_tok_list_item->auth_tok;
+
+	/* check for body size - one to two bytes */
+	rc = parse_packet_length(&data[(*packet_size)], &body_size,
+				 &length_size);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "Error parsing packet length; "
+				"rc = [%d]\n", rc);
+		goto out_free;
+	}
+	if (unlikely(body_size < (0x05 + ECRYPTFS_SALT_SIZE))) {
+		ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
+				body_size);
+		rc = -EINVAL;
+		goto out_free;
+	}
+	(*packet_size) += length_size;
+
+	/* now we know the length of the remainting Tag 3 packet size:
+	 *   5 fix bytes for: version string, cipher, S2K ID, hash algo,
+	 *                    number of hash iterations
+	 *   ECRYPTFS_SALT_SIZE bytes for salt
+	 *   body_size bytes minus the stuff above is the encrypted key size
+	 */
+	if (unlikely((*packet_size) + body_size > max_packet_size)) {
+		ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+		rc = -EINVAL;
+		goto out_free;
+	}
+
+	/* There are 5 characters of additional information in the
+	 * packet */
+	(*new_auth_tok)->session_key.encrypted_key_size =
+		body_size - (0x05 + ECRYPTFS_SALT_SIZE);
+	ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n",
+			(*new_auth_tok)->session_key.encrypted_key_size);
+
+	/* Version 4 (from RFC2440) - one byte */
+	if (unlikely(data[(*packet_size)++] != 0x04)) {
+		ecryptfs_printk(KERN_DEBUG, "Unknown version number "
+				"[%d]\n", data[(*packet_size) - 1]);
+		rc = -EINVAL;
+		goto out_free;
+	}
+
+	/* cipher - one byte */
+	ecryptfs_cipher_code_to_string(crypt_stat->cipher,
+				       (u16)data[(*packet_size)]);
+	/* A little extra work to differentiate among the AES key
+	 * sizes; see RFC2440 */
+	switch(data[(*packet_size)++]) {
+	case RFC2440_CIPHER_AES_192:
+		crypt_stat->key_size = 24;
+		break;
+	default:
+		crypt_stat->key_size =
+			(*new_auth_tok)->session_key.encrypted_key_size;
+	}
+	ecryptfs_init_crypt_ctx(crypt_stat);
+	/* S2K identifier 3 (from RFC2440) */
+	if (unlikely(data[(*packet_size)++] != 0x03)) {
+		ecryptfs_printk(KERN_ERR, "Only S2K ID 3 is currently "
+				"supported\n");
+		rc = -ENOSYS;
+		goto out_free;
+	}
+
+	/* TODO: finish the hash mapping */
+	/* hash algorithm - one byte */
+	switch (data[(*packet_size)++]) {
+	case 0x01: /* See RFC2440 for these numbers and their mappings */
+		/* Choose MD5 */
+		/* salt - ECRYPTFS_SALT_SIZE bytes */
+		memcpy((*new_auth_tok)->token.password.salt,
+		       &data[(*packet_size)], ECRYPTFS_SALT_SIZE);
+		(*packet_size) += ECRYPTFS_SALT_SIZE;
+
+		/* This conversion was taken straight from RFC2440 */
+		/* number of hash iterations - one byte */
+		(*new_auth_tok)->token.password.hash_iterations =
+			((u32) 16 + (data[(*packet_size)] & 15))
+				<< ((data[(*packet_size)] >> 4) + 6);
+		(*packet_size)++;
+
+		/* encrypted session key -
+		 *   (body_size-5-ECRYPTFS_SALT_SIZE) bytes */
+		memcpy((*new_auth_tok)->session_key.encrypted_key,
+		       &data[(*packet_size)],
+		       (*new_auth_tok)->session_key.encrypted_key_size);
+		(*packet_size) +=
+			(*new_auth_tok)->session_key.encrypted_key_size;
+		(*new_auth_tok)->session_key.flags &=
+			~ECRYPTFS_CONTAINS_DECRYPTED_KEY;
+		(*new_auth_tok)->session_key.flags |=
+			ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
+		(*new_auth_tok)->token.password.hash_algo = 0x01;
+		break;
+	default:
+		ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: "
+				"[%d]\n", data[(*packet_size) - 1]);
+		rc = -ENOSYS;
+		goto out_free;
+	}
+	(*new_auth_tok)->token_type = ECRYPTFS_PASSWORD;
+	/* TODO: Parametarize; we might actually want userspace to
+	 * decrypt the session key. */
+	ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
+			    ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
+	ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
+			    ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT);
+	list_add(&auth_tok_list_item->list, auth_tok_list);
+	goto out;
+out_free:
+	(*new_auth_tok) = NULL;
+	memset(auth_tok_list_item, 0,
+	       sizeof(struct ecryptfs_auth_tok_list_item));
+	kmem_cache_free(ecryptfs_auth_tok_list_item_cache,
+			auth_tok_list_item);
+out:
+	if (rc)
+		(*packet_size) = 0;
+	return rc;
+}
+
+/**
+ * parse_tag_11_packet
+ * @data: The raw bytes of the packet
+ * @contents: This function writes the data contents of the literal
+ *            packet into this memory location
+ * @max_contents_bytes: The maximum number of bytes that this function
+ *                      is allowed to write into contents
+ * @tag_11_contents_size: This function writes the size of the parsed
+ *                        contents into this memory location; zero on
+ *                        error
+ * @packet_size: This function writes the size of the parsed packet
+ *               into this memory location; zero on error
+ * @max_packet_size: maximum number of bytes to parse
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+parse_tag_11_packet(unsigned char *data, unsigned char *contents,
+		    size_t max_contents_bytes, size_t *tag_11_contents_size,
+		    size_t *packet_size, size_t max_packet_size)
+{
+	int rc = 0;
+	size_t body_size;
+	size_t length_size;
+
+	(*packet_size) = 0;
+	(*tag_11_contents_size) = 0;
+
+	/* check that:
+	 *   one byte for the Tag 11 ID flag
+	 *   two bytes for the Tag 11 length
+	 * do not exceed the maximum_packet_size
+	 */
+	if (unlikely((*packet_size) + 3 > max_packet_size)) {
+		ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* check for Tag 11 identifyer - one byte */
+	if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) {
+		ecryptfs_printk(KERN_WARNING,
+				"Invalid tag 11 packet format\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* get Tag 11 content length - one or two bytes */
+	rc = parse_packet_length(&data[(*packet_size)], &body_size,
+				 &length_size);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING,
+				"Invalid tag 11 packet format\n");
+		goto out;
+	}
+	(*packet_size) += length_size;
+
+	if (body_size < 13) {
+		ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
+				body_size);
+		rc = -EINVAL;
+		goto out;
+	}
+	/* We have 13 bytes of surrounding packet values */
+	(*tag_11_contents_size) = (body_size - 13);
+
+	/* now we know the length of the remainting Tag 11 packet size:
+	 *   14 fix bytes for: special flag one, special flag two,
+	 *   		       12 skipped bytes
+	 *   body_size bytes minus the stuff above is the Tag 11 content
+	 */
+	/* FIXME why is the body size one byte smaller than the actual
+	 * size of the body?
+	 * this seems to be an error here as well as in
+	 * write_tag_11_packet() */
+	if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) {
+		ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* special flag one - one byte */
+	if (data[(*packet_size)++] != 0x62) {
+		ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* special flag two - one byte */
+	if (data[(*packet_size)++] != 0x08) {
+		ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* skip the next 12 bytes */
+	(*packet_size) += 12; /* We don't care about the filename or
+			       * the timestamp */
+
+	/* get the Tag 11 contents - tag_11_contents_size bytes */
+	memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size));
+	(*packet_size) += (*tag_11_contents_size);
+
+out:
+	if (rc) {
+		(*packet_size) = 0;
+		(*tag_11_contents_size) = 0;
+	}
+	return rc;
+}
+
+/**
+ * decrypt_session_key - Decrypt the session key with the given auth_tok.
+ *
+ * Returns Zero on success; non-zero error otherwise.
+ */
+static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
+			       struct ecryptfs_crypt_stat *crypt_stat)
+{
+	int rc = 0;
+	struct ecryptfs_password *password_s_ptr;
+	struct crypto_tfm *tfm = NULL;
+	struct scatterlist src_sg[2], dst_sg[2];
+	struct mutex *tfm_mutex = NULL;
+	/* TODO: Use virt_to_scatterlist for these */
+	char *encrypted_session_key;
+	char *session_key;
+
+	password_s_ptr = &auth_tok->token.password;
+	if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags,
+				ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET))
+		ecryptfs_printk(KERN_DEBUG, "Session key encryption key "
+				"set; skipping key generation\n");
+	ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])"
+			":\n",
+			password_s_ptr->session_key_encryption_key_bytes);
+	if (ecryptfs_verbosity > 0)
+		ecryptfs_dump_hex(password_s_ptr->session_key_encryption_key,
+				  password_s_ptr->
+				  session_key_encryption_key_bytes);
+	if (!strcmp(crypt_stat->cipher,
+		    crypt_stat->mount_crypt_stat->global_default_cipher_name)
+	    && crypt_stat->mount_crypt_stat->global_key_tfm) {
+		tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+		tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
+	} else {
+		tfm = crypto_alloc_tfm(crypt_stat->cipher,
+				       CRYPTO_TFM_REQ_WEAK_KEY);
+		if (!tfm) {
+			printk(KERN_ERR "Error allocating crypto context\n");
+			rc = -ENOMEM;
+			goto out;
+		}
+	}
+	if (password_s_ptr->session_key_encryption_key_bytes
+	    < crypto_tfm_alg_min_keysize(tfm)) {
+		printk(KERN_WARNING "Session key encryption key is [%d] bytes; "
+		       "minimum keysize for selected cipher is [%d] bytes.\n",
+		       password_s_ptr->session_key_encryption_key_bytes,
+		       crypto_tfm_alg_min_keysize(tfm));
+		rc = -EINVAL;
+		goto out;
+	}
+	if (tfm_mutex)
+		mutex_lock(tfm_mutex);
+	crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
+			     crypt_stat->key_size);
+	/* TODO: virt_to_scatterlist */
+	encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
+	if (!encrypted_session_key) {
+		ecryptfs_printk(KERN_ERR, "Out of memory\n");
+		rc = -ENOMEM;
+		goto out_free_tfm;
+	}
+	session_key = (char *)__get_free_page(GFP_KERNEL);
+	if (!session_key) {
+		kfree(encrypted_session_key);
+		ecryptfs_printk(KERN_ERR, "Out of memory\n");
+		rc = -ENOMEM;
+		goto out_free_tfm;
+	}
+	memcpy(encrypted_session_key, auth_tok->session_key.encrypted_key,
+	       auth_tok->session_key.encrypted_key_size);
+	src_sg[0].page = virt_to_page(encrypted_session_key);
+	src_sg[0].offset = 0;
+	BUG_ON(auth_tok->session_key.encrypted_key_size > PAGE_CACHE_SIZE);
+	src_sg[0].length = auth_tok->session_key.encrypted_key_size;
+	dst_sg[0].page = virt_to_page(session_key);
+	dst_sg[0].offset = 0;
+	auth_tok->session_key.decrypted_key_size =
+	    auth_tok->session_key.encrypted_key_size;
+	dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
+	/* TODO: Handle error condition */
+	crypto_cipher_decrypt(tfm, dst_sg, src_sg,
+			      auth_tok->session_key.encrypted_key_size);
+	auth_tok->session_key.decrypted_key_size =
+	    auth_tok->session_key.encrypted_key_size;
+	memcpy(auth_tok->session_key.decrypted_key, session_key,
+	       auth_tok->session_key.decrypted_key_size);
+	auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY;
+	memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key,
+	       auth_tok->session_key.decrypted_key_size);
+	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+	ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n");
+	if (ecryptfs_verbosity > 0)
+		ecryptfs_dump_hex(crypt_stat->key,
+				  crypt_stat->key_size);
+	memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
+	free_page((unsigned long)encrypted_session_key);
+	memset(session_key, 0, PAGE_CACHE_SIZE);
+	free_page((unsigned long)session_key);
+out_free_tfm:
+	if (tfm_mutex)
+		mutex_unlock(tfm_mutex);
+	else
+		crypto_free_tfm(tfm);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_parse_packet_set
+ * @dest: The header page in memory
+ * @version: Version of file format, to guide parsing behavior
+ *
+ * Get crypt_stat to have the file's session key if the requisite key
+ * is available to decrypt the session key.
+ *
+ * Returns Zero if a valid authentication token was retrieved and
+ * processed; negative value for file not encrypted or for error
+ * conditions.
+ */
+int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
+			      unsigned char *src,
+			      struct dentry *ecryptfs_dentry)
+{
+	size_t i = 0;
+	int rc = 0;
+	size_t found_auth_tok = 0;
+	size_t next_packet_is_auth_tok_packet;
+	char sig[ECRYPTFS_SIG_SIZE_HEX];
+	struct list_head auth_tok_list;
+	struct list_head *walker;
+	struct ecryptfs_auth_tok *chosen_auth_tok = NULL;
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+		&ecryptfs_superblock_to_private(
+			ecryptfs_dentry->d_sb)->mount_crypt_stat;
+	struct ecryptfs_auth_tok *candidate_auth_tok = NULL;
+	size_t packet_size;
+	struct ecryptfs_auth_tok *new_auth_tok;
+	unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE];
+	size_t tag_11_contents_size;
+	size_t tag_11_packet_size;
+
+	INIT_LIST_HEAD(&auth_tok_list);
+	/* Parse the header to find as many packets as we can, these will be
+	 * added the our &auth_tok_list */
+	next_packet_is_auth_tok_packet = 1;
+	while (next_packet_is_auth_tok_packet) {
+		size_t max_packet_size = ((PAGE_CACHE_SIZE - 8) - i);
+
+		switch (src[i]) {
+		case ECRYPTFS_TAG_3_PACKET_TYPE:
+			rc = parse_tag_3_packet(crypt_stat,
+						(unsigned char *)&src[i],
+						&auth_tok_list, &new_auth_tok,
+						&packet_size, max_packet_size);
+			if (rc) {
+				ecryptfs_printk(KERN_ERR, "Error parsing "
+						"tag 3 packet\n");
+				rc = -EIO;
+				goto out_wipe_list;
+			}
+			i += packet_size;
+			rc = parse_tag_11_packet((unsigned char *)&src[i],
+						 sig_tmp_space,
+						 ECRYPTFS_SIG_SIZE,
+						 &tag_11_contents_size,
+						 &tag_11_packet_size,
+						 max_packet_size);
+			if (rc) {
+				ecryptfs_printk(KERN_ERR, "No valid "
+						"(ecryptfs-specific) literal "
+						"packet containing "
+						"authentication token "
+						"signature found after "
+						"tag 3 packet\n");
+				rc = -EIO;
+				goto out_wipe_list;
+			}
+			i += tag_11_packet_size;
+			if (ECRYPTFS_SIG_SIZE != tag_11_contents_size) {
+				ecryptfs_printk(KERN_ERR, "Expected "
+						"signature of size [%d]; "
+						"read size [%d]\n",
+						ECRYPTFS_SIG_SIZE,
+						tag_11_contents_size);
+				rc = -EIO;
+				goto out_wipe_list;
+			}
+			ecryptfs_to_hex(new_auth_tok->token.password.signature,
+					sig_tmp_space, tag_11_contents_size);
+			new_auth_tok->token.password.signature[
+				ECRYPTFS_PASSWORD_SIG_SIZE] = '\0';
+			ECRYPTFS_SET_FLAG(crypt_stat->flags,
+					  ECRYPTFS_ENCRYPTED);
+			break;
+		case ECRYPTFS_TAG_11_PACKET_TYPE:
+			ecryptfs_printk(KERN_WARNING, "Invalid packet set "
+					"(Tag 11 not allowed by itself)\n");
+			rc = -EIO;
+			goto out_wipe_list;
+			break;
+		default:
+			ecryptfs_printk(KERN_DEBUG, "No packet at offset "
+					"[%d] of the file header; hex value of "
+					"character is [0x%.2x]\n", i, src[i]);
+			next_packet_is_auth_tok_packet = 0;
+		}
+	}
+	if (list_empty(&auth_tok_list)) {
+		rc = -EINVAL; /* Do not support non-encrypted files in
+			       * the 0.1 release */
+		goto out;
+	}
+	/* If we have a global auth tok, then we should try to use
+	 * it */
+	if (mount_crypt_stat->global_auth_tok) {
+		memcpy(sig, mount_crypt_stat->global_auth_tok_sig,
+		       ECRYPTFS_SIG_SIZE_HEX);
+		chosen_auth_tok = mount_crypt_stat->global_auth_tok;
+	} else
+		BUG(); /* We should always have a global auth tok in
+			* the 0.1 release */
+	/* Scan list to see if our chosen_auth_tok works */
+	list_for_each(walker, &auth_tok_list) {
+		struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
+		auth_tok_list_item =
+		    list_entry(walker, struct ecryptfs_auth_tok_list_item,
+			       list);
+		candidate_auth_tok = &auth_tok_list_item->auth_tok;
+		if (unlikely(ecryptfs_verbosity > 0)) {
+			ecryptfs_printk(KERN_DEBUG,
+					"Considering cadidate auth tok:\n");
+			ecryptfs_dump_auth_tok(candidate_auth_tok);
+		}
+		/* TODO: Replace ECRYPTFS_SIG_SIZE_HEX w/ dynamic value */
+		if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD
+		    && !strncmp(candidate_auth_tok->token.password.signature,
+				sig, ECRYPTFS_SIG_SIZE_HEX)) {
+			found_auth_tok = 1;
+			goto leave_list;
+			/* TODO: Transfer the common salt into the
+			 * crypt_stat salt */
+		}
+	}
+leave_list:
+	if (!found_auth_tok) {
+		ecryptfs_printk(KERN_ERR, "Could not find authentication "
+				"token on temporary list for sig [%.*s]\n",
+				ECRYPTFS_SIG_SIZE_HEX, sig);
+		rc = -EIO;
+		goto out_wipe_list;
+	} else {
+		memcpy(&(candidate_auth_tok->token.password),
+		       &(chosen_auth_tok->token.password),
+		       sizeof(struct ecryptfs_password));
+		rc = decrypt_session_key(candidate_auth_tok, crypt_stat);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error decrypting the "
+					"session key\n");
+			goto out_wipe_list;
+		}
+		rc = ecryptfs_compute_root_iv(crypt_stat);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error computing "
+					"the root IV\n");
+			goto out_wipe_list;
+		}
+	}
+	rc = ecryptfs_init_crypt_ctx(crypt_stat);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error initializing crypto "
+				"context for cipher [%s]; rc = [%d]\n",
+				crypt_stat->cipher, rc);
+	}
+out_wipe_list:
+	wipe_auth_tok_list(&auth_tok_list);
+out:
+	return rc;
+}
+
+/**
+ * write_tag_11_packet
+ * @dest: Target into which Tag 11 packet is to be written
+ * @max: Maximum packet length
+ * @contents: Byte array of contents to copy in
+ * @contents_length: Number of bytes in contents
+ * @packet_length: Length of the Tag 11 packet written; zero on error
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length,
+		    size_t *packet_length)
+{
+	int rc = 0;
+	size_t packet_size_length;
+
+	(*packet_length) = 0;
+	if ((13 + contents_length) > max) {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_ERR, "Packet length larger than "
+				"maximum allowable\n");
+		goto out;
+	}
+	/* General packet header */
+	/* Packet tag */
+	dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE;
+	/* Packet length */
+	rc = write_packet_length(&dest[(*packet_length)],
+				 (13 + contents_length), &packet_size_length);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error generating tag 11 packet "
+				"header; cannot generate packet length\n");
+		goto out;
+	}
+	(*packet_length) += packet_size_length;
+	/* Tag 11 specific */
+	/* One-octet field that describes how the data is formatted */
+	dest[(*packet_length)++] = 0x62; /* binary data */
+	/* One-octet filename length followed by filename */
+	dest[(*packet_length)++] = 8;
+	memcpy(&dest[(*packet_length)], "_CONSOLE", 8);
+	(*packet_length) += 8;
+	/* Four-octet number indicating modification date */
+	memset(&dest[(*packet_length)], 0x00, 4);
+	(*packet_length) += 4;
+	/* Remainder is literal data */
+	memcpy(&dest[(*packet_length)], contents, contents_length);
+	(*packet_length) += contents_length;
+ out:
+	if (rc)
+		(*packet_length) = 0;
+	return rc;
+}
+
+/**
+ * write_tag_3_packet
+ * @dest: Buffer into which to write the packet
+ * @max: Maximum number of bytes that can be written
+ * @auth_tok: Authentication token
+ * @crypt_stat: The cryptographic context
+ * @key_rec: encrypted key
+ * @packet_size: This function will write the number of bytes that end
+ *               up constituting the packet; set to zero on error
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
+		   struct ecryptfs_crypt_stat *crypt_stat,
+		   struct ecryptfs_key_record *key_rec, size_t *packet_size)
+{
+	int rc = 0;
+
+	size_t i;
+	size_t signature_is_valid = 0;
+	size_t encrypted_session_key_valid = 0;
+	char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+	struct scatterlist dest_sg[2];
+	struct scatterlist src_sg[2];
+	struct crypto_tfm *tfm = NULL;
+	struct mutex *tfm_mutex = NULL;
+	size_t key_rec_size;
+	size_t packet_size_length;
+	size_t cipher_code;
+
+	(*packet_size) = 0;
+	/* Check for a valid signature on the auth_tok */
+	for (i = 0; i < ECRYPTFS_SIG_SIZE_HEX; i++)
+		signature_is_valid |= auth_tok->token.password.signature[i];
+	if (!signature_is_valid)
+		BUG();
+	ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature,
+			  ECRYPTFS_SIG_SIZE);
+	encrypted_session_key_valid = 0;
+	for (i = 0; i < crypt_stat->key_size; i++)
+		encrypted_session_key_valid |=
+			auth_tok->session_key.encrypted_key[i];
+	if (encrypted_session_key_valid) {
+		memcpy((*key_rec).enc_key,
+		       auth_tok->session_key.encrypted_key,
+		       auth_tok->session_key.encrypted_key_size);
+		goto encrypted_session_key_set;
+	}
+	if (auth_tok->session_key.encrypted_key_size == 0)
+		auth_tok->session_key.encrypted_key_size =
+			crypt_stat->key_size;
+	if (crypt_stat->key_size == 24
+	    && strcmp("aes", crypt_stat->cipher) == 0) {
+		memset((crypt_stat->key + 24), 0, 8);
+		auth_tok->session_key.encrypted_key_size = 32;
+	}
+	(*key_rec).enc_key_size =
+		auth_tok->session_key.encrypted_key_size;
+	if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
+				ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) {
+		ecryptfs_printk(KERN_DEBUG, "Using previously generated "
+				"session key encryption key of size [%d]\n",
+				auth_tok->token.password.
+				session_key_encryption_key_bytes);
+		memcpy(session_key_encryption_key,
+		       auth_tok->token.password.session_key_encryption_key,
+		       crypt_stat->key_size);
+		ecryptfs_printk(KERN_DEBUG,
+				"Cached session key " "encryption key: \n");
+		if (ecryptfs_verbosity > 0)
+			ecryptfs_dump_hex(session_key_encryption_key, 16);
+	}
+	if (unlikely(ecryptfs_verbosity > 0)) {
+		ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n");
+		ecryptfs_dump_hex(session_key_encryption_key, 16);
+	}
+	rc = virt_to_scatterlist(crypt_stat->key,
+				 (*key_rec).enc_key_size, src_sg, 2);
+	if (!rc) {
+		ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
+				"for crypt_stat session key\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	rc = virt_to_scatterlist((*key_rec).enc_key,
+				 (*key_rec).enc_key_size, dest_sg, 2);
+	if (!rc) {
+		ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
+				"for crypt_stat encrypted session key\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	if (!strcmp(crypt_stat->cipher,
+		    crypt_stat->mount_crypt_stat->global_default_cipher_name)
+	    && crypt_stat->mount_crypt_stat->global_key_tfm) {
+		tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+		tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
+	} else
+		tfm = crypto_alloc_tfm(crypt_stat->cipher, 0);
+	if (!tfm) {
+		ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
+				"context for cipher [%s]\n",
+				crypt_stat->cipher);
+		rc = -EINVAL;
+		goto out;
+	}
+	if (tfm_mutex)
+		mutex_lock(tfm_mutex);
+	rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
+				  crypt_stat->key_size);
+	if (rc < 0) {
+		if (tfm_mutex)
+			mutex_unlock(tfm_mutex);
+		ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
+				"context\n");
+		goto out;
+	}
+	rc = 0;
+	ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
+			crypt_stat->key_size);
+	crypto_cipher_encrypt(tfm, dest_sg, src_sg,
+			      (*key_rec).enc_key_size);
+	if (tfm_mutex)
+		mutex_unlock(tfm_mutex);
+	ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
+	if (ecryptfs_verbosity > 0)
+		ecryptfs_dump_hex((*key_rec).enc_key,
+				  (*key_rec).enc_key_size);
+encrypted_session_key_set:
+	/* Now we have a valid key_rec.  Append it to the
+	 * key_rec set. */
+	key_rec_size = (sizeof(struct ecryptfs_key_record)
+			- ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
+			+ ((*key_rec).enc_key_size));
+	/* TODO: Include a packet size limit as a parameter to this
+	 * function once we have multi-packet headers (for versions
+	 * later than 0.1 */
+	if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) {
+		ecryptfs_printk(KERN_ERR, "Keyset too large\n");
+		rc = -EINVAL;
+		goto out;
+	}
+	/* TODO: Packet size limit */
+	/* We have 5 bytes of surrounding packet data */
+	if ((0x05 + ECRYPTFS_SALT_SIZE
+	     + (*key_rec).enc_key_size) >= max) {
+		ecryptfs_printk(KERN_ERR, "Authentication token is too "
+				"large\n");
+		rc = -EINVAL;
+		goto out;
+	}
+	/* This format is inspired by OpenPGP; see RFC 2440
+	 * packet tag 3 */
+	dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE;
+	/* ver+cipher+s2k+hash+salt+iter+enc_key */
+	rc = write_packet_length(&dest[(*packet_size)],
+				 (0x05 + ECRYPTFS_SALT_SIZE
+				  + (*key_rec).enc_key_size),
+				 &packet_size_length);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet "
+				"header; cannot generate packet length\n");
+		goto out;
+	}
+	(*packet_size) += packet_size_length;
+	dest[(*packet_size)++] = 0x04; /* version 4 */
+	cipher_code = ecryptfs_code_for_cipher_string(crypt_stat);
+	if (cipher_code == 0) {
+		ecryptfs_printk(KERN_WARNING, "Unable to generate code for "
+				"cipher [%s]\n", crypt_stat->cipher);
+		rc = -EINVAL;
+		goto out;
+	}
+	dest[(*packet_size)++] = cipher_code;
+	dest[(*packet_size)++] = 0x03;	/* S2K */
+	dest[(*packet_size)++] = 0x01;	/* MD5 (TODO: parameterize) */
+	memcpy(&dest[(*packet_size)], auth_tok->token.password.salt,
+	       ECRYPTFS_SALT_SIZE);
+	(*packet_size) += ECRYPTFS_SALT_SIZE;	/* salt */
+	dest[(*packet_size)++] = 0x60;	/* hash iterations (65536) */
+	memcpy(&dest[(*packet_size)], (*key_rec).enc_key,
+	       (*key_rec).enc_key_size);
+	(*packet_size) += (*key_rec).enc_key_size;
+out:
+	if (tfm && !tfm_mutex)
+		crypto_free_tfm(tfm);
+	if (rc)
+		(*packet_size) = 0;
+	return rc;
+}
+
+/**
+ * ecryptfs_generate_key_packet_set
+ * @dest: Virtual address from which to write the key record set
+ * @crypt_stat: The cryptographic context from which the
+ *              authentication tokens will be retrieved
+ * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat
+ *                   for the global parameters
+ * @len: The amount written
+ * @max: The maximum amount of data allowed to be written
+ *
+ * Generates a key packet set and writes it to the virtual address
+ * passed in.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+int
+ecryptfs_generate_key_packet_set(char *dest_base,
+				 struct ecryptfs_crypt_stat *crypt_stat,
+				 struct dentry *ecryptfs_dentry, size_t *len,
+				 size_t max)
+{
+	int rc = 0;
+	struct ecryptfs_auth_tok *auth_tok;
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+		&ecryptfs_superblock_to_private(
+			ecryptfs_dentry->d_sb)->mount_crypt_stat;
+	size_t written;
+	struct ecryptfs_key_record key_rec;
+
+	(*len) = 0;
+	if (mount_crypt_stat->global_auth_tok) {
+		auth_tok = mount_crypt_stat->global_auth_tok;
+		if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
+			rc = write_tag_3_packet((dest_base + (*len)),
+						max, auth_tok,
+						crypt_stat, &key_rec,
+						&written);
+			if (rc) {
+				ecryptfs_printk(KERN_WARNING, "Error "
+						"writing tag 3 packet\n");
+				goto out;
+			}
+			(*len) += written;
+			/* Write auth tok signature packet */
+			rc = write_tag_11_packet(
+				(dest_base + (*len)),
+				(max - (*len)),
+				key_rec.sig, ECRYPTFS_SIG_SIZE, &written);
+			if (rc) {
+				ecryptfs_printk(KERN_ERR, "Error writing "
+						"auth tok signature packet\n");
+				goto out;
+			}
+			(*len) += written;
+		} else {
+			ecryptfs_printk(KERN_WARNING, "Unsupported "
+					"authentication token type\n");
+			rc = -EINVAL;
+			goto out;
+		}
+		if (rc) {
+			ecryptfs_printk(KERN_WARNING, "Error writing "
+					"authentication token packet with sig "
+					"= [%s]\n",
+					mount_crypt_stat->global_auth_tok_sig);
+			rc = -EIO;
+			goto out;
+		}
+	} else
+		BUG();
+	if (likely((max - (*len)) > 0)) {
+		dest_base[(*len)] = 0x00;
+	} else {
+		ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n");
+		rc = -EIO;
+	}
+out:
+	if (rc)
+		(*len) = 0;
+	return rc;
+}
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
new file mode 100644
index 0000000..7a11b8a
--- /dev/null
+++ b/fs/ecryptfs/main.c
@@ -0,0 +1,831 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *              Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/dcache.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/namei.h>
+#include <linux/skbuff.h>
+#include <linux/crypto.h>
+#include <linux/netlink.h>
+#include <linux/mount.h>
+#include <linux/dcache.h>
+#include <linux/pagemap.h>
+#include <linux/key.h>
+#include <linux/parser.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * Module parameter that defines the ecryptfs_verbosity level.
+ */
+int ecryptfs_verbosity = 0;
+
+module_param(ecryptfs_verbosity, int, 0);
+MODULE_PARM_DESC(ecryptfs_verbosity,
+		 "Initial verbosity level (0 or 1; defaults to "
+		 "0, which is Quiet)");
+
+void __ecryptfs_printk(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	if (fmt[1] == '7') { /* KERN_DEBUG */
+		if (ecryptfs_verbosity >= 1)
+			vprintk(fmt, args);
+	} else
+		vprintk(fmt, args);
+	va_end(args);
+}
+
+/**
+ * ecryptfs_interpose
+ * @lower_dentry: Existing dentry in the lower filesystem
+ * @dentry: ecryptfs' dentry
+ * @sb: ecryptfs's super_block
+ * @flag: If set to true, then d_add is called, else d_instantiate is called
+ *
+ * Interposes upper and lower dentries.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
+		       struct super_block *sb, int flag)
+{
+	struct inode *lower_inode;
+	struct inode *inode;
+	int rc = 0;
+
+	lower_inode = lower_dentry->d_inode;
+	if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) {
+		rc = -EXDEV;
+		goto out;
+	}
+	if (!igrab(lower_inode)) {
+		rc = -ESTALE;
+		goto out;
+	}
+	inode = iget5_locked(sb, (unsigned long)lower_inode,
+			     ecryptfs_inode_test, ecryptfs_inode_set,
+			     lower_inode);
+	if (!inode) {
+		rc = -EACCES;
+		iput(lower_inode);
+		goto out;
+	}
+	if (inode->i_state & I_NEW)
+		unlock_new_inode(inode);
+	else
+		iput(lower_inode);
+	if (S_ISLNK(lower_inode->i_mode))
+		inode->i_op = &ecryptfs_symlink_iops;
+	else if (S_ISDIR(lower_inode->i_mode))
+		inode->i_op = &ecryptfs_dir_iops;
+	if (S_ISDIR(lower_inode->i_mode))
+		inode->i_fop = &ecryptfs_dir_fops;
+	/* TODO: Is there a better way to identify if the inode is
+	 * special? */
+	if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
+	    S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
+		init_special_inode(inode, lower_inode->i_mode,
+				   lower_inode->i_rdev);
+	dentry->d_op = &ecryptfs_dops;
+	if (flag)
+		d_add(dentry, inode);
+	else
+		d_instantiate(dentry, inode);
+	ecryptfs_copy_attr_all(inode, lower_inode);
+	/* This size will be overwritten for real files w/ headers and
+	 * other metadata */
+	ecryptfs_copy_inode_size(inode, lower_inode);
+out:
+	return rc;
+}
+
+enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug,
+       ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher,
+       ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes,
+       ecryptfs_opt_passthrough, ecryptfs_opt_err };
+
+static match_table_t tokens = {
+	{ecryptfs_opt_sig, "sig=%s"},
+	{ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"},
+	{ecryptfs_opt_debug, "debug=%u"},
+	{ecryptfs_opt_ecryptfs_debug, "ecryptfs_debug=%u"},
+	{ecryptfs_opt_cipher, "cipher=%s"},
+	{ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"},
+	{ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"},
+	{ecryptfs_opt_passthrough, "ecryptfs_passthrough"},
+	{ecryptfs_opt_err, NULL}
+};
+
+/**
+ * ecryptfs_verify_version
+ * @version: The version number to confirm
+ *
+ * Returns zero on good version; non-zero otherwise
+ */
+static int ecryptfs_verify_version(u16 version)
+{
+	int rc = 0;
+	unsigned char major;
+	unsigned char minor;
+
+	major = ((version >> 8) & 0xFF);
+	minor = (version & 0xFF);
+	if (major != ECRYPTFS_VERSION_MAJOR) {
+		ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
+				"Expected [%d]; got [%d]\n",
+				ECRYPTFS_VERSION_MAJOR, major);
+		rc = -EINVAL;
+		goto out;
+	}
+	if (minor != ECRYPTFS_VERSION_MINOR) {
+		ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
+				"Expected [%d]; got [%d]\n",
+				ECRYPTFS_VERSION_MINOR, minor);
+		rc = -EINVAL;
+		goto out;
+	}
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_parse_options
+ * @sb: The ecryptfs super block
+ * @options: The options pased to the kernel
+ *
+ * Parse mount options:
+ * debug=N 	   - ecryptfs_verbosity level for debug output
+ * sig=XXX	   - description(signature) of the key to use
+ *
+ * Returns the dentry object of the lower-level (lower/interposed)
+ * directory; We want to mount our stackable file system on top of
+ * that lower directory.
+ *
+ * The signature of the key to use must be the description of a key
+ * already in the keyring. Mounting will fail if the key can not be
+ * found.
+ *
+ * Returns zero on success; non-zero on error
+ */
+static int ecryptfs_parse_options(struct super_block *sb, char *options)
+{
+	char *p;
+	int rc = 0;
+	int sig_set = 0;
+	int cipher_name_set = 0;
+	int cipher_key_bytes;
+	int cipher_key_bytes_set = 0;
+	struct key *auth_tok_key = NULL;
+	struct ecryptfs_auth_tok *auth_tok = NULL;
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+		&ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
+	substring_t args[MAX_OPT_ARGS];
+	int token;
+	char *sig_src;
+	char *sig_dst;
+	char *debug_src;
+	char *cipher_name_dst;
+	char *cipher_name_src;
+	char *cipher_key_bytes_src;
+	struct crypto_tfm *tmp_tfm;
+	int cipher_name_len;
+
+	if (!options) {
+		rc = -EINVAL;
+		goto out;
+	}
+	while ((p = strsep(&options, ",")) != NULL) {
+		if (!*p)
+			continue;
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case ecryptfs_opt_sig:
+		case ecryptfs_opt_ecryptfs_sig:
+			sig_src = args[0].from;
+			sig_dst =
+				mount_crypt_stat->global_auth_tok_sig;
+			memcpy(sig_dst, sig_src, ECRYPTFS_SIG_SIZE_HEX);
+			sig_dst[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+			ecryptfs_printk(KERN_DEBUG,
+					"The mount_crypt_stat "
+					"global_auth_tok_sig set to: "
+					"[%s]\n", sig_dst);
+			sig_set = 1;
+			break;
+		case ecryptfs_opt_debug:
+		case ecryptfs_opt_ecryptfs_debug:
+			debug_src = args[0].from;
+			ecryptfs_verbosity =
+				(int)simple_strtol(debug_src, &debug_src,
+						   0);
+			ecryptfs_printk(KERN_DEBUG,
+					"Verbosity set to [%d]" "\n",
+					ecryptfs_verbosity);
+			break;
+		case ecryptfs_opt_cipher:
+		case ecryptfs_opt_ecryptfs_cipher:
+			cipher_name_src = args[0].from;
+			cipher_name_dst =
+				mount_crypt_stat->
+				global_default_cipher_name;
+			strncpy(cipher_name_dst, cipher_name_src,
+				ECRYPTFS_MAX_CIPHER_NAME_SIZE);
+			ecryptfs_printk(KERN_DEBUG,
+					"The mount_crypt_stat "
+					"global_default_cipher_name set to: "
+					"[%s]\n", cipher_name_dst);
+			cipher_name_set = 1;
+			break;
+		case ecryptfs_opt_ecryptfs_key_bytes:
+			cipher_key_bytes_src = args[0].from;
+			cipher_key_bytes =
+				(int)simple_strtol(cipher_key_bytes_src,
+						   &cipher_key_bytes_src, 0);
+			mount_crypt_stat->global_default_cipher_key_size =
+				cipher_key_bytes;
+			ecryptfs_printk(KERN_DEBUG,
+					"The mount_crypt_stat "
+					"global_default_cipher_key_size "
+					"set to: [%d]\n", mount_crypt_stat->
+					global_default_cipher_key_size);
+			cipher_key_bytes_set = 1;
+			break;
+		case ecryptfs_opt_passthrough:
+			mount_crypt_stat->flags |=
+				ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED;
+			break;
+		case ecryptfs_opt_err:
+		default:
+			ecryptfs_printk(KERN_WARNING,
+					"eCryptfs: unrecognized option '%s'\n",
+					p);
+		}
+	}
+	/* Do not support lack of mount-wide signature in 0.1
+	 * release */
+	if (!sig_set) {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_ERR, "You must supply a valid "
+				"passphrase auth tok signature as a mount "
+				"parameter; see the eCryptfs README\n");
+		goto out;
+	}
+	if (!cipher_name_set) {
+		cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER);
+		if (unlikely(cipher_name_len
+			     >= ECRYPTFS_MAX_CIPHER_NAME_SIZE)) {
+			rc = -EINVAL;
+			BUG();
+			goto out;
+		}
+		memcpy(mount_crypt_stat->global_default_cipher_name,
+		       ECRYPTFS_DEFAULT_CIPHER, cipher_name_len);
+		mount_crypt_stat->global_default_cipher_name[cipher_name_len]
+		    = '\0';
+	}
+	if (!cipher_key_bytes_set) {
+		mount_crypt_stat->global_default_cipher_key_size =
+			ECRYPTFS_DEFAULT_KEY_BYTES;
+		ecryptfs_printk(KERN_DEBUG, "Cipher key size was not "
+				"specified.  Defaulting to [%d]\n",
+				mount_crypt_stat->
+				global_default_cipher_key_size);
+	}
+	rc = ecryptfs_process_cipher(
+		&tmp_tfm,
+		&mount_crypt_stat->global_key_tfm,
+		mount_crypt_stat->global_default_cipher_name,
+		mount_crypt_stat->global_default_cipher_key_size);
+	if (tmp_tfm)
+		crypto_free_tfm(tmp_tfm);
+	if (rc) {
+		printk(KERN_ERR "Error attempting to initialize cipher [%s] "
+		       "with key size [%Zd] bytes; rc = [%d]\n",
+		       mount_crypt_stat->global_default_cipher_name,
+		       mount_crypt_stat->global_default_cipher_key_size, rc);
+		rc = -EINVAL;
+		goto out;
+	}
+	mutex_init(&mount_crypt_stat->global_key_tfm_mutex);
+	ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: "
+			"[%s]\n", mount_crypt_stat->global_auth_tok_sig);
+	/* The reference to this key is held until umount is done The
+	 * call to key_put is done in ecryptfs_put_super() */
+	auth_tok_key = request_key(&key_type_user,
+				   mount_crypt_stat->global_auth_tok_sig,
+				   NULL);
+	if (!auth_tok_key || IS_ERR(auth_tok_key)) {
+		ecryptfs_printk(KERN_ERR, "Could not find key with "
+				"description: [%s]\n",
+				mount_crypt_stat->global_auth_tok_sig);
+		process_request_key_err(PTR_ERR(auth_tok_key));
+		rc = -EINVAL;
+		goto out;
+	}
+	auth_tok = ecryptfs_get_key_payload_data(auth_tok_key);
+	if (ecryptfs_verify_version(auth_tok->version)) {
+		ecryptfs_printk(KERN_ERR, "Data structure version mismatch. "
+				"Userspace tools must match eCryptfs kernel "
+				"module with major version [%d] and minor "
+				"version [%d]\n", ECRYPTFS_VERSION_MAJOR,
+				ECRYPTFS_VERSION_MINOR);
+		rc = -EINVAL;
+		goto out;
+	}
+	if (auth_tok->token_type != ECRYPTFS_PASSWORD) {
+		ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure "
+				"returned from key\n");
+		rc = -EINVAL;
+		goto out;
+	}
+	mount_crypt_stat->global_auth_tok_key = auth_tok_key;
+	mount_crypt_stat->global_auth_tok = auth_tok;
+out:
+	return rc;
+}
+
+struct kmem_cache *ecryptfs_sb_info_cache;
+
+/**
+ * ecryptfs_fill_super
+ * @sb: The ecryptfs super block
+ * @raw_data: The options passed to mount
+ * @silent: Not used but required by function prototype
+ *
+ * Sets up what we can of the sb, rest is done in ecryptfs_read_super
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int
+ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent)
+{
+	int rc = 0;
+
+	/* Released in ecryptfs_put_super() */
+	ecryptfs_set_superblock_private(sb,
+					kmem_cache_alloc(ecryptfs_sb_info_cache,
+							 SLAB_KERNEL));
+	if (!ecryptfs_superblock_to_private(sb)) {
+		ecryptfs_printk(KERN_WARNING, "Out of memory\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	memset(ecryptfs_superblock_to_private(sb), 0,
+	       sizeof(struct ecryptfs_sb_info));
+	sb->s_op = &ecryptfs_sops;
+	/* Released through deactivate_super(sb) from get_sb_nodev */
+	sb->s_root = d_alloc(NULL, &(const struct qstr) {
+			     .hash = 0,.name = "/",.len = 1});
+	if (!sb->s_root) {
+		ecryptfs_printk(KERN_ERR, "d_alloc failed\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	sb->s_root->d_op = &ecryptfs_dops;
+	sb->s_root->d_sb = sb;
+	sb->s_root->d_parent = sb->s_root;
+	/* Released in d_release when dput(sb->s_root) is called */
+	/* through deactivate_super(sb) from get_sb_nodev() */
+	ecryptfs_set_dentry_private(sb->s_root,
+				    kmem_cache_alloc(ecryptfs_dentry_info_cache,
+						     SLAB_KERNEL));
+	if (!ecryptfs_dentry_to_private(sb->s_root)) {
+		ecryptfs_printk(KERN_ERR,
+				"dentry_info_cache alloc failed\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+	memset(ecryptfs_dentry_to_private(sb->s_root), 0,
+	       sizeof(struct ecryptfs_dentry_info));
+	rc = 0;
+out:
+	/* Should be able to rely on deactivate_super called from
+	 * get_sb_nodev */
+	return rc;
+}
+
+/**
+ * ecryptfs_read_super
+ * @sb: The ecryptfs super block
+ * @dev_name: The path to mount over
+ *
+ * Read the super block of the lower filesystem, and use
+ * ecryptfs_interpose to create our initial inode and super block
+ * struct.
+ */
+static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
+{
+	int rc;
+	struct nameidata nd;
+	struct dentry *lower_root;
+	struct vfsmount *lower_mnt;
+
+	memset(&nd, 0, sizeof(struct nameidata));
+	rc = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
+		goto out_free;
+	}
+	lower_root = nd.dentry;
+	if (!lower_root->d_inode) {
+		ecryptfs_printk(KERN_WARNING,
+				"No directory to interpose on\n");
+		rc = -ENOENT;
+		goto out_free;
+	}
+	lower_mnt = nd.mnt;
+	ecryptfs_set_superblock_lower(sb, lower_root->d_sb);
+	sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
+	ecryptfs_set_dentry_lower(sb->s_root, lower_root);
+	ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt);
+	if ((rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0)))
+		goto out_free;
+	rc = 0;
+	goto out;
+out_free:
+	path_release(&nd);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_get_sb
+ * @fs_type
+ * @flags
+ * @dev_name: The path to mount over
+ * @raw_data: The options passed into the kernel
+ *
+ * The whole ecryptfs_get_sb process is broken into 4 functions:
+ * ecryptfs_parse_options(): handle options passed to ecryptfs, if any
+ * ecryptfs_fill_super(): used by get_sb_nodev, fills out the super_block
+ *                        with as much information as it can before needing
+ *                        the lower filesystem.
+ * ecryptfs_read_super(): this accesses the lower filesystem and uses
+ *                        ecryptfs_interpolate to perform most of the linking
+ * ecryptfs_interpolate(): links the lower filesystem into ecryptfs
+ */
+static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
+			const char *dev_name, void *raw_data,
+			struct vfsmount *mnt)
+{
+	int rc;
+	struct super_block *sb;
+
+	rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt);
+	if (rc < 0) {
+		printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc);
+		goto out;
+	}
+	sb = mnt->mnt_sb;
+	rc = ecryptfs_parse_options(sb, raw_data);
+	if (rc) {
+		printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc);
+		goto out_abort;
+	}
+	rc = ecryptfs_read_super(sb, dev_name);
+	if (rc) {
+		printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc);
+		goto out_abort;
+	}
+	goto out;
+out_abort:
+	dput(sb->s_root);
+	up_write(&sb->s_umount);
+	deactivate_super(sb);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_kill_block_super
+ * @sb: The ecryptfs super block
+ *
+ * Used to bring the superblock down and free the private data.
+ * Private data is free'd in ecryptfs_put_super()
+ */
+static void ecryptfs_kill_block_super(struct super_block *sb)
+{
+	generic_shutdown_super(sb);
+}
+
+static struct file_system_type ecryptfs_fs_type = {
+	.owner = THIS_MODULE,
+	.name = "ecryptfs",
+	.get_sb = ecryptfs_get_sb,
+	.kill_sb = ecryptfs_kill_block_super,
+	.fs_flags = 0
+};
+
+/**
+ * inode_info_init_once
+ *
+ * Initializes the ecryptfs_inode_info_cache when it is created
+ */
+static void
+inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags)
+{
+	struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr;
+
+	if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR)
+		inode_init_once(&ei->vfs_inode);
+}
+
+static struct ecryptfs_cache_info {
+	kmem_cache_t **cache;
+	const char *name;
+	size_t size;
+	void (*ctor)(void*, struct kmem_cache *, unsigned long);
+} ecryptfs_cache_infos[] = {
+	{
+		.cache = &ecryptfs_auth_tok_list_item_cache,
+		.name = "ecryptfs_auth_tok_list_item",
+		.size = sizeof(struct ecryptfs_auth_tok_list_item),
+	},
+	{
+		.cache = &ecryptfs_file_info_cache,
+		.name = "ecryptfs_file_cache",
+		.size = sizeof(struct ecryptfs_file_info),
+	},
+	{
+		.cache = &ecryptfs_dentry_info_cache,
+		.name = "ecryptfs_dentry_info_cache",
+		.size = sizeof(struct ecryptfs_dentry_info),
+	},
+	{
+		.cache = &ecryptfs_inode_info_cache,
+		.name = "ecryptfs_inode_cache",
+		.size = sizeof(struct ecryptfs_inode_info),
+		.ctor = inode_info_init_once,
+	},
+	{
+		.cache = &ecryptfs_sb_info_cache,
+		.name = "ecryptfs_sb_cache",
+		.size = sizeof(struct ecryptfs_sb_info),
+	},
+	{
+		.cache = &ecryptfs_header_cache_0,
+		.name = "ecryptfs_headers_0",
+		.size = PAGE_CACHE_SIZE,
+	},
+	{
+		.cache = &ecryptfs_header_cache_1,
+		.name = "ecryptfs_headers_1",
+		.size = PAGE_CACHE_SIZE,
+	},
+	{
+		.cache = &ecryptfs_header_cache_2,
+		.name = "ecryptfs_headers_2",
+		.size = PAGE_CACHE_SIZE,
+	},
+	{
+		.cache = &ecryptfs_lower_page_cache,
+		.name = "ecryptfs_lower_page_cache",
+		.size = PAGE_CACHE_SIZE,
+	},
+};
+
+static void ecryptfs_free_kmem_caches(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) {
+		struct ecryptfs_cache_info *info;
+
+		info = &ecryptfs_cache_infos[i];
+		if (*(info->cache))
+			kmem_cache_destroy(*(info->cache));
+	}
+}
+
+/**
+ * ecryptfs_init_kmem_caches
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_init_kmem_caches(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) {
+		struct ecryptfs_cache_info *info;
+
+		info = &ecryptfs_cache_infos[i];
+		*(info->cache) = kmem_cache_create(info->name, info->size,
+				0, SLAB_HWCACHE_ALIGN, info->ctor, NULL);
+		if (!*(info->cache)) {
+			ecryptfs_free_kmem_caches();
+			ecryptfs_printk(KERN_WARNING, "%s: "
+					"kmem_cache_create failed\n",
+					info->name);
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
+struct ecryptfs_obj {
+	char *name;
+	struct list_head slot_list;
+	struct kobject kobj;
+};
+
+struct ecryptfs_attribute {
+	struct attribute attr;
+	ssize_t(*show) (struct ecryptfs_obj *, char *);
+	ssize_t(*store) (struct ecryptfs_obj *, const char *, size_t);
+};
+
+static ssize_t
+ecryptfs_attr_store(struct kobject *kobj,
+		    struct attribute *attr, const char *buf, size_t len)
+{
+	struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj,
+						kobj);
+	struct ecryptfs_attribute *attribute =
+		container_of(attr, struct ecryptfs_attribute, attr);
+
+	return (attribute->store ? attribute->store(obj, buf, len) : 0);
+}
+
+static ssize_t
+ecryptfs_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj,
+						kobj);
+	struct ecryptfs_attribute *attribute =
+		container_of(attr, struct ecryptfs_attribute, attr);
+
+	return (attribute->show ? attribute->show(obj, buf) : 0);
+}
+
+static struct sysfs_ops ecryptfs_sysfs_ops = {
+	.show = ecryptfs_attr_show,
+	.store = ecryptfs_attr_store
+};
+
+static struct kobj_type ecryptfs_ktype = {
+	.sysfs_ops = &ecryptfs_sysfs_ops
+};
+
+static decl_subsys(ecryptfs, &ecryptfs_ktype, NULL);
+
+static ssize_t version_show(struct ecryptfs_obj *obj, char *buff)
+{
+	return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK);
+}
+
+static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version);
+
+struct ecryptfs_version_str_map_elem {
+	u32 flag;
+	char *str;
+} ecryptfs_version_str_map[] = {
+	{ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"},
+	{ECRYPTFS_VERSIONING_PUBKEY, "pubkey"},
+	{ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"},
+	{ECRYPTFS_VERSIONING_POLICY, "policy"}
+};
+
+static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff)
+{
+	int i;
+	int remaining = PAGE_SIZE;
+	int total_written = 0;
+
+	buff[0] = '\0';
+	for (i = 0; i < ARRAY_SIZE(ecryptfs_version_str_map); i++) {
+		int entry_size;
+
+		if (!(ECRYPTFS_VERSIONING_MASK
+		      & ecryptfs_version_str_map[i].flag))
+			continue;
+		entry_size = strlen(ecryptfs_version_str_map[i].str);
+		if ((entry_size + 2) > remaining)
+			goto out;
+		memcpy(buff, ecryptfs_version_str_map[i].str, entry_size);
+		buff[entry_size++] = '\n';
+		buff[entry_size] = '\0';
+		buff += entry_size;
+		total_written += entry_size;
+		remaining -= entry_size;
+	}
+out:
+	return total_written;
+}
+
+static struct ecryptfs_attribute sysfs_attr_version_str = __ATTR_RO(version_str);
+
+static int do_sysfs_registration(void)
+{
+	int rc;
+
+	if ((rc = subsystem_register(&ecryptfs_subsys))) {
+		printk(KERN_ERR
+		       "Unable to register ecryptfs sysfs subsystem\n");
+		goto out;
+	}
+	rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj,
+			       &sysfs_attr_version.attr);
+	if (rc) {
+		printk(KERN_ERR
+		       "Unable to create ecryptfs version attribute\n");
+		subsystem_unregister(&ecryptfs_subsys);
+		goto out;
+	}
+	rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj,
+			       &sysfs_attr_version_str.attr);
+	if (rc) {
+		printk(KERN_ERR
+		       "Unable to create ecryptfs version_str attribute\n");
+		sysfs_remove_file(&ecryptfs_subsys.kset.kobj,
+				  &sysfs_attr_version.attr);
+		subsystem_unregister(&ecryptfs_subsys);
+		goto out;
+	}
+out:
+	return rc;
+}
+
+static int __init ecryptfs_init(void)
+{
+	int rc;
+
+	if (ECRYPTFS_DEFAULT_EXTENT_SIZE > PAGE_CACHE_SIZE) {
+		rc = -EINVAL;
+		ecryptfs_printk(KERN_ERR, "The eCryptfs extent size is "
+				"larger than the host's page size, and so "
+				"eCryptfs cannot run on this system. The "
+				"default eCryptfs extent size is [%d] bytes; "
+				"the page size is [%d] bytes.\n",
+				ECRYPTFS_DEFAULT_EXTENT_SIZE, PAGE_CACHE_SIZE);
+		goto out;
+	}
+	rc = ecryptfs_init_kmem_caches();
+	if (rc) {
+		printk(KERN_ERR
+		       "Failed to allocate one or more kmem_cache objects\n");
+		goto out;
+	}
+	rc = register_filesystem(&ecryptfs_fs_type);
+	if (rc) {
+		printk(KERN_ERR "Failed to register filesystem\n");
+		ecryptfs_free_kmem_caches();
+		goto out;
+	}
+	kset_set_kset_s(&ecryptfs_subsys, fs_subsys);
+	sysfs_attr_version.attr.owner = THIS_MODULE;
+	sysfs_attr_version_str.attr.owner = THIS_MODULE;
+	rc = do_sysfs_registration();
+	if (rc) {
+		printk(KERN_ERR "sysfs registration failed\n");
+		unregister_filesystem(&ecryptfs_fs_type);
+		ecryptfs_free_kmem_caches();
+		goto out;
+	}
+out:
+	return rc;
+}
+
+static void __exit ecryptfs_exit(void)
+{
+	sysfs_remove_file(&ecryptfs_subsys.kset.kobj,
+			  &sysfs_attr_version.attr);
+	sysfs_remove_file(&ecryptfs_subsys.kset.kobj,
+			  &sysfs_attr_version_str.attr);
+	subsystem_unregister(&ecryptfs_subsys);
+	unregister_filesystem(&ecryptfs_fs_type);
+	ecryptfs_free_kmem_caches();
+}
+
+MODULE_AUTHOR("Michael A. Halcrow <mhalcrow@us.ibm.com>");
+MODULE_DESCRIPTION("eCryptfs");
+
+MODULE_LICENSE("GPL");
+
+module_init(ecryptfs_init)
+module_exit(ecryptfs_exit)
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
new file mode 100644
index 0000000..924dd90
--- /dev/null
+++ b/fs/ecryptfs/mmap.c
@@ -0,0 +1,788 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * This is where eCryptfs coordinates the symmetric encryption and
+ * decryption of the file data as it passes between the lower
+ * encrypted file and the upper decrypted file.
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/pagemap.h>
+#include <linux/writeback.h>
+#include <linux/page-flags.h>
+#include <linux/mount.h>
+#include <linux/file.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include "ecryptfs_kernel.h"
+
+struct kmem_cache *ecryptfs_lower_page_cache;
+
+/**
+ * ecryptfs_get1page
+ *
+ * Get one page from cache or lower f/s, return error otherwise.
+ *
+ * Returns unlocked and up-to-date page (if ok), with increased
+ * refcnt.
+ */
+static struct page *ecryptfs_get1page(struct file *file, int index)
+{
+	struct page *page;
+	struct dentry *dentry;
+	struct inode *inode;
+	struct address_space *mapping;
+
+	dentry = file->f_dentry;
+	inode = dentry->d_inode;
+	mapping = inode->i_mapping;
+	page = read_cache_page(mapping, index,
+			       (filler_t *)mapping->a_ops->readpage,
+			       (void *)file);
+	if (IS_ERR(page))
+		goto out;
+	wait_on_page_locked(page);
+out:
+	return page;
+}
+
+static
+int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros);
+
+/**
+ * ecryptfs_fill_zeros
+ * @file: The ecryptfs file
+ * @new_length: The new length of the data in the underlying file;
+ *              everything between the prior end of the file and the
+ *              new end of the file will be filled with zero's.
+ *              new_length must be greater than  current length
+ *
+ * Function for handling lseek-ing past the end of the file.
+ *
+ * This function does not support shrinking, only growing a file.
+ *
+ * Returns zero on success; non-zero otherwise.
+ */
+int ecryptfs_fill_zeros(struct file *file, loff_t new_length)
+{
+	int rc = 0;
+	struct dentry *dentry = file->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	pgoff_t old_end_page_index = 0;
+	pgoff_t index = old_end_page_index;
+	int old_end_pos_in_page = -1;
+	pgoff_t new_end_page_index;
+	int new_end_pos_in_page;
+	loff_t cur_length = i_size_read(inode);
+
+	if (cur_length != 0) {
+		index = old_end_page_index =
+		    ((cur_length - 1) >> PAGE_CACHE_SHIFT);
+		old_end_pos_in_page = ((cur_length - 1) & ~PAGE_CACHE_MASK);
+	}
+	new_end_page_index = ((new_length - 1) >> PAGE_CACHE_SHIFT);
+	new_end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK);
+	ecryptfs_printk(KERN_DEBUG, "old_end_page_index = [0x%.16x]; "
+			"old_end_pos_in_page = [%d]; "
+			"new_end_page_index = [0x%.16x]; "
+			"new_end_pos_in_page = [%d]\n",
+			old_end_page_index, old_end_pos_in_page,
+			new_end_page_index, new_end_pos_in_page);
+	if (old_end_page_index == new_end_page_index) {
+		/* Start and end are in the same page; we just need to
+		 * set a portion of the existing page to zero's */
+		rc = write_zeros(file, index, (old_end_pos_in_page + 1),
+				 (new_end_pos_in_page - old_end_pos_in_page));
+		if (rc)
+			ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
+					"index=[0x%.16x], "
+					"old_end_pos_in_page=[d], "
+					"(PAGE_CACHE_SIZE - new_end_pos_in_page"
+					"=[%d]"
+					")=[d]) returned [%d]\n", file, index,
+					old_end_pos_in_page,
+					new_end_pos_in_page,
+					(PAGE_CACHE_SIZE - new_end_pos_in_page),
+					rc);
+		goto out;
+	}
+	/* Fill the remainder of the previous last page with zeros */
+	rc = write_zeros(file, index, (old_end_pos_in_page + 1),
+			 ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page));
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
+				"index=[0x%.16x], old_end_pos_in_page=[d], "
+				"(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) "
+				"returned [%d]\n", file, index,
+				old_end_pos_in_page,
+				(PAGE_CACHE_SIZE - old_end_pos_in_page), rc);
+		goto out;
+	}
+	index++;
+	while (index < new_end_page_index) {
+		/* Fill all intermediate pages with zeros */
+		rc = write_zeros(file, index, 0, PAGE_CACHE_SIZE);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
+					"index=[0x%.16x], "
+					"old_end_pos_in_page=[d], "
+					"(PAGE_CACHE_SIZE - new_end_pos_in_page"
+					"=[%d]"
+					")=[d]) returned [%d]\n", file, index,
+					old_end_pos_in_page,
+					new_end_pos_in_page,
+					(PAGE_CACHE_SIZE - new_end_pos_in_page),
+					rc);
+			goto out;
+		}
+		index++;
+	}
+	/* Fill the portion at the beginning of the last new page with
+	 * zero's */
+	rc = write_zeros(file, index, 0, (new_end_pos_in_page + 1));
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "write_zeros(file="
+				"[%p], index=[0x%.16x], 0, "
+				"new_end_pos_in_page=[%d]"
+				"returned [%d]\n", file, index,
+				new_end_pos_in_page, rc);
+		goto out;
+	}
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_writepage
+ * @page: Page that is locked before this call is made
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
+{
+	struct ecryptfs_page_crypt_context ctx;
+	int rc;
+
+	ctx.page = page;
+	ctx.mode = ECRYPTFS_WRITEPAGE_MODE;
+	ctx.param.wbc = wbc;
+	rc = ecryptfs_encrypt_page(&ctx);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "Error encrypting "
+				"page (upper index [0x%.16x])\n", page->index);
+		ClearPageUptodate(page);
+		goto out;
+	}
+	SetPageUptodate(page);
+	unlock_page(page);
+out:
+	return rc;
+}
+
+/**
+ * Reads the data from the lower file file at index lower_page_index
+ * and copies that data into page.
+ *
+ * @param page	Page to fill
+ * @param lower_page_index Index of the page in the lower file to get
+ */
+int ecryptfs_do_readpage(struct file *file, struct page *page,
+			 pgoff_t lower_page_index)
+{
+	int rc;
+	struct dentry *dentry;
+	struct file *lower_file;
+	struct dentry *lower_dentry;
+	struct inode *inode;
+	struct inode *lower_inode;
+	char *page_data;
+	struct page *lower_page = NULL;
+	char *lower_page_data;
+	const struct address_space_operations *lower_a_ops;
+
+	dentry = file->f_dentry;
+	lower_file = ecryptfs_file_to_lower(file);
+	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	inode = dentry->d_inode;
+	lower_inode = ecryptfs_inode_to_lower(inode);
+	lower_a_ops = lower_inode->i_mapping->a_ops;
+	lower_page = read_cache_page(lower_inode->i_mapping, lower_page_index,
+				     (filler_t *)lower_a_ops->readpage,
+				     (void *)lower_file);
+	if (IS_ERR(lower_page)) {
+		rc = PTR_ERR(lower_page);
+		lower_page = NULL;
+		ecryptfs_printk(KERN_ERR, "Error reading from page cache\n");
+		goto out;
+	}
+	wait_on_page_locked(lower_page);
+	page_data = (char *)kmap(page);
+	if (!page_data) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR, "Error mapping page\n");
+		goto out;
+	}
+	lower_page_data = (char *)kmap(lower_page);
+	if (!lower_page_data) {
+		rc = -ENOMEM;
+		ecryptfs_printk(KERN_ERR, "Error mapping page\n");
+		kunmap(page);
+		goto out;
+	}
+	memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
+	kunmap(lower_page);
+	kunmap(page);
+	rc = 0;
+out:
+	if (likely(lower_page))
+		page_cache_release(lower_page);
+	if (rc == 0)
+		SetPageUptodate(page);
+	else
+		ClearPageUptodate(page);
+	return rc;
+}
+
+/**
+ * ecryptfs_readpage
+ * @file: This is an ecryptfs file
+ * @page: ecryptfs associated page to stick the read data into
+ *
+ * Read in a page, decrypting if necessary.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int ecryptfs_readpage(struct file *file, struct page *page)
+{
+	int rc = 0;
+	struct ecryptfs_crypt_stat *crypt_stat;
+
+	BUG_ON(!(file && file->f_dentry && file->f_dentry->d_inode));
+	crypt_stat =
+		&ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat;
+	if (!crypt_stat
+	    || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)
+	    || ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) {
+		ecryptfs_printk(KERN_DEBUG,
+				"Passing through unencrypted page\n");
+		rc = ecryptfs_do_readpage(file, page, page->index);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error reading page; rc = "
+					"[%d]\n", rc);
+			goto out;
+		}
+	} else {
+		rc = ecryptfs_decrypt_page(file, page);
+		if (rc) {
+
+			ecryptfs_printk(KERN_ERR, "Error decrypting page; "
+					"rc = [%d]\n", rc);
+			goto out;
+		}
+	}
+	SetPageUptodate(page);
+out:
+	if (rc)
+		ClearPageUptodate(page);
+	ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
+			page->index);
+	unlock_page(page);
+	return rc;
+}
+
+static int fill_zeros_to_end_of_page(struct page *page, unsigned int to)
+{
+	struct inode *inode = page->mapping->host;
+	int end_byte_in_page;
+	int rc = 0;
+	char *page_virt;
+
+	if ((i_size_read(inode) / PAGE_CACHE_SIZE) == page->index) {
+		end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE;
+		if (to > end_byte_in_page)
+			end_byte_in_page = to;
+		page_virt = kmap(page);
+		if (!page_virt) {
+			rc = -ENOMEM;
+			ecryptfs_printk(KERN_WARNING,
+					"Could not map page\n");
+			goto out;
+		}
+		memset((page_virt + end_byte_in_page), 0,
+		       (PAGE_CACHE_SIZE - end_byte_in_page));
+		kunmap(page);
+	}
+out:
+	return rc;
+}
+
+static int ecryptfs_prepare_write(struct file *file, struct page *page,
+				  unsigned from, unsigned to)
+{
+	int rc = 0;
+
+	kmap(page);
+	if (from == 0 && to == PAGE_CACHE_SIZE)
+		goto out;	/* If we are writing a full page, it will be
+				   up to date. */
+	if (!PageUptodate(page))
+		rc = ecryptfs_do_readpage(file, page, page->index);
+out:
+	return rc;
+}
+
+int ecryptfs_grab_and_map_lower_page(struct page **lower_page,
+				     char **lower_virt,
+				     struct inode *lower_inode,
+				     unsigned long lower_page_index)
+{
+	int rc = 0;
+
+	(*lower_page) = grab_cache_page(lower_inode->i_mapping,
+					lower_page_index);
+	if (!(*lower_page)) {
+		ecryptfs_printk(KERN_ERR, "grab_cache_page for "
+				"lower_page_index = [0x%.16x] failed\n",
+				lower_page_index);
+		rc = -EINVAL;
+		goto out;
+	}
+	if (lower_virt)
+		(*lower_virt) = kmap((*lower_page));
+	else
+		kmap((*lower_page));
+out:
+	return rc;
+}
+
+int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
+					      struct inode *lower_inode,
+					      struct writeback_control *wbc)
+{
+	int rc = 0;
+
+	rc = lower_inode->i_mapping->a_ops->writepage(lower_page, wbc);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error calling lower writepage(); "
+				"rc = [%d]\n", rc);
+		goto out;
+	}
+	lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+	page_cache_release(lower_page);
+out:
+	return rc;
+}
+
+static void ecryptfs_unmap_and_release_lower_page(struct page *lower_page)
+{
+	kunmap(lower_page);
+	ecryptfs_printk(KERN_DEBUG, "Unlocking lower page with index = "
+			"[0x%.16x]\n", lower_page->index);
+	unlock_page(lower_page);
+	page_cache_release(lower_page);
+}
+
+/**
+ * ecryptfs_write_inode_size_to_header
+ *
+ * Writes the lower file size to the first 8 bytes of the header.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+int
+ecryptfs_write_inode_size_to_header(struct file *lower_file,
+				    struct inode *lower_inode,
+				    struct inode *inode)
+{
+	int rc = 0;
+	struct page *header_page;
+	char *header_virt;
+	const struct address_space_operations *lower_a_ops;
+	u64 file_size;
+
+	rc = ecryptfs_grab_and_map_lower_page(&header_page, &header_virt,
+					      lower_inode, 0);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "grab_cache_page for header page "
+				"failed\n");
+		goto out;
+	}
+	lower_a_ops = lower_inode->i_mapping->a_ops;
+	rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8);
+	file_size = (u64)i_size_read(inode);
+	ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size);
+	file_size = cpu_to_be64(file_size);
+	memcpy(header_virt, &file_size, sizeof(u64));
+	rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8);
+	if (rc < 0)
+		ecryptfs_printk(KERN_ERR, "Error commiting header page "
+				"write\n");
+	ecryptfs_unmap_and_release_lower_page(header_page);
+	lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty_sync(inode);
+out:
+	return rc;
+}
+
+int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
+			    struct file *lower_file,
+			    unsigned long lower_page_index, int byte_offset,
+			    int region_bytes)
+{
+	int rc = 0;
+
+	rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL, lower_inode,
+					      lower_page_index);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error attempting to grab and map "
+				"lower page with index [0x%.16x]\n",
+				lower_page_index);
+		goto out;
+	}
+	rc = lower_inode->i_mapping->a_ops->prepare_write(lower_file,
+							  (*lower_page),
+							  byte_offset,
+							  region_bytes);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "prepare_write for "
+				"lower_page_index = [0x%.16x] failed; rc = "
+				"[%d]\n", lower_page_index, rc);
+	}
+out:
+	if (rc && (*lower_page)) {
+		ecryptfs_unmap_and_release_lower_page(*lower_page);
+		(*lower_page) = NULL;
+	}
+	return rc;
+}
+
+/**
+ * ecryptfs_commit_lower_page
+ *
+ * Returns zero on success; non-zero on error
+ */
+int
+ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
+			   struct file *lower_file, int byte_offset,
+			   int region_size)
+{
+	int rc = 0;
+
+	rc = lower_inode->i_mapping->a_ops->commit_write(
+		lower_file, lower_page, byte_offset, region_size);
+	if (rc < 0) {
+		ecryptfs_printk(KERN_ERR,
+				"Error committing write; rc = [%d]\n", rc);
+	} else
+		rc = 0;
+	ecryptfs_unmap_and_release_lower_page(lower_page);
+	return rc;
+}
+
+/**
+ * ecryptfs_copy_page_to_lower
+ *
+ * Used for plaintext pass-through; no page index interpolation
+ * required.
+ */
+int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
+				struct file *lower_file)
+{
+	int rc = 0;
+	struct page *lower_page;
+
+	rc = ecryptfs_get_lower_page(&lower_page, lower_inode, lower_file,
+				     page->index, 0, PAGE_CACHE_SIZE);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error attempting to get page "
+				"at index [0x%.16x]\n", page->index);
+		goto out;
+	}
+	/* TODO: aops */
+	memcpy((char *)page_address(lower_page), page_address(page),
+	       PAGE_CACHE_SIZE);
+	rc = ecryptfs_commit_lower_page(lower_page, lower_inode, lower_file,
+					0, PAGE_CACHE_SIZE);
+	if (rc)
+		ecryptfs_printk(KERN_ERR, "Error attempting to commit page "
+				"at index [0x%.16x]\n", page->index);
+out:
+	return rc;
+}
+
+static int
+process_new_file(struct ecryptfs_crypt_stat *crypt_stat,
+		 struct file *file, struct inode *inode)
+{
+	struct page *header_page;
+	const struct address_space_operations *lower_a_ops;
+	struct inode *lower_inode;
+	struct file *lower_file;
+	char *header_virt;
+	int rc = 0;
+	int current_header_page = 0;
+	int header_pages;
+	int more_header_data_to_be_written = 1;
+
+	lower_inode = ecryptfs_inode_to_lower(inode);
+	lower_file = ecryptfs_file_to_lower(file);
+	lower_a_ops = lower_inode->i_mapping->a_ops;
+	header_pages = ((crypt_stat->header_extent_size
+			 * crypt_stat->num_header_extents_at_front)
+			/ PAGE_CACHE_SIZE);
+	BUG_ON(header_pages < 1);
+	while (current_header_page < header_pages) {
+		rc = ecryptfs_grab_and_map_lower_page(&header_page,
+						      &header_virt,
+						      lower_inode,
+						      current_header_page);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "grab_cache_page for "
+					"header page [%d] failed; rc = [%d]\n",
+					current_header_page, rc);
+			goto out;
+		}
+		rc = lower_a_ops->prepare_write(lower_file, header_page, 0,
+						PAGE_CACHE_SIZE);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error preparing to write "
+					"header page out; rc = [%d]\n", rc);
+			goto out;
+		}
+		memset(header_virt, 0, PAGE_CACHE_SIZE);
+		if (more_header_data_to_be_written) {
+			rc = ecryptfs_write_headers_virt(header_virt,
+							 crypt_stat,
+							 file->f_dentry);
+			if (rc) {
+				ecryptfs_printk(KERN_WARNING, "Error "
+						"generating header; rc = "
+						"[%d]\n", rc);
+				rc = -EIO;
+				memset(header_virt, 0, PAGE_CACHE_SIZE);
+				ecryptfs_unmap_and_release_lower_page(
+					header_page);
+				goto out;
+			}
+			if (current_header_page == 0)
+				memset(header_virt, 0, 8);
+			more_header_data_to_be_written = 0;
+		}
+		rc = lower_a_ops->commit_write(lower_file, header_page, 0,
+					       PAGE_CACHE_SIZE);
+		ecryptfs_unmap_and_release_lower_page(header_page);
+		if (rc < 0) {
+			ecryptfs_printk(KERN_ERR,
+					"Error commiting header page write; "
+					"rc = [%d]\n", rc);
+			break;
+		}
+		current_header_page++;
+	}
+	if (rc >= 0) {
+		rc = 0;
+		ecryptfs_printk(KERN_DEBUG, "lower_inode->i_blocks = "
+				"[0x%.16x]\n", lower_inode->i_blocks);
+		i_size_write(inode, 0);
+		lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+		mark_inode_dirty_sync(inode);
+	}
+	ecryptfs_printk(KERN_DEBUG, "Clearing ECRYPTFS_NEW_FILE flag in "
+			"crypt_stat at memory location [%p]\n", crypt_stat);
+	ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE);
+out:
+	return rc;
+}
+
+/**
+ * ecryptfs_commit_write
+ * @file: The eCryptfs file object
+ * @page: The eCryptfs page
+ * @from: Ignored (we rotate the page IV on each write)
+ * @to: Ignored
+ *
+ * This is where we encrypt the data and pass the encrypted data to
+ * the lower filesystem.  In OpenPGP-compatible mode, we operate on
+ * entire underlying packets.
+ */
+static int ecryptfs_commit_write(struct file *file, struct page *page,
+				 unsigned from, unsigned to)
+{
+	struct ecryptfs_page_crypt_context ctx;
+	loff_t pos;
+	struct inode *inode;
+	struct inode *lower_inode;
+	struct file *lower_file;
+	struct ecryptfs_crypt_stat *crypt_stat;
+	int rc;
+
+	inode = page->mapping->host;
+	lower_inode = ecryptfs_inode_to_lower(inode);
+	lower_file = ecryptfs_file_to_lower(file);
+	mutex_lock(&lower_inode->i_mutex);
+	crypt_stat =
+		&ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat;
+	if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) {
+		ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
+			"crypt_stat at memory location [%p]\n", crypt_stat);
+		rc = process_new_file(crypt_stat, file, inode);
+		if (rc) {
+			ecryptfs_printk(KERN_ERR, "Error processing new "
+					"file; rc = [%d]\n", rc);
+			goto out;
+		}
+	} else
+		ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
+	ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
+			"(page w/ index = [0x%.16x], to = [%d])\n", page->index,
+			to);
+	rc = fill_zeros_to_end_of_page(page, to);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
+				"zeros in page with index = [0x%.16x]\n",
+				page->index);
+		goto out;
+	}
+	ctx.page = page;
+	ctx.mode = ECRYPTFS_PREPARE_COMMIT_MODE;
+	ctx.param.lower_file = lower_file;
+	rc = ecryptfs_encrypt_page(&ctx);
+	if (rc) {
+		ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
+				"index [0x%.16x])\n", page->index);
+		goto out;
+	}
+	rc = 0;
+	inode->i_blocks = lower_inode->i_blocks;
+	pos = (page->index << PAGE_CACHE_SHIFT) + to;
+	if (pos > i_size_read(inode)) {
+		i_size_write(inode, pos);
+		ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
+				"[0x%.16x]\n", i_size_read(inode));
+	}
+	ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode);
+	lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty_sync(inode);
+out:
+	kunmap(page); /* mapped in prior call (prepare_write) */
+	if (rc < 0)
+		ClearPageUptodate(page);
+	else
+		SetPageUptodate(page);
+	mutex_unlock(&lower_inode->i_mutex);
+	return rc;
+}
+
+/**
+ * write_zeros
+ * @file: The ecryptfs file
+ * @index: The index in which we are writing
+ * @start: The position after the last block of data
+ * @num_zeros: The number of zeros to write
+ *
+ * Write a specified number of zero's to a page.
+ *
+ * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE
+ */
+static
+int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros)
+{
+	int rc = 0;
+	struct page *tmp_page;
+
+	tmp_page = ecryptfs_get1page(file, index);
+	if (IS_ERR(tmp_page)) {
+		ecryptfs_printk(KERN_ERR, "Error getting page at index "
+				"[0x%.16x]\n", index);
+		rc = PTR_ERR(tmp_page);
+		goto out;
+	}
+	kmap(tmp_page);
+	rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros);
+	if (rc) {
+		ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
+				"to remainder of page at index [0x%.16x]\n",
+				index);
+		kunmap(tmp_page);
+		page_cache_release(tmp_page);
+		goto out;
+	}
+	memset(((char *)page_address(tmp_page) + start), 0, num_zeros);
+	rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros);
+	if (rc < 0) {
+		ecryptfs_printk(KERN_ERR, "Error attempting to write zero's "
+				"to remainder of page at index [0x%.16x]\n",
+				index);
+		kunmap(tmp_page);
+		page_cache_release(tmp_page);
+		goto out;
+	}
+	rc = 0;
+	kunmap(tmp_page);
+	page_cache_release(tmp_page);
+out:
+	return rc;
+}
+
+static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
+{
+	int rc = 0;
+	struct inode *inode;
+	struct inode *lower_inode;
+
+	inode = (struct inode *)mapping->host;
+	lower_inode = ecryptfs_inode_to_lower(inode);
+	if (lower_inode->i_mapping->a_ops->bmap)
+		rc = lower_inode->i_mapping->a_ops->bmap(lower_inode->i_mapping,
+							 block);
+	return rc;
+}
+
+static void ecryptfs_sync_page(struct page *page)
+{
+	struct inode *inode;
+	struct inode *lower_inode;
+	struct page *lower_page;
+
+	inode = page->mapping->host;
+	lower_inode = ecryptfs_inode_to_lower(inode);
+	/* NOTE: Recently swapped with grab_cache_page(), since
+	 * sync_page() just makes sure that pending I/O gets done. */
+	lower_page = find_lock_page(lower_inode->i_mapping, page->index);
+	if (!lower_page) {
+		ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n");
+		return;
+	}
+	lower_page->mapping->a_ops->sync_page(lower_page);
+	ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
+			lower_page->index);
+	unlock_page(lower_page);
+	page_cache_release(lower_page);
+}
+
+struct address_space_operations ecryptfs_aops = {
+	.writepage = ecryptfs_writepage,
+	.readpage = ecryptfs_readpage,
+	.prepare_write = ecryptfs_prepare_write,
+	.commit_write = ecryptfs_commit_write,
+	.bmap = ecryptfs_bmap,
+	.sync_page = ecryptfs_sync_page,
+};
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
new file mode 100644
index 0000000..c337c04
--- /dev/null
+++ b/fs/ecryptfs/super.c
@@ -0,0 +1,198 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *              Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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/fs.h>
+#include <linux/mount.h>
+#include <linux/key.h>
+#include <linux/seq_file.h>
+#include <linux/crypto.h>
+#include "ecryptfs_kernel.h"
+
+struct kmem_cache *ecryptfs_inode_info_cache;
+
+/**
+ * ecryptfs_alloc_inode - allocate an ecryptfs inode
+ * @sb: Pointer to the ecryptfs super block
+ *
+ * Called to bring an inode into existence.
+ *
+ * Only handle allocation, setting up structures should be done in
+ * ecryptfs_read_inode. This is because the kernel, between now and
+ * then, will 0 out the private data pointer.
+ *
+ * Returns a pointer to a newly allocated inode, NULL otherwise
+ */
+static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
+{
+	struct ecryptfs_inode_info *ecryptfs_inode;
+	struct inode *inode = NULL;
+
+	ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache,
+					  SLAB_KERNEL);
+	if (unlikely(!ecryptfs_inode))
+		goto out;
+	ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat);
+	inode = &ecryptfs_inode->vfs_inode;
+out:
+	return inode;
+}
+
+/**
+ * ecryptfs_destroy_inode
+ * @inode: The ecryptfs inode
+ *
+ * This is used during the final destruction of the inode.
+ * All allocation of memory related to the inode, including allocated
+ * memory in the crypt_stat struct, will be released here.
+ * There should be no chance that this deallocation will be missed.
+ */
+static void ecryptfs_destroy_inode(struct inode *inode)
+{
+	struct ecryptfs_inode_info *inode_info;
+
+	inode_info = ecryptfs_inode_to_private(inode);
+	ecryptfs_destruct_crypt_stat(&inode_info->crypt_stat);
+	kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
+}
+
+/**
+ * ecryptfs_init_inode
+ * @inode: The ecryptfs inode
+ *
+ * Set up the ecryptfs inode.
+ */
+void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode)
+{
+	ecryptfs_set_inode_lower(inode, lower_inode);
+	inode->i_ino = lower_inode->i_ino;
+	inode->i_version++;
+	inode->i_op = &ecryptfs_main_iops;
+	inode->i_fop = &ecryptfs_main_fops;
+	inode->i_mapping->a_ops = &ecryptfs_aops;
+}
+
+/**
+ * ecryptfs_put_super
+ * @sb: Pointer to the ecryptfs super block
+ *
+ * Final actions when unmounting a file system.
+ * This will handle deallocation and release of our private data.
+ */
+static void ecryptfs_put_super(struct super_block *sb)
+{
+	struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
+
+	ecryptfs_destruct_mount_crypt_stat(&sb_info->mount_crypt_stat);
+	kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
+	ecryptfs_set_superblock_private(sb, NULL);
+}
+
+/**
+ * ecryptfs_statfs
+ * @sb: The ecryptfs super block
+ * @buf: The struct kstatfs to fill in with stats
+ *
+ * Get the filesystem statistics. Currently, we let this pass right through
+ * to the lower filesystem and take no action ourselves.
+ */
+static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+	return vfs_statfs(ecryptfs_dentry_to_lower(dentry), buf);
+}
+
+/**
+ * ecryptfs_clear_inode
+ * @inode - The ecryptfs inode
+ *
+ * Called by iput() when the inode reference count reached zero
+ * and the inode is not hashed anywhere.  Used to clear anything
+ * that needs to be, before the inode is completely destroyed and put
+ * on the inode free list. We use this to drop out reference to the
+ * lower inode.
+ */
+static void ecryptfs_clear_inode(struct inode *inode)
+{
+	iput(ecryptfs_inode_to_lower(inode));
+}
+
+/**
+ * ecryptfs_umount_begin
+ *
+ * Called in do_umount().
+ */
+static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags)
+{
+	struct vfsmount *lower_mnt =
+		ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root);
+	struct super_block *lower_sb;
+
+	mntput(lower_mnt);
+	lower_sb = lower_mnt->mnt_sb;
+	if (lower_sb->s_op->umount_begin)
+		lower_sb->s_op->umount_begin(lower_mnt, flags);
+}
+
+/**
+ * ecryptfs_show_options
+ *
+ * Prints the directory we are currently mounted over.
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+	struct super_block *sb = mnt->mnt_sb;
+	struct dentry *lower_root_dentry = ecryptfs_dentry_to_lower(sb->s_root);
+	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(sb->s_root);
+	char *tmp_page;
+	char *path;
+	int rc = 0;
+
+	tmp_page = (char *)__get_free_page(GFP_KERNEL);
+	if (!tmp_page) {
+		rc = -ENOMEM;
+		goto out;
+	}
+	path = d_path(lower_root_dentry, lower_mnt, tmp_page, PAGE_SIZE);
+	if (IS_ERR(path)) {
+		rc = PTR_ERR(path);
+		goto out;
+	}
+	seq_printf(m, ",dir=%s", path);
+	free_page((unsigned long)tmp_page);
+out:
+	return rc;
+}
+
+struct super_operations ecryptfs_sops = {
+	.alloc_inode = ecryptfs_alloc_inode,
+	.destroy_inode = ecryptfs_destroy_inode,
+	.drop_inode = generic_delete_inode,
+	.put_super = ecryptfs_put_super,
+	.statfs = ecryptfs_statfs,
+	.remount_fs = NULL,
+	.clear_inode = ecryptfs_clear_inode,
+	.umount_begin = ecryptfs_umount_begin,
+	.show_options = ecryptfs_show_options
+};
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 8d54433..557d5b6 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -720,9 +720,10 @@
 
 	/* Allocates an inode from the eventpoll file system */
 	inode = ep_eventpoll_inode();
-	error = PTR_ERR(inode);
-	if (IS_ERR(inode))
+	if (IS_ERR(inode)) {
+		error = PTR_ERR(inode);
 		goto eexit_2;
+	}
 
 	/* Allocates a free descriptor to plug the file onto */
 	error = get_unused_fd();
diff --git a/fs/exec.c b/fs/exec.c
index 6270f8f..d993ea1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1318,7 +1318,7 @@
 			case 'h':
 				down_read(&uts_sem);
 				rc = snprintf(out_ptr, out_end - out_ptr,
-					      "%s", system_utsname.nodename);
+					      "%s", utsname()->nodename);
 				up_read(&uts_sem);
 				if (rc > out_end - out_ptr)
 					goto out;
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 4c39009..93e77c3 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -315,7 +315,7 @@
  * the name matching the specified inode number.
  */
 static int filldir_one(void * __buf, const char * name, int len,
-			loff_t pos, ino_t ino, unsigned int d_type)
+			loff_t pos, u64 ino, unsigned int d_type)
 {
 	struct getdents_callback *buf = __buf;
 	int result = 0;
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 3e50a41..69c439f 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -648,7 +648,7 @@
 }
 
 static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
-			     loff_t offset, ino_t ino, unsigned int d_type)
+			     loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct fat_ioctl_filldir_callback *buf = __buf;
 	struct dirent __user *d1 = buf->dirent;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index d35cbc6..e4f2616 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -250,19 +250,22 @@
 	return error;
 }
 
-static void f_modown(struct file *filp, unsigned long pid,
+static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
                      uid_t uid, uid_t euid, int force)
 {
 	write_lock_irq(&filp->f_owner.lock);
 	if (force || !filp->f_owner.pid) {
-		filp->f_owner.pid = pid;
+		put_pid(filp->f_owner.pid);
+		filp->f_owner.pid = get_pid(pid);
+		filp->f_owner.pid_type = type;
 		filp->f_owner.uid = uid;
 		filp->f_owner.euid = euid;
 	}
 	write_unlock_irq(&filp->f_owner.lock);
 }
 
-int f_setown(struct file *filp, unsigned long arg, int force)
+int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
+		int force)
 {
 	int err;
 	
@@ -270,15 +273,44 @@
 	if (err)
 		return err;
 
-	f_modown(filp, arg, current->uid, current->euid, force);
+	f_modown(filp, pid, type, current->uid, current->euid, force);
 	return 0;
 }
+EXPORT_SYMBOL(__f_setown);
 
+int f_setown(struct file *filp, unsigned long arg, int force)
+{
+	enum pid_type type;
+	struct pid *pid;
+	int who = arg;
+	int result;
+	type = PIDTYPE_PID;
+	if (who < 0) {
+		type = PIDTYPE_PGID;
+		who = -who;
+	}
+	rcu_read_lock();
+	pid = find_pid(who);
+	result = __f_setown(filp, pid, type, force);
+	rcu_read_unlock();
+	return result;
+}
 EXPORT_SYMBOL(f_setown);
 
 void f_delown(struct file *filp)
 {
-	f_modown(filp, 0, 0, 0, 1);
+	f_modown(filp, NULL, PIDTYPE_PID, 0, 0, 1);
+}
+
+pid_t f_getown(struct file *filp)
+{
+	pid_t pid;
+	read_lock(&filp->f_owner.lock);
+	pid = pid_nr(filp->f_owner.pid);
+	if (filp->f_owner.pid_type == PIDTYPE_PGID)
+		pid = -pid;
+	read_unlock(&filp->f_owner.lock);
+	return pid;
 }
 
 static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
@@ -319,7 +351,7 @@
 		 * current syscall conventions, the only way
 		 * to fix this will be in libc.
 		 */
-		err = filp->f_owner.pid;
+		err = f_getown(filp);
 		force_successful_syscall_return();
 		break;
 	case F_SETOWN:
@@ -470,24 +502,19 @@
 void send_sigio(struct fown_struct *fown, int fd, int band)
 {
 	struct task_struct *p;
-	int pid;
+	enum pid_type type;
+	struct pid *pid;
 	
 	read_lock(&fown->lock);
+	type = fown->pid_type;
 	pid = fown->pid;
 	if (!pid)
 		goto out_unlock_fown;
 	
 	read_lock(&tasklist_lock);
-	if (pid > 0) {
-		p = find_task_by_pid(pid);
-		if (p) {
-			send_sigio_to_task(p, fown, fd, band);
-		}
-	} else {
-		do_each_task_pid(-pid, PIDTYPE_PGID, p) {
-			send_sigio_to_task(p, fown, fd, band);
-		} while_each_task_pid(-pid, PIDTYPE_PGID, p);
-	}
+	do_each_pid_task(pid, type, p) {
+		send_sigio_to_task(p, fown, fd, band);
+	} while_each_pid_task(pid, type, p);
 	read_unlock(&tasklist_lock);
  out_unlock_fown:
 	read_unlock(&fown->lock);
@@ -503,9 +530,12 @@
 int send_sigurg(struct fown_struct *fown)
 {
 	struct task_struct *p;
-	int pid, ret = 0;
+	enum pid_type type;
+	struct pid *pid;
+	int ret = 0;
 	
 	read_lock(&fown->lock);
+	type = fown->pid_type;
 	pid = fown->pid;
 	if (!pid)
 		goto out_unlock_fown;
@@ -513,16 +543,9 @@
 	ret = 1;
 	
 	read_lock(&tasklist_lock);
-	if (pid > 0) {
-		p = find_task_by_pid(pid);
-		if (p) {
-			send_sigurg_to_task(p, fown);
-		}
-	} else {
-		do_each_task_pid(-pid, PIDTYPE_PGID, p) {
-			send_sigurg_to_task(p, fown);
-		} while_each_task_pid(-pid, PIDTYPE_PGID, p);
-	}
+	do_each_pid_task(pid, type, p) {
+		send_sigurg_to_task(p, fown);
+	} while_each_pid_task(pid, type, p);
 	read_unlock(&tasklist_lock);
  out_unlock_fown:
 	read_unlock(&fown->lock);
diff --git a/fs/file_table.c b/fs/file_table.c
index bc35a40..24f25a0 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -174,6 +174,7 @@
 	fops_put(file->f_op);
 	if (file->f_mode & FMODE_WRITE)
 		put_write_access(inode);
+	put_pid(file->f_owner.pid);
 	file_kill(file);
 	file->f_dentry = NULL;
 	file->f_vfsmnt = NULL;
diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c
index ae78306..1528a6f 100644
--- a/fs/hfsplus/part_tbl.c
+++ b/fs/hfsplus/part_tbl.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/hfs/part_tbl.c
+ * linux/fs/hfsplus/part_tbl.c
  *
  * Copyright (C) 1996-1997  Paul H. Hargrove
  * This file may be distributed under the terms of the GNU General Public License.
diff --git a/fs/inode.c b/fs/inode.c
index ada7643..bf6bec4 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -657,7 +657,7 @@
 	return inode;
 }
 
-static inline unsigned long hash(struct super_block *sb, unsigned long hashval)
+static unsigned long hash(struct super_block *sb, unsigned long hashval)
 {
 	unsigned long tmp;
 
@@ -1003,7 +1003,7 @@
 
 	list_del_init(&inode->i_list);
 	list_del_init(&inode->i_sb_list);
-	inode->i_state|=I_FREEING;
+	inode->i_state |= I_FREEING;
 	inodes_stat.nr_inodes--;
 	spin_unlock(&inode_lock);
 
@@ -1210,13 +1210,15 @@
 		return;
 
 	now = current_fs_time(inode->i_sb);
-	if (!timespec_equal(&inode->i_mtime, &now))
+	if (!timespec_equal(&inode->i_mtime, &now)) {
+		inode->i_mtime = now;
 		sync_it = 1;
-	inode->i_mtime = now;
+	}
 
-	if (!timespec_equal(&inode->i_ctime, &now))
+	if (!timespec_equal(&inode->i_ctime, &now)) {
+		inode->i_ctime = now;
 		sync_it = 1;
-	inode->i_ctime = now;
+	}
 
 	if (sync_it)
 		mark_inode_dirty_sync(inode);
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 32a8caf..10be512 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/commit.c
+ * linux/fs/jbd/commit.c
  *
  * Written by Stephen C. Tweedie <sct@redhat.com>, 1998
  *
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 7af6099..c518dd8 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/journal.c
+ * linux/fs/jbd/journal.c
  *
  * Written by Stephen C. Tweedie <sct@redhat.com>, 1998
  *
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index e228130..4d84bdc 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -5,16 +5,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -183,7 +183,7 @@
 		posix_acl_release(acl);
 	} else
 		inode->i_mode &= ~current->fs->umask;
-	
+
 	JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
 			       inode->i_mode;
 
diff --git a/fs/jfs/endian24.h b/fs/jfs/endian24.h
index ab7cd05..79494c4 100644
--- a/fs/jfs/endian24.h
+++ b/fs/jfs/endian24.h
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2001
+ *   Copyright (C) International Business Machines Corp., 2001
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 976e90d..34181b8 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -108,7 +108,7 @@
 	.aio_read	= generic_file_aio_read,
 	.aio_write	= generic_file_aio_write,
 	.mmap		= generic_file_mmap,
- 	.sendfile	= generic_file_sendfile,
+	.sendfile	= generic_file_sendfile,
 	.fsync		= jfs_fsync,
 	.release	= jfs_release,
 	.ioctl		= jfs_ioctl,
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index a8cc169..f571911 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -33,7 +33,7 @@
 
 void jfs_read_inode(struct inode *inode)
 {
-	if (diRead(inode)) { 
+	if (diRead(inode)) {
 		make_bad_inode(inode);
 		return;
 	}
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index a7629376..455fa42 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines  Corp., 2002
+ *   Copyright (C) International Business Machines  Corp., 2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_ACL
diff --git a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h
index 7f3e9ac..79c6180 100644
--- a/fs/jfs/jfs_btree.h
+++ b/fs/jfs/jfs_btree.h
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_BTREE
diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
index 81f0e51..9c5d596 100644
--- a/fs/jfs/jfs_debug.c
+++ b/fs/jfs/jfs_debug.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h
index 9f2572a..40b2011 100644
--- a/fs/jfs/jfs_dinode.h
+++ b/fs/jfs/jfs_dinode.h
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
+ *   Copyright (C) International Business Machines Corp., 2000-2001
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_DINODE
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index f05ebb6..23546c8 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -30,28 +30,28 @@
  *
  *	the working state of the block allocation map is accessed in
  *	two directions:
- *	
+ *
  *	1) allocation and free requests that start at the dmap
  *	   level and move up through the dmap control pages (i.e.
  *	   the vast majority of requests).
- * 
- * 	2) allocation requests that start at dmap control page
- *	   level and work down towards the dmaps.
- *	
- *	the serialization scheme used here is as follows. 
  *
- *	requests which start at the bottom are serialized against each 
- *	other through buffers and each requests holds onto its buffers 
- *	as it works it way up from a single dmap to the required level 
+ *	2) allocation requests that start at dmap control page
+ *	   level and work down towards the dmaps.
+ *
+ *	the serialization scheme used here is as follows.
+ *
+ *	requests which start at the bottom are serialized against each
+ *	other through buffers and each requests holds onto its buffers
+ *	as it works it way up from a single dmap to the required level
  *	of dmap control page.
  *	requests that start at the top are serialized against each other
  *	and request that start from the bottom by the multiple read/single
  *	write inode lock of the bmap inode. requests starting at the top
  *	take this lock in write mode while request starting at the bottom
  *	take the lock in read mode.  a single top-down request may proceed
- *	exclusively while multiple bottoms-up requests may proceed 
- * 	simultaneously (under the protection of busy buffers).
- *	
+ *	exclusively while multiple bottoms-up requests may proceed
+ *	simultaneously (under the protection of busy buffers).
+ *
  *	in addition to information found in dmaps and dmap control pages,
  *	the working state of the block allocation map also includes read/
  *	write information maintained in the bmap descriptor (i.e. total
@@ -59,7 +59,7 @@
  *	a single exclusive lock (BMAP_LOCK) is used to guard this information
  *	in the face of multiple-bottoms up requests.
  *	(lock ordering: IREAD_LOCK, BMAP_LOCK);
- *	
+ *
  *	accesses to the persistent state of the block allocation map (limited
  *	to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
  */
@@ -120,7 +120,7 @@
 /*
  *	buddy table
  *
- * table used for determining buddy sizes within characters of 
+ * table used for determining buddy sizes within characters of
  * dmap bitmap words.  the characters themselves serve as indexes
  * into the table, with the table elements yielding the maximum
  * binary buddy of free bits within the character.
@@ -146,7 +146,7 @@
 
 
 /*
- * NAME:    	dbMount()
+ * NAME:	dbMount()
  *
  * FUNCTION:	initializate the block allocation map.
  *
@@ -223,12 +223,12 @@
 
 
 /*
- * NAME:    	dbUnmount()
+ * NAME:	dbUnmount()
  *
  * FUNCTION:	terminate the block allocation map in preparation for
  *		file system unmount.
  *
- * 		the in-core bmap descriptor is written to disk and
+ *		the in-core bmap descriptor is written to disk and
  *		the memory for this descriptor is freed.
  *
  * PARAMETERS:
@@ -311,7 +311,7 @@
 
 
 /*
- * NAME:    	dbFree()
+ * NAME:	dbFree()
  *
  * FUNCTION:	free the specified block range from the working block
  *		allocation map.
@@ -397,7 +397,7 @@
  *
  * FUNCTION:    update the allocation state (free or allocate) of the
  *		specified block range in the persistent block allocation map.
- *		
+ *
  *		the blocks will be updated in the persistent map one
  *		dmap at a time.
  *
@@ -475,7 +475,7 @@
 		/* update the bits of the dmap words. the first and last
 		 * words may only have a subset of their bits updated. if
 		 * this is the case, we'll work against that word (i.e.
-		 * partial first and/or last) only in a single pass.  a 
+		 * partial first and/or last) only in a single pass.  a
 		 * single pass will also be used to update all words that
 		 * are to have all their bits updated.
 		 */
@@ -662,11 +662,11 @@
  *		the block allocation policy uses hints and a multi-step
  *		approach.
  *
- *	  	for allocation requests smaller than the number of blocks
+ *		for allocation requests smaller than the number of blocks
  *		per dmap, we first try to allocate the new blocks
  *		immediately following the hint.  if these blocks are not
  *		available, we try to allocate blocks near the hint.  if
- *		no blocks near the hint are available, we next try to 
+ *		no blocks near the hint are available, we next try to
  *		allocate within the same dmap as contains the hint.
  *
  *		if no blocks are available in the dmap or the allocation
@@ -713,7 +713,7 @@
 #endif				/* _STILL_TO_PORT */
 
 	/* get the log2 number of blocks to be allocated.
-	 * if the number of blocks is not a log2 multiple, 
+	 * if the number of blocks is not a log2 multiple,
 	 * it will be rounded up to the next log2 multiple.
 	 */
 	l2nb = BLKSTOL2(nblocks);
@@ -906,7 +906,7 @@
 	 * validate extent request:
 	 *
 	 * note: defragfs policy:
-	 *  max 64 blocks will be moved.  
+	 *  max 64 blocks will be moved.
 	 *  allocation request size must be satisfied from a single dmap.
 	 */
 	if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) {
@@ -1333,7 +1333,7 @@
  *		or two sub-trees, depending on the allocation group size.
  *		we search the top nodes of these subtrees left to right for
  *		sufficient free space.  if sufficient free space is found,
- *		the subtree is searched to find the leftmost leaf that 
+ *		the subtree is searched to find the leftmost leaf that
  *		has free space.  once we have made it to the leaf, we
  *		move the search to the next lower level dmap control page
  *		corresponding to this leaf.  we continue down the dmap control
@@ -1398,7 +1398,7 @@
 	 * that fully describes the allocation group since the allocation
 	 * group is already fully described by a dmap.  in this case, we
 	 * just call dbAllocCtl() to search the dmap tree and allocate the
-	 * required space if available.  
+	 * required space if available.
 	 *
 	 * if the allocation group is completely free, dbAllocCtl() is
 	 * also called to allocate the required space.  this is done for
@@ -1450,7 +1450,7 @@
 	    (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
 	ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
 
-	/* dmap control page trees fan-out by 4 and a single allocation 
+	/* dmap control page trees fan-out by 4 and a single allocation
 	 * group may be described by 1 or 2 subtrees within the ag level
 	 * dmap control page, depending upon the ag size. examine the ag's
 	 * subtrees for sufficient free space, starting with the leftmost
@@ -1633,7 +1633,7 @@
 
 	/* starting at the specified dmap control page level and block
 	 * number, search down the dmap control levels for the starting
-	 * block number of a dmap page that contains or starts off 
+	 * block number of a dmap page that contains or starts off
 	 * sufficient free blocks.
 	 */
 	for (lev = level, b = *blkno; lev >= 0; lev--) {
@@ -1677,7 +1677,7 @@
 		}
 
 		/* adjust the block number to reflect the location within
-		 * the dmap control page (i.e. the leaf) at which free 
+		 * the dmap control page (i.e. the leaf) at which free
 		 * space was found.
 		 */
 		b += (((s64) leafidx) << budmin);
@@ -1700,12 +1700,12 @@
  * NAME:	dbAllocCtl()
  *
  * FUNCTION:    attempt to allocate a specified number of contiguous
- *		blocks starting within a specific dmap.  
- *		
+ *		blocks starting within a specific dmap.
+ *
  *		this routine is called by higher level routines that search
  *		the dmap control pages above the actual dmaps for contiguous
  *		free space.  the result of successful searches by these
- * 		routines are the starting block numbers within dmaps, with
+ *		routines are the starting block numbers within dmaps, with
  *		the dmaps themselves containing the desired contiguous free
  *		space or starting a contiguous free space of desired size
  *		that is made up of the blocks of one or more dmaps. these
@@ -1872,14 +1872,14 @@
  *
  * FUNCTION:    attempt to allocate a specified number of contiguous blocks
  *		from a specified dmap.
- *		
+ *
  *		this routine checks if the contiguous blocks are available.
  *		if so, nblocks of blocks are allocated; otherwise, ENOSPC is
  *		returned.
  *
  * PARAMETERS:
  *      mp	-  pointer to bmap descriptor
- *      dp	-  pointer to dmap to attempt to allocate blocks from. 
+ *      dp	-  pointer to dmap to attempt to allocate blocks from.
  *      l2nb	-  log2 number of contiguous block desired.
  *      nblocks	-  actual number of contiguous block desired.
  *      results	-  on successful return, set to the starting block number
@@ -1890,7 +1890,7 @@
  *      -ENOSPC	- insufficient disk resources
  *      -EIO	- i/o error
  *
- * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or 
+ * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or
  *	IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
  */
 static int
@@ -2032,7 +2032,7 @@
 
 	/* root changed. bubble the change up to the dmap control pages.
 	 * if the adjustment of the upper level control pages fails,
-	 * backout the deallocation. 
+	 * backout the deallocation.
 	 */
 	if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 0, 0))) {
 		word = (blkno & (BPERDMAP - 1)) >> L2DBWORD;
@@ -2245,7 +2245,7 @@
 	 * words (i.e. partial first and/or last) on an individual basis
 	 * (a single pass), freeing the bits of interest by hand and updating
 	 * the leaf corresponding to the dmap word. a single pass will be used
-	 * for all dmap words fully contained within the specified range.  
+	 * for all dmap words fully contained within the specified range.
 	 * within this pass, the bits of all fully contained dmap words will
 	 * be marked as free in a single shot and the leaves will be updated. a
 	 * single leaf may describe the free space of multiple dmap words,
@@ -2267,7 +2267,7 @@
 		 */
 		if (nb < DBWORD) {
 			/* free (zero) the appropriate bits within this
-			 * dmap word. 
+			 * dmap word.
 			 */
 			dp->wmap[word] &=
 			    cpu_to_le32(~(ONES << (DBWORD - nb)
@@ -2327,7 +2327,7 @@
 
 	BMAP_LOCK(bmp);
 
-	/* update the free count for the allocation group and 
+	/* update the free count for the allocation group and
 	 * map.
 	 */
 	agno = blkno >> bmp->db_agl2size;
@@ -2378,7 +2378,7 @@
  *		or deallocation resulted in the root change.  this range
  *		is respresented by a single leaf of the current dmapctl
  *		and the leaf will be updated with this value, possibly
- *		causing a binary buddy system within the leaves to be 
+ *		causing a binary buddy system within the leaves to be
  *		split or joined.  the update may also cause the dmapctl's
  *		dmtree to be updated.
  *
@@ -2590,7 +2590,7 @@
 		}
 	}
 
-	/* adjust the dmap tree to reflect the specified leaf's new 
+	/* adjust the dmap tree to reflect the specified leaf's new
 	 * value.
 	 */
 	dbAdjTree(tp, leafno, newval);
@@ -2638,7 +2638,7 @@
 	/* the back split is accomplished by iteratively finding the leaf
 	 * that starts the buddy system that contains the specified leaf and
 	 * splitting that system in two.  this iteration continues until
-	 * the specified leaf becomes the start of a buddy system. 
+	 * the specified leaf becomes the start of a buddy system.
 	 *
 	 * determine maximum possible l2 size for the specified leaf.
 	 */
@@ -2853,7 +2853,7 @@
  * NAME:	dbFindLeaf()
  *
  * FUNCTION:    search a dmtree_t for sufficient free blocks, returning
- *		the index of a leaf describing the free blocks if 
+ *		the index of a leaf describing the free blocks if
  *		sufficient free blocks are found.
  *
  *		the search starts at the top of the dmtree_t tree and
@@ -2869,7 +2869,7 @@
  *
  * RETURN VALUES:
  *      0	- success
- *      -ENOSPC	- insufficient free blocks. 
+ *      -ENOSPC	- insufficient free blocks.
  */
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
 {
@@ -3090,7 +3090,7 @@
 
 
 /*
- * NAME:    	dbAllocBottomUp()
+ * NAME:	dbAllocBottomUp()
  *
  * FUNCTION:	alloc the specified block range from the working block
  *		allocation map.
@@ -3241,7 +3241,7 @@
 	BMAP_LOCK(bmp);
 
 	/* if this allocation group is completely free,
-	 * update the highest active allocation group number 
+	 * update the highest active allocation group number
 	 * if this allocation group is the new max.
 	 */
 	agno = blkno >> bmp->db_agl2size;
@@ -3273,7 +3273,7 @@
  * NAME:	dbExtendFS()
  *
  * FUNCTION:	extend bmap from blkno for nblocks;
- * 		dbExtendFS() updates bmap ready for dbAllocBottomUp();
+ *		dbExtendFS() updates bmap ready for dbAllocBottomUp();
  *
  * L2
  *  |
@@ -3284,7 +3284,7 @@
  *       d0,...,dn  d0,...,dn  d0,...,dn    d0,...,dn  d0,...,dn  d0,.,dm;
  * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm
  *
- * <---old---><----------------------------extend----------------------->   
+ * <---old---><----------------------------extend----------------------->
  */
 int dbExtendFS(struct inode *ipbmap, s64 blkno,	s64 nblocks)
 {
@@ -3330,7 +3330,7 @@
 	bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0;
 
 	/*
-	 *      reconfigure db_agfree[] 
+	 *      reconfigure db_agfree[]
 	 * from old AG configuration to new AG configuration;
 	 *
 	 * coalesce contiguous k (newAGSize/oldAGSize) AGs;
@@ -3491,7 +3491,7 @@
 			}	/* for each dmap in a L0 */
 
 			/*
-			 * build current L0 page from its leaves, and 
+			 * build current L0 page from its leaves, and
 			 * initialize corresponding parent L1 leaf
 			 */
 			*l1leaf = dbInitDmapCtl(l0dcp, 0, ++i);
@@ -3515,7 +3515,7 @@
 		}		/* for each L0 in a L1 */
 
 		/*
-		 * build current L1 page from its leaves, and 
+		 * build current L1 page from its leaves, and
 		 * initialize corresponding parent L2 leaf
 		 */
 		*l2leaf = dbInitDmapCtl(l1dcp, 1, ++j);
@@ -3570,7 +3570,7 @@
 	 *      finalize bmap control page
 	 */
 //finalize:
-	/* 
+	/*
 	 * compute db_agpref: preferred ag to allocate from
 	 * (the leftmost ag with average free space in it);
 	 */
@@ -3614,9 +3614,9 @@
 
 	/*
 	 * compute db_aglevel, db_agheigth, db_width, db_agstart:
-	 * an ag is covered in aglevel dmapctl summary tree, 
-	 * at agheight level height (from leaf) with agwidth number of nodes 
-	 * each, which starts at agstart index node of the smmary tree node 
+	 * an ag is covered in aglevel dmapctl summary tree,
+	 * at agheight level height (from leaf) with agwidth number of nodes
+	 * each, which starts at agstart index node of the smmary tree node
 	 * array;
 	 */
 	bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
@@ -3635,13 +3635,13 @@
 
 /*
  * NAME:	dbInitDmap()/ujfs_idmap_page()
- *                                                                    
+ *
  * FUNCTION:	initialize working/persistent bitmap of the dmap page
  *		for the specified number of blocks:
- *                                                                    
+ *
  *		at entry, the bitmaps had been initialized as free (ZEROS);
- *		The number of blocks will only account for the actually 
- *		existing blocks. Blocks which don't actually exist in 
+ *		The number of blocks will only account for the actually
+ *		existing blocks. Blocks which don't actually exist in
  *		the aggregate will be marked as allocated (ONES);
  *
  * PARAMETERS:
@@ -3677,7 +3677,7 @@
 
 	/*
 	 * free the bits corresponding to the block range (ZEROS):
-	 * note: not all bits of the first and last words may be contained 
+	 * note: not all bits of the first and last words may be contained
 	 * within the block range.
 	 */
 	for (r = nblocks; r > 0; r -= nb, blkno += nb) {
@@ -3709,7 +3709,7 @@
 	}
 
 	/*
-	 * mark bits following the range to be freed (non-existing 
+	 * mark bits following the range to be freed (non-existing
 	 * blocks) as allocated (ONES)
 	 */
 
@@ -3741,11 +3741,11 @@
 
 /*
  * NAME:	dbInitDmapTree()/ujfs_complete_dmap()
- *                                                                    
+ *
  * FUNCTION:	initialize summary tree of the specified dmap:
  *
  *		at entry, bitmap of the dmap has been initialized;
- *                                                                    
+ *
  * PARAMETERS:
  *	dp	- dmap to complete
  *	blkno	- starting block number for this dmap
@@ -3769,7 +3769,7 @@
 
 	/* init each leaf from corresponding wmap word:
 	 * note: leaf is set to NOFREE(-1) if all blocks of corresponding
-	 * bitmap word are allocated. 
+	 * bitmap word are allocated.
 	 */
 	cp = tp->stree + le32_to_cpu(tp->leafidx);
 	for (i = 0; i < LPERDMAP; i++)
@@ -3782,10 +3782,10 @@
 
 /*
  * NAME:	dbInitTree()/ujfs_adjtree()
- *                                                                    
+ *
  * FUNCTION:	initialize binary buddy summary tree of a dmap or dmapctl.
  *
- *		at entry, the leaves of the tree has been initialized 
+ *		at entry, the leaves of the tree has been initialized
  *		from corresponding bitmap word or root of summary tree
  *		of the child control page;
  *		configure binary buddy system at the leaf level, then
@@ -3813,15 +3813,15 @@
 	/*
 	 * configure the leaf levevl into binary buddy system
 	 *
-	 * Try to combine buddies starting with a buddy size of 1 
-	 * (i.e. two leaves). At a buddy size of 1 two buddy leaves 
-	 * can be combined if both buddies have a maximum free of l2min; 
-	 * the combination will result in the left-most buddy leaf having 
-	 * a maximum free of l2min+1.  
-	 * After processing all buddies for a given size, process buddies 
-	 * at the next higher buddy size (i.e. current size * 2) and 
-	 * the next maximum free (current free + 1).  
-	 * This continues until the maximum possible buddy combination 
+	 * Try to combine buddies starting with a buddy size of 1
+	 * (i.e. two leaves). At a buddy size of 1 two buddy leaves
+	 * can be combined if both buddies have a maximum free of l2min;
+	 * the combination will result in the left-most buddy leaf having
+	 * a maximum free of l2min+1.
+	 * After processing all buddies for a given size, process buddies
+	 * at the next higher buddy size (i.e. current size * 2) and
+	 * the next maximum free (current free + 1).
+	 * This continues until the maximum possible buddy combination
 	 * yields maximum free.
 	 */
 	for (l2free = dtp->budmin, bsize = 1; l2free < l2max;
@@ -3845,10 +3845,10 @@
 	 * bubble summary information of leaves up the tree.
 	 *
 	 * Starting at the leaf node level, the four nodes described by
-	 * the higher level parent node are compared for a maximum free and 
-	 * this maximum becomes the value of the parent node.  
-	 * when all lower level nodes are processed in this fashion then 
-	 * move up to the next level (parent becomes a lower level node) and 
+	 * the higher level parent node are compared for a maximum free and
+	 * this maximum becomes the value of the parent node.
+	 * when all lower level nodes are processed in this fashion then
+	 * move up to the next level (parent becomes a lower level node) and
 	 * continue the process for that level.
 	 */
 	for (child = le32_to_cpu(dtp->leafidx),
@@ -3857,7 +3857,7 @@
 		/* get index of 1st node of parent level */
 		parent = (child - 1) >> 2;
 
-		/* set the value of the parent node as the maximum 
+		/* set the value of the parent node as the maximum
 		 * of the four nodes of the current level.
 		 */
 		for (i = 0, cp = tp + child, cp1 = tp + parent;
@@ -3885,8 +3885,8 @@
 	dcp->budmin = L2BPERDMAP + L2LPERCTL * level;
 
 	/*
-	 * initialize the leaves of current level that were not covered 
-	 * by the specified input block range (i.e. the leaves have no 
+	 * initialize the leaves of current level that were not covered
+	 * by the specified input block range (i.e. the leaves have no
 	 * low level dmapctl or dmap).
 	 */
 	cp = &dcp->stree[CTLLEAFIND + i];
@@ -3900,9 +3900,9 @@
 
 /*
  * NAME:	dbGetL2AGSize()/ujfs_getagl2size()
- *                                                                    
+ *
  * FUNCTION:	Determine log2(allocation group size) from aggregate size
- *                                                                    
+ *
  * PARAMETERS:
  *	nblocks	- Number of blocks in aggregate
  *
@@ -3935,8 +3935,8 @@
 
 /*
  * NAME:	dbMapFileSizeToMapSize()
- *                                                                    
- * FUNCTION:	compute number of blocks the block allocation map file 
+ *
+ * FUNCTION:	compute number of blocks the block allocation map file
  *		can cover from the map file size;
  *
  * RETURNS:	Number of blocks which can be covered by this block map file;
@@ -3968,7 +3968,7 @@
 	npages = nblocks >> JFS_SBI(sb)->l2nbperpage;
 	level = BMAPPGTOLEV(npages);
 
-	/* At each level, accumulate the number of dmap pages covered by 
+	/* At each level, accumulate the number of dmap pages covered by
 	 * the number of full child levels below it;
 	 * repeat for the last incomplete child level.
 	 */
@@ -3990,7 +3990,7 @@
 		npages--;
 	}
 
-	/* convert the number of dmaps into the number of blocks 
+	/* convert the number of dmaps into the number of blocks
 	 * which can be covered by the dmaps;
 	 */
 	nblocks = ndmaps << L2BPERDMAP;
diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h
index 8b14cc8..45ea454 100644
--- a/fs/jfs/jfs_dmap.h
+++ b/fs/jfs/jfs_dmap.h
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_DMAP
@@ -27,7 +27,7 @@
 #define L2LPERDMAP	8	/* l2 number of leaves per dmap tree */
 #define	DBWORD		32	/* # of blks covered by a map word */
 #define	L2DBWORD	5	/* l2 # of blks covered by a mword */
-#define BUDMIN  	L2DBWORD	/* max free string in a map word */
+#define BUDMIN		L2DBWORD	/* max free string in a map word */
 #define BPERDMAP	(LPERDMAP * DBWORD)	/* num of blks per dmap */
 #define L2BPERDMAP	13	/* l2 num of blks per dmap */
 #define CTLTREESIZE	(1024+256+64+16+4+1)	/* size of a dmapctl tree */
@@ -57,7 +57,7 @@
 
 #define	MAXMAPSIZE	MAXL2SIZE	/* maximum aggregate map size */
 
-/* 
+/*
  * determine the maximum free string for four (lower level) nodes
  * of the tree.
  */
@@ -122,7 +122,7 @@
 #define BLKTOCTL(b,s,l)   \
         (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
 
-/* 
+/*
  * convert aggregate map size to the zero origin dmapctl level of the
  * top dmapctl.
  */
@@ -192,13 +192,13 @@
 
 /* macros for accessing fields within dmtree */
 #define	dmt_nleafs	t1.nleafs
-#define	dmt_l2nleafs 	t1.l2nleafs
-#define	dmt_leafidx 	t1.leafidx
-#define	dmt_height 	t1.height
-#define	dmt_budmin 	t1.budmin
-#define	dmt_stree 	t1.stree
+#define	dmt_l2nleafs	t1.l2nleafs
+#define	dmt_leafidx	t1.leafidx
+#define	dmt_height	t1.height
+#define	dmt_budmin	t1.budmin
+#define	dmt_stree	t1.stree
 
-/* 
+/*
  *	on-disk aggregate disk allocation map descriptor.
  */
 struct dbmap_disk {
@@ -237,7 +237,7 @@
 	s64 dn_agsize;		/* num of blks per alloc group       */
 	signed char dn_maxfreebud;	/* max free buddy system             */
 };				/* - 4096 -                             */
-/* 
+/*
  *	in-memory aggregate disk allocation map descriptor.
  */
 struct bmap {
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 6c3f083..ecb2216 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -78,7 +78,7 @@
  *
  * case-insensitive search:
  *
- * 	fold search key;
+ *	fold search key;
  *
  *	case-insensitive search of B-tree:
  *	for internal entry, router key is already folded;
@@ -93,7 +93,7 @@
  *	else
  *		return no match;
  *
- * 	serialization:
+ *	serialization:
  * target directory inode lock is being held on entry/exit
  * of all main directory service routines.
  *
@@ -925,7 +925,7 @@
  *
  * return: 0 - success;
  *	   errno - failure;
- * 	leaf page unpinned;
+ *	leaf page unpinned;
  */
 static int dtSplitUp(tid_t tid,
 	  struct inode *ip, struct dtsplit * split, struct btstack * btstack)
@@ -3767,7 +3767,7 @@
  *	     across page boundary
  *
  * return: non-zero on error
- *	
+ *
  */
 static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
 			       int ri, struct component_name * key, int flag)
@@ -3780,13 +3780,13 @@
 	lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
 					GFP_KERNEL);
 	if (lkey.name == NULL)
-		return -ENOSPC;
+		return -ENOMEM;
 
 	rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
 					GFP_KERNEL);
 	if (rkey.name == NULL) {
 		kfree(lkey.name);
-		return -ENOSPC;
+		return -ENOMEM;
 	}
 
 	/* get left and right key */
diff --git a/fs/jfs/jfs_dtree.h b/fs/jfs/jfs_dtree.h
index 13e4fdf..af8513f 100644
--- a/fs/jfs/jfs_dtree.h
+++ b/fs/jfs/jfs_dtree.h
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_DTREE
@@ -80,7 +80,7 @@
 /*
  *	leaf node entry head/only segment
  *
- * 	For legacy filesystems, name contains 13 wchars -- no index field
+ *	For legacy filesystems, name contains 13 wchars -- no index field
  */
 struct ldtentry {
 	__le32 inumber;		/* 4: 4-byte aligned */
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index 933b745..a35bdca 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -125,7 +125,7 @@
 	}
 
 	/* allocate the disk blocks for the extent.  initially, extBalloc()
-	 * will try to allocate disk blocks for the requested size (xlen). 
+	 * will try to allocate disk blocks for the requested size (xlen).
 	 * if this fails (xlen contiguous free blocks not avaliable), it'll
 	 * try to allocate a smaller number of blocks (producing a smaller
 	 * extent), with this smaller number of blocks consisting of the
@@ -150,7 +150,7 @@
 	/* determine the value of the extent flag */
 	xflag = abnr ? XAD_NOTRECORDED : 0;
 
-	/* if we can extend the hint extent to cover the current request, 
+	/* if we can extend the hint extent to cover the current request,
 	 * extend it.  otherwise, insert a new extent to
 	 * cover the current request.
 	 */
@@ -159,7 +159,7 @@
 	else
 		rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
 
-	/* if the extend or insert failed, 
+	/* if the extend or insert failed,
 	 * free the newly allocated blocks and return the error.
 	 */
 	if (rc) {
@@ -235,7 +235,7 @@
 	xoff = offsetXAD(xp);
 
 	/* if the extend page is abnr and if the request is for
-	 * the extent to be allocated and recorded, 
+	 * the extent to be allocated and recorded,
 	 * make the page allocated and recorded.
 	 */
 	if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
@@ -397,7 +397,7 @@
 	if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
 		return (rc);
 
-	/* check if not extent exists for the previous page.  
+	/* check if not extent exists for the previous page.
 	 * this is possible for sparse files.
 	 */
 	if (xadl.nxad == 0) {
@@ -410,7 +410,7 @@
 	 */
 	xp->flag &= XAD_NOTRECORDED;
 
-        if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {          
+        if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
 		jfs_error(ip->i_sb, "extHint: corrupt xtree");
 		return -EIO;
         }
@@ -492,7 +492,7 @@
  * FUNCTION:    allocate disk blocks to form an extent.
  *
  *		initially, we will try to allocate disk blocks for the
- *		requested size (nblocks).  if this fails (nblocks 
+ *		requested size (nblocks).  if this fails (nblocks
  *		contiguous free blocks not avaliable), we'll try to allocate
  *		a smaller number of blocks (producing a smaller extent), with
  *		this smaller number of blocks consisting of the requested
@@ -500,7 +500,7 @@
  *		number (i.e. 16 -> 8).  we'll continue to round down and
  *		retry the allocation until the number of blocks to allocate
  *		is smaller than the number of blocks per page.
- *		
+ *
  * PARAMETERS:
  *	ip	 - the inode of the file.
  *	hint	 - disk block number to be used as an allocation hint.
@@ -509,7 +509,7 @@
  *		   exit, this value is set to the number of blocks actually
  *		   allocated.
  *	blkno	 - pointer to a block address that is filled in on successful
- *		   return with the starting block number of the newly 
+ *		   return with the starting block number of the newly
  *		   allocated block range.
  *
  * RETURN VALUES:
@@ -530,7 +530,7 @@
 	/* get the number of blocks to initially attempt to allocate.
 	 * we'll first try the number of blocks requested unless this
 	 * number is greater than the maximum number of contiguous free
-	 * blocks in the map. in that case, we'll start off with the 
+	 * blocks in the map. in that case, we'll start off with the
 	 * maximum free.
 	 */
 	max = (s64) 1 << bmp->db_maxfreebud;
@@ -582,19 +582,19 @@
  *
  * FUNCTION:    attempt to extend an extent's allocation.
  *
- *		initially, we will try to extend the extent's allocation
- *		in place.  if this fails, we'll try to move the extent
- *		to a new set of blocks. if moving the extent, we initially
+ *		Initially, we will try to extend the extent's allocation
+ *		in place.  If this fails, we'll try to move the extent
+ *		to a new set of blocks.  If moving the extent, we initially
  *		will try to allocate disk blocks for the requested size
- *		(nnew).  if this fails 	(new contiguous free blocks not
- *		avaliable), we'll try  to allocate a smaller number of
+ *		(newnblks).  if this fails (new contiguous free blocks not
+ *		avaliable), we'll try to allocate a smaller number of
  *		blocks (producing a smaller extent), with this smaller
  *		number of blocks consisting of the requested number of
  *		blocks rounded down to the next smaller power of 2
- *		number (i.e. 16 -> 8).  we'll continue to round down and
+ *		number (i.e. 16 -> 8).  We'll continue to round down and
  *		retry the allocation until the number of blocks to allocate
  *		is smaller than the number of blocks per page.
- *		
+ *
  * PARAMETERS:
  *	ip	 - the inode of the file.
  *	blkno    - starting block number of the extents current allocation.
@@ -625,7 +625,7 @@
 			return (rc);
 	}
 
-	/* in place extension not possible.  
+	/* in place extension not possible.
 	 * try to move the extent to a new set of blocks.
 	 */
 	return (extBalloc(ip, blkno, newnblks, newblkno));
diff --git a/fs/jfs/jfs_extent.h b/fs/jfs/jfs_extent.h
index 3a7f3f2..b567e12 100644
--- a/fs/jfs/jfs_extent.h
+++ b/fs/jfs/jfs_extent.h
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
+ *   Copyright (C) International Business Machines Corp., 2000-2001
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_EXTENT
diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h
index 72a5588..9901928 100644
--- a/fs/jfs/jfs_filsys.h
+++ b/fs/jfs/jfs_filsys.h
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_FILSYS
@@ -21,9 +21,9 @@
 /*
  *	jfs_filsys.h
  *
- * file system (implementation-dependent) constants 
+ * file system (implementation-dependent) constants
  *
- * refer to <limits.h> for system wide implementation-dependent constants 
+ * refer to <limits.h> for system wide implementation-dependent constants
  */
 
 /*
@@ -49,7 +49,7 @@
 
 #define JFS_DFS		0x20000000	/* DCE DFS LFS support */
 
-#define JFS_LINUX      	0x10000000	/* Linux support */
+#define JFS_LINUX	0x10000000	/* Linux support */
 /*	case-sensitive name/directory support */
 
 /* directory option */
@@ -59,7 +59,7 @@
 #define	JFS_COMMIT	0x00000f00	/* commit option mask */
 #define	JFS_GROUPCOMMIT	0x00000100	/* group (of 1) commit */
 #define	JFS_LAZYCOMMIT	0x00000200	/* lazy commit */
-#define	JFS_TMPFS	0x00000400	/* temporary file system - 
+#define	JFS_TMPFS	0x00000400	/* temporary file system -
 					 * do not log/commit:
 					 */
 
@@ -196,7 +196,7 @@
 					 * followed by 1st extent of map
 					 */
 #define AITBL_OFF	(AIMAP_OFF + (SIZE_OF_MAP_PAGE << 1))
-					/* 
+					/*
 					 * 1st extent of aggregate inode table
 					 */
 #define SUPER2_OFF	(AITBL_OFF + INODE_EXTENT_SIZE)
@@ -270,13 +270,13 @@
  */
 #define FM_CLEAN 0x00000000	/* file system is unmounted and clean */
 #define FM_MOUNT 0x00000001	/* file system is mounted cleanly */
-#define FM_DIRTY 0x00000002	/* file system was not unmounted and clean 
-				 * when mounted or 
+#define FM_DIRTY 0x00000002	/* file system was not unmounted and clean
+				 * when mounted or
 				 * commit failure occurred while being mounted:
-				 * fsck() must be run to repair 
+				 * fsck() must be run to repair
 				 */
 #define	FM_LOGREDO 0x00000004	/* log based recovery (logredo()) failed:
-				 * fsck() must be run to repair 
+				 * fsck() must be run to repair
 				 */
 #define	FM_EXTENDFS 0x00000008	/* file system extendfs() in progress */
 
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index a45ee24..489a3d6 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -98,7 +98,7 @@
  * FUNCTION:    initialize the incore inode map control structures for
  *		a fileset or aggregate init time.
  *
- *              the inode map's control structure (dinomap) is 
+ *              the inode map's control structure (dinomap) is
  *              brought in from disk and placed in virtual memory.
  *
  * PARAMETERS:
@@ -107,7 +107,7 @@
  * RETURN VALUES:
  *      0       - success
  *      -ENOMEM  - insufficient free virtual memory.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 int diMount(struct inode *ipimap)
 {
@@ -191,7 +191,7 @@
  * RETURN VALUES:
  *      0       - success
  *      -ENOMEM  - insufficient free virtual memory.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 int diUnmount(struct inode *ipimap, int mounterror)
 {
@@ -281,7 +281,7 @@
  *		on entry, the specifed incore inode should itself
  *		specify the disk inode number corresponding to the
  *		incore inode (i.e. i_number should be initialized).
- *		
+ *
  *		this routine handles incore inode initialization for
  *		both "special" and "regular" inodes.  special inodes
  *		are those required early in the mount process and
@@ -289,7 +289,7 @@
  *		is not yet initialized.  these "special" inodes are
  *		identified by a NULL inode map inode pointer and are
  *		actually initialized by a call to diReadSpecial().
- *		
+ *
  *		for regular inodes, the iag describing the disk inode
  *		is read from disk to determine the inode extent address
  *		for the disk inode.  with the inode extent address in
@@ -302,9 +302,9 @@
  *
  * RETURN VALUES:
  *      0       - success
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  *      -ENOMEM	- insufficient memory
- *      
+ *
  */
 int diRead(struct inode *ip)
 {
@@ -586,14 +586,14 @@
  *		page of the extent that contains the disk inode is
  *		read and the disk inode portion of the incore inode
  *		is copied to the disk inode.
- *		
+ *
  * PARAMETERS:
  *	tid -  transacation id
  *      ip  -  pointer to incore inode to be written to the inode extent.
  *
  * RETURN VALUES:
  *      0       - success
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 int diWrite(tid_t tid, struct inode *ip)
 {
@@ -676,11 +676,11 @@
 	 * copy btree root from in-memory inode to on-disk inode
 	 *
 	 * (tlock is taken from inline B+-tree root in in-memory
-	 * inode when the B+-tree root is updated, which is pointed 
+	 * inode when the B+-tree root is updated, which is pointed
 	 * by jfs_ip->blid as well as being on tx tlock list)
 	 *
-	 * further processing of btree root is based on the copy 
-	 * in in-memory inode, where txLog() will log from, and, 
+	 * further processing of btree root is based on the copy
+	 * in in-memory inode, where txLog() will log from, and,
 	 * for xtree root, txUpdateMap() will update map and reset
 	 * XAD_NEW bit;
 	 */
@@ -824,7 +824,7 @@
 		memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd));
 #endif				/*  _JFS_FASTDASD */
 
-	/* release the buffer holding the updated on-disk inode. 
+	/* release the buffer holding the updated on-disk inode.
 	 * the buffer will be later written by commit processing.
 	 */
 	write_metapage(mp);
@@ -842,7 +842,7 @@
  *		if the inode to be freed represents the first (only)
  *		free inode within the iag, the iag will be placed on
  *		the ag free inode list.
- *	
+ *
  *		freeing the inode will cause the inode extent to be
  *		freed if the inode is the only allocated inode within
  *		the extent.  in this case all the disk resource backing
@@ -865,11 +865,11 @@
  *		any updates and are held until all updates are complete.
  *
  * PARAMETERS:
- *      ip  	- inode to be freed.
+ *      ip	- inode to be freed.
  *
  * RETURN VALUES:
  *      0       - success
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 int diFree(struct inode *ip)
 {
@@ -898,7 +898,7 @@
 	 */
 	iagno = INOTOIAG(inum);
 
-	/* make sure that the iag is contained within 
+	/* make sure that the iag is contained within
 	 * the map.
 	 */
 	if (iagno >= imap->im_nextiag) {
@@ -1013,7 +1013,7 @@
 
 		/* update the free inode summary map for the extent if
 		 * freeing the inode means the extent will now have free
-		 * inodes (i.e., the inode being freed is the first free 
+		 * inodes (i.e., the inode being freed is the first free
 		 * inode of extent),
 		 */
 		if (iagp->wmap[extno] == cpu_to_le32(ONES)) {
@@ -1204,9 +1204,9 @@
 		iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
 	}
 
-	/* update the inode extent address and working map 
+	/* update the inode extent address and working map
 	 * to reflect the free extent.
-	 * the permanent map should have been updated already 
+	 * the permanent map should have been updated already
 	 * for the inode being freed.
 	 */
 	if (iagp->pmap[extno] != 0) {
@@ -1218,7 +1218,7 @@
 
 	/* update the free extent and free inode summary maps
 	 * to reflect the freed extent.
-	 * the inode summary map is marked to indicate no inodes 
+	 * the inode summary map is marked to indicate no inodes
 	 * available for the freed extent.
 	 */
 	sword = extno >> L2EXTSPERSUM;
@@ -1255,17 +1255,17 @@
 	 * start transaction to update block allocation map
 	 * for the inode extent freed;
 	 *
-	 * N.B. AG_LOCK is released and iag will be released below, and 
+	 * N.B. AG_LOCK is released and iag will be released below, and
 	 * other thread may allocate inode from/reusing the ixad freed
-	 * BUT with new/different backing inode extent from the extent 
-	 * to be freed by the transaction;  
+	 * BUT with new/different backing inode extent from the extent
+	 * to be freed by the transaction;
 	 */
 	tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
 	mutex_lock(&JFS_IP(ipimap)->commit_mutex);
 
-	/* acquire tlock of the iag page of the freed ixad 
+	/* acquire tlock of the iag page of the freed ixad
 	 * to force the page NOHOMEOK (even though no data is
-	 * logged from the iag page) until NOREDOPAGE|FREEXTENT log 
+	 * logged from the iag page) until NOREDOPAGE|FREEXTENT log
 	 * for the free of the extent is committed;
 	 * write FREEXTENT|NOREDOPAGE log record
 	 * N.B. linelock is overlaid as freed extent descriptor;
@@ -1284,8 +1284,8 @@
 	 * logredo needs the IAG number and IAG extent index in order
 	 * to ensure that the IMap is consistent.  The least disruptive
 	 * way to pass these values through  to the transaction manager
-	 * is in the iplist array.  
-	 * 
+	 * is in the iplist array.
+	 *
 	 * It's not pretty, but it works.
 	 */
 	iplist[1] = (struct inode *) (size_t)iagno;
@@ -1340,18 +1340,18 @@
 /*
  * NAME:        diAlloc(pip,dir,ip)
  *
- * FUNCTION:    allocate a disk inode from the inode working map 
+ * FUNCTION:    allocate a disk inode from the inode working map
  *		for a fileset or aggregate.
  *
  * PARAMETERS:
- *      pip  	- pointer to incore inode for the parent inode.
- *      dir  	- 'true' if the new disk inode is for a directory.
- *      ip  	- pointer to a new inode
+ *      pip	- pointer to incore inode for the parent inode.
+ *      dir	- 'true' if the new disk inode is for a directory.
+ *      ip	- pointer to a new inode
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 int diAlloc(struct inode *pip, bool dir, struct inode *ip)
 {
@@ -1372,7 +1372,7 @@
 	JFS_IP(ip)->ipimap = ipimap;
 	JFS_IP(ip)->fileset = FILESYSTEM_I;
 
-	/* for a directory, the allocation policy is to start 
+	/* for a directory, the allocation policy is to start
 	 * at the ag level using the preferred ag.
 	 */
 	if (dir) {
@@ -1435,7 +1435,7 @@
 	/*
 	 *      try to allocate from the IAG
 	 */
-	/* check if the inode may be allocated from the iag 
+	/* check if the inode may be allocated from the iag
 	 * (i.e. the inode has free inodes or new extent can be added).
 	 */
 	if (iagp->nfreeinos || addext) {
@@ -1490,7 +1490,7 @@
 		 * hint or, if appropriate (i.e. addext is true), allocate
 		 * an extent of free inodes at or following the extent
 		 * containing the hint.
-		 * 
+		 *
 		 * the free inode and free extent summary maps are used
 		 * here, so determine the starting summary map position
 		 * and the number of words we'll have to examine.  again,
@@ -1641,7 +1641,7 @@
  *		inodes should be added for the allocation group, with
  *		the current request satisfied from this extent. if this
  *		is the case, an attempt will be made to do just that.  if
- *		this attempt fails or it has been determined that a new 
+ *		this attempt fails or it has been determined that a new
  *		extent should not be added, an attempt is made to satisfy
  *		the request by allocating an existing (backed) free inode
  *		from the allocation group.
@@ -1649,24 +1649,24 @@
  * PRE CONDITION: Already have the AG lock for this AG.
  *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      agno  	- allocation group to allocate from.
- *      dir  	- 'true' if the new disk inode is for a directory.
- *      ip  	- pointer to the new inode to be filled in on successful return
+ *      imap	- pointer to inode map control structure.
+ *      agno	- allocation group to allocate from.
+ *      dir	- 'true' if the new disk inode is for a directory.
+ *      ip	- pointer to the new inode to be filled in on successful return
  *		  with the disk inode number allocated, its extent address
  *		  and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 static int
 diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
 {
 	int rc, addext, numfree, numinos;
 
-	/* get the number of free and the number of backed disk 
+	/* get the number of free and the number of backed disk
 	 * inodes currently within the ag.
 	 */
 	numfree = imap->im_agctl[agno].numfree;
@@ -1719,17 +1719,17 @@
  *		specified primary group.
  *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      agno  	- primary allocation group (to avoid).
- *      dir  	- 'true' if the new disk inode is for a directory.
- *      ip  	- pointer to a new inode to be filled in on successful return
+ *      imap	- pointer to inode map control structure.
+ *      agno	- primary allocation group (to avoid).
+ *      dir	- 'true' if the new disk inode is for a directory.
+ *      ip	- pointer to a new inode to be filled in on successful return
  *		  with the disk inode number allocated, its extent address
  *		  and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 static int
 diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
@@ -1738,7 +1738,7 @@
 	int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
 
 
-	/* try to allocate from the ags following agno up to 
+	/* try to allocate from the ags following agno up to
 	 * the maximum ag number.
 	 */
 	for (ag = agno + 1; ag <= maxag; ag++) {
@@ -1780,21 +1780,21 @@
  *
  *		allocation occurs from the first iag on the list using
  *		the iag's free inode summary map to find the leftmost
- *		free inode in the iag. 
- *		
+ *		free inode in the iag.
+ *
  * PRE CONDITION: Already have AG lock for this AG.
- *		
+ *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      agno  	- allocation group.
- *      ip  	- pointer to new inode to be filled in on successful return
+ *      imap	- pointer to inode map control structure.
+ *      agno	- allocation group.
+ *      ip	- pointer to new inode to be filled in on successful return
  *		  with the disk inode number allocated, its extent address
  *		  and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
 {
@@ -1867,7 +1867,7 @@
 		return -EIO;
 	}
 
-	/* compute the inode number within the iag. 
+	/* compute the inode number within the iag.
 	 */
 	ino = (extno << L2INOSPEREXT) + rem;
 
@@ -1892,17 +1892,17 @@
 /*
  * NAME:        diAllocExt(imap,agno,ip)
  *
- * FUNCTION:   	add a new extent of free inodes to an iag, allocating
- *	       	an inode from this extent to satisfy the current allocation
- *	       	request.
- *		
+ * FUNCTION:	add a new extent of free inodes to an iag, allocating
+ *		an inode from this extent to satisfy the current allocation
+ *		request.
+ *
  *		this routine first tries to find an existing iag with free
  *		extents through the ag free extent list.  if list is not
  *		empty, the head of the list will be selected as the home
  *		of the new extent of free inodes.  otherwise (the list is
  *		empty), a new iag will be allocated for the ag to contain
  *		the extent.
- *		
+ *
  *		once an iag has been selected, the free extent summary map
  *		is used to locate a free extent within the iag and diNewExt()
  *		is called to initialize the extent, with initialization
@@ -1910,16 +1910,16 @@
  *		for the purpose of satisfying this request.
  *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      agno  	- allocation group number.
- *      ip  	- pointer to new inode to be filled in on successful return
+ *      imap	- pointer to inode map control structure.
+ *      agno	- allocation group number.
+ *      ip	- pointer to new inode to be filled in on successful return
  *		  with the disk inode number allocated, its extent address
  *		  and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
 {
@@ -2012,7 +2012,7 @@
 /*
  * NAME:        diAllocBit(imap,iagp,ino)
  *
- * FUNCTION:   	allocate a backed inode from an iag.
+ * FUNCTION:	allocate a backed inode from an iag.
  *
  *		this routine performs the mechanics of allocating a
  *		specified inode from a backed extent.
@@ -2025,19 +2025,19 @@
  *		in the face of updates to multiple buffers.  under this
  *		approach, all required buffers are obtained before making
  *		any updates and are held all are updates are complete.
- *		
+ *
  * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
  *	this AG.  Must have read lock on imap inode.
  *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      iagp  	- pointer to iag. 
- *      ino   	- inode number to be allocated within the iag.
+ *      imap	- pointer to inode map control structure.
+ *      iagp	- pointer to iag.
+ *      ino	- inode number to be allocated within the iag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
 {
@@ -2172,19 +2172,19 @@
  *		buffers.  under this approach, all required buffers are
  *		obtained before making any updates and are held until all
  *		updates are complete.
- *		
+ *
  * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
  *	this AG.  Must have read lock on imap inode.
  *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      iagp  	- pointer to iag. 
- *      extno  	- extent number.
+ *      imap	- pointer to inode map control structure.
+ *      iagp	- pointer to iag.
+ *      extno	- extent number.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
 {
@@ -2432,34 +2432,34 @@
 /*
  * NAME:        diNewIAG(imap,iagnop,agno)
  *
- * FUNCTION:   	allocate a new iag for an allocation group.
- *		
- *		first tries to allocate the iag from the inode map 
- *		iagfree list:  
- *		if the list has free iags, the head of the list is removed 
+ * FUNCTION:	allocate a new iag for an allocation group.
+ *
+ *		first tries to allocate the iag from the inode map
+ *		iagfree list:
+ *		if the list has free iags, the head of the list is removed
  *		and returned to satisfy the request.
  *		if the inode map's iag free list is empty, the inode map
  *		is extended to hold a new iag. this new iag is initialized
  *		and returned to satisfy the request.
  *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      iagnop 	- pointer to an iag number set with the number of the
+ *      imap	- pointer to inode map control structure.
+ *      iagnop	- pointer to an iag number set with the number of the
  *		  newly allocated iag upon successful return.
- *      agno  	- allocation group number.
+ *      agno	- allocation group number.
  *	bpp	- Buffer pointer to be filled in with new IAG's buffer
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC	- insufficient disk resources.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  *
- * serialization: 
+ * serialization:
  *	AG lock held on entry/exit;
  *	write lock on the map is held inside;
  *	read lock on the map is held on successful completion;
  *
- * note: new iag transaction: 
+ * note: new iag transaction:
  * . synchronously write iag;
  * . write log of xtree and inode  of imap;
  * . commit;
@@ -2494,7 +2494,7 @@
 	/* acquire the free iag lock */
 	IAGFREE_LOCK(imap);
 
-	/* if there are any iags on the inode map free iag list, 
+	/* if there are any iags on the inode map free iag list,
 	 * allocate the iag from the head of the list.
 	 */
 	if (imap->im_freeiag >= 0) {
@@ -2618,8 +2618,8 @@
 		flush_metapage(mp);
 
 		/*
-		 * txCommit(COMMIT_FORCE) will synchronously write address 
-		 * index pages and inode after commit in careful update order 
+		 * txCommit(COMMIT_FORCE) will synchronously write address
+		 * index pages and inode after commit in careful update order
 		 * of address index pages (right to left, bottom up);
 		 */
 		iplist[0] = ipimap;
@@ -2678,11 +2678,11 @@
  *
  * FUNCTION:    get the buffer for the specified iag within a fileset
  *		or aggregate inode map.
- *		
+ *
  * PARAMETERS:
- *      imap  	- pointer to inode map control structure.
- *      iagno  	- iag number.
- *      bpp  	- point to buffer pointer to be filled in on successful
+ *      imap	- pointer to inode map control structure.
+ *      iagno	- iag number.
+ *      bpp	- point to buffer pointer to be filled in on successful
  *		  exit.
  *
  * SERIALIZATION:
@@ -2692,7 +2692,7 @@
  *
  * RETURN VALUES:
  *      0       - success.
- *      -EIO  	- i/o error.
+ *      -EIO	- i/o error.
  */
 static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
 {
@@ -2718,8 +2718,8 @@
  *		the specified bit position.
  *
  * PARAMETERS:
- *      word  	- word to be examined.
- *      start  	- starting bit position.
+ *      word	- word to be examined.
+ *      start	- starting bit position.
  *
  * RETURN VALUES:
  *      bit position of first free bit in the word or 32 if
@@ -2740,10 +2740,10 @@
 
 /*
  * NAME:	diUpdatePMap()
- *                                                                    
- * FUNCTION: Update the persistent map in an IAG for the allocation or 
+ *
+ * FUNCTION: Update the persistent map in an IAG for the allocation or
  *	freeing of the specified inode.
- *                                                                    
+ *
  * PRE CONDITIONS: Working map has already been updated for allocate.
  *
  * PARAMETERS:
@@ -2752,7 +2752,7 @@
  *	is_free	- If 'true' indicates inode should be marked freed, otherwise
  *		  indicates inode should be marked allocated.
  *
- * RETURN VALUES: 
+ * RETURN VALUES:
  *		0 for success
  */
 int
@@ -2793,7 +2793,7 @@
 	extno = ino >> L2INOSPEREXT;
 	bitno = ino & (INOSPEREXT - 1);
 	mask = HIGHORDER >> bitno;
-	/* 
+	/*
 	 * mark the inode free in persistent map:
 	 */
 	if (is_free) {
@@ -2803,7 +2803,7 @@
 		 * of last reference release;
 		 */
 		if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
-			jfs_error(ipimap->i_sb, 
+			jfs_error(ipimap->i_sb,
 				  "diUpdatePMap: inode %ld not marked as "
 				  "allocated in wmap!", inum);
 		}
@@ -2877,8 +2877,8 @@
  *	diExtendFS()
  *
  * function: update imap for extendfs();
- * 
- * note: AG size has been increased s.t. each k old contiguous AGs are 
+ *
+ * note: AG size has been increased s.t. each k old contiguous AGs are
  * coalesced into a new AG;
  */
 int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
@@ -2897,7 +2897,7 @@
 		   atomic_read(&imap->im_numfree));
 
 	/*
-	 *      reconstruct imap 
+	 *      reconstruct imap
 	 *
 	 * coalesce contiguous k (newAGSize/oldAGSize) AGs;
 	 * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
@@ -2931,7 +2931,7 @@
 		}
 
 		/* leave free iag in the free iag list */
-		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {  
+		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
 		        release_metapage(bp);
 			continue;
 		}
diff --git a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h
index e3b7db4..4f9c346 100644
--- a/fs/jfs/jfs_imap.h
+++ b/fs/jfs/jfs_imap.h
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_IMAP
@@ -45,13 +45,13 @@
 /* get the starting block number of the 4K page of an inode extent
  * that contains ino.
  */
-#define INOPBLK(pxd,ino,l2nbperpg)    	(addressPXD((pxd)) +		\
+#define INOPBLK(pxd,ino,l2nbperpg)	(addressPXD((pxd)) +		\
 	((((ino) & (INOSPEREXT-1)) >> L2INOSPERPAGE) << (l2nbperpg)))
 
 /*
  *	inode allocation map:
- * 
- * inode allocation map consists of 
+ *
+ * inode allocation map consists of
  * . the inode map control page and
  * . inode allocation group pages (per 4096 inodes)
  * which are addressed by standard JFS xtree.
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index 54d7371..9400558 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -4,18 +4,18 @@
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */ 
+ */
 #ifndef _H_JFS_INCORE
 #define _H_JFS_INCORE
 
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index bffaca9..4c67ed9 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -61,7 +61,7 @@
 	inode = new_inode(sb);
 	if (!inode) {
 		jfs_warn("ialloc: new_inode returned NULL!");
-		return inode;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	jfs_inode = JFS_IP(inode);
@@ -69,9 +69,10 @@
 	rc = diAlloc(parent, S_ISDIR(mode), inode);
 	if (rc) {
 		jfs_warn("ialloc: diAlloc returned %d!", rc);
-		make_bad_inode(inode);
+		if (rc == -EIO)
+			make_bad_inode(inode);
 		iput(inode);
-		return NULL;
+		return ERR_PTR(rc);
 	}
 
 	inode->i_uid = current->fsuid;
@@ -97,7 +98,7 @@
 		inode->i_flags |= S_NOQUOTA;
 		inode->i_nlink = 0;
 		iput(inode);
-		return NULL;
+		return ERR_PTR(-EDQUOT);
 	}
 
 	inode->i_mode = mode;
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 1fc48df..0d06ccf 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_INODE
diff --git a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h
index 70ac9f7..7d78e83 100644
--- a/fs/jfs/jfs_lock.h
+++ b/fs/jfs/jfs_lock.h
@@ -1,19 +1,19 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2001
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_LOCK
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 3315f0b..b89c9ab 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -337,7 +337,7 @@
  * PARAMETER:	cd	- commit descriptor
  *
  * RETURN:	end-of-log address
- *			
+ *
  * serialization: LOG_LOCK() held on entry/exit
  */
 static int
@@ -554,7 +554,7 @@
  * PARAMETER:	log
  *
  * RETURN:	0
- *			
+ *
  * serialization: LOG_LOCK() held on entry/exit
  */
 static int lmNextPage(struct jfs_log * log)
@@ -656,7 +656,7 @@
  *	page number - redrive pageout of the page at the head of
  *	pageout queue until full page has been written.
  *
- * RETURN:	
+ * RETURN:
  *
  * NOTE:
  *	LOGGC_LOCK serializes log group commit queue, and
@@ -920,10 +920,10 @@
  *	this code is called again.
  *
  * PARAMETERS:	log	- log structure
- * 		hard_sync - 1 to force all metadata to be written
+ *		hard_sync - 1 to force all metadata to be written
  *
  * RETURN:	0
- *			
+ *
  * serialization: LOG_LOCK() held on entry/exit
  */
 static int lmLogSync(struct jfs_log * log, int hard_sync)
@@ -1052,7 +1052,7 @@
  * FUNCTION:	write log SYNCPT record for specified log
  *
  * PARAMETERS:	log	  - log structure
- * 		hard_sync - set to 1 to force metadata to be written
+ *		hard_sync - set to 1 to force metadata to be written
  */
 void jfs_syncpt(struct jfs_log *log, int hard_sync)
 {	LOG_LOCK(log);
@@ -1067,7 +1067,7 @@
  *	insert filesystem in the active list of the log.
  *
  * PARAMETER:	ipmnt	- file system mount inode
- *		iplog 	- log inode (out)
+ *		iplog	- log inode (out)
  *
  * RETURN:
  *
@@ -1082,7 +1082,7 @@
 
 	if (sbi->flag & JFS_NOINTEGRITY)
 		return open_dummy_log(sb);
-	
+
 	if (sbi->mntflag & JFS_INLINELOG)
 		return open_inline_log(sb);
 
@@ -1131,7 +1131,7 @@
 
 	log->bdev = bdev;
 	memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
-	
+
 	/*
 	 * initialize log:
 	 */
@@ -1253,13 +1253,13 @@
  *	initialize the log from log superblock.
  *	set the log state in the superblock to LOGMOUNT and
  *	write SYNCPT log record.
- *		
+ *
  * PARAMETER:	log	- log structure
  *
  * RETURN:	0	- if ok
  *		-EINVAL	- bad log magic number or superblock dirty
  *		error returned from logwait()
- *			
+ *
  * serialization: single first open thread
  */
 int lmLogInit(struct jfs_log * log)
@@ -1297,7 +1297,7 @@
 
 	if (!test_bit(log_INLINELOG, &log->flag))
 		log->l2bsize = L2LOGPSIZE;
-	
+
 	/* check for disabled journaling to disk */
 	if (log->no_integrity) {
 		/*
@@ -1651,7 +1651,7 @@
  * PARAMETER:	log	- log inode
  *
  * RETURN:	0	- success
- *			
+ *
  * serialization: single last close thread
  */
 int lmLogShutdown(struct jfs_log * log)
@@ -1677,7 +1677,7 @@
 	lrd.type = cpu_to_le16(LOG_SYNCPT);
 	lrd.length = 0;
 	lrd.log.syncpt.sync = 0;
-	
+
 	lsn = lmWriteRecord(log, NULL, &lrd, NULL);
 	bp = log->bp;
 	lp = (struct logpage *) bp->l_ldata;
@@ -1703,7 +1703,7 @@
 	jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d",
 		 lsn, log->page, log->eor);
 
-      out:    
+      out:
 	/*
 	 * shutdown per log i/o
 	 */
@@ -1769,7 +1769,7 @@
 			lbmFree(bpsuper);
 			return -EIO;
 		}
-		
+
 	}
 
 	/*
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index 8c6909b..a53fb17 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_LOGMGR
@@ -35,19 +35,19 @@
 /*
  *	log logical volume
  *
- * a log is used to make the commit operation on journalled 
+ * a log is used to make the commit operation on journalled
  * files within the same logical volume group atomic.
  * a log is implemented with a logical volume.
- * there is one log per logical volume group. 
+ * there is one log per logical volume group.
  *
  * block 0 of the log logical volume is not used (ipl etc).
  * block 1 contains a log "superblock" and is used by logFormat(),
- * lmLogInit(), lmLogShutdown(), and logRedo() to record status 
- * of the log but is not otherwise used during normal processing. 
+ * lmLogInit(), lmLogShutdown(), and logRedo() to record status
+ * of the log but is not otherwise used during normal processing.
  * blocks 2 - (N-1) are used to contain log records.
  *
- * when a volume group is varied-on-line, logRedo() must have 
- * been executed before the file systems (logical volumes) in 
+ * when a volume group is varied-on-line, logRedo() must have
+ * been executed before the file systems (logical volumes) in
  * the volume group can be mounted.
  */
 /*
@@ -97,26 +97,26 @@
  *	log logical page
  *
  * (this comment should be rewritten !)
- * the header and trailer structures (h,t) will normally have 
+ * the header and trailer structures (h,t) will normally have
  * the same page and eor value.
- * An exception to this occurs when a complete page write is not 
+ * An exception to this occurs when a complete page write is not
  * accomplished on a power failure. Since the hardware may "split write"
- * sectors in the page, any out of order sequence may occur during powerfail 
+ * sectors in the page, any out of order sequence may occur during powerfail
  * and needs to be recognized during log replay.  The xor value is
  * an "exclusive or" of all log words in the page up to eor.  This
  * 32 bit eor is stored with the top 16 bits in the header and the
  * bottom 16 bits in the trailer.  logredo can easily recognize pages
- * that were not completed by reconstructing this eor and checking 
+ * that were not completed by reconstructing this eor and checking
  * the log page.
  *
- * Previous versions of the operating system did not allow split 
- * writes and detected partially written records in logredo by 
- * ordering the updates to the header, trailer, and the move of data 
- * into the logdata area.  The order: (1) data is moved (2) header 
- * is updated (3) trailer is updated.  In logredo, when the header 
- * differed from the trailer, the header and trailer were reconciled 
- * as follows: if h.page != t.page they were set to the smaller of 
- * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) 
+ * Previous versions of the operating system did not allow split
+ * writes and detected partially written records in logredo by
+ * ordering the updates to the header, trailer, and the move of data
+ * into the logdata area.  The order: (1) data is moved (2) header
+ * is updated (3) trailer is updated.  In logredo, when the header
+ * differed from the trailer, the header and trailer were reconciled
+ * as follows: if h.page != t.page they were set to the smaller of
+ * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only)
  * h.eor != t.eor they were set to the smaller of their two values.
  */
 struct logpage {
@@ -147,20 +147,20 @@
  * in a  page, pages are written to temporary paging space if
  * if they must be written to disk before commit, and i/o is
  * scheduled for modified pages to their home location after
- * the log records containing the after values and the commit 
+ * the log records containing the after values and the commit
  * record is written to the log on disk, undo discards the copy
  * in main-memory.)
  *
- * a log record consists of a data area of variable length followed by 
+ * a log record consists of a data area of variable length followed by
  * a descriptor of fixed size LOGRDSIZE bytes.
- * the  data area is rounded up to an integral number of 4-bytes and 
+ * the  data area is rounded up to an integral number of 4-bytes and
  * must be no longer than LOGPSIZE.
- * the descriptor is of size of multiple of 4-bytes and aligned on a 
- * 4-byte boundary. 
+ * the descriptor is of size of multiple of 4-bytes and aligned on a
+ * 4-byte boundary.
  * records are packed one after the other in the data area of log pages.
- * (sometimes a DUMMY record is inserted so that at least one record ends 
+ * (sometimes a DUMMY record is inserted so that at least one record ends
  * on every page or the longest record is placed on at most two pages).
- * the field eor in page header/trailer points to the byte following 
+ * the field eor in page header/trailer points to the byte following
  * the last record on a page.
  */
 
@@ -270,11 +270,11 @@
 		/*
 		 *      NOREDOINOEXT: the inode extent is freed
 		 *
-		 * do not apply after-image records which precede this 
-		 * record in the log with the any of the 4 page block 
-		 * numbers in this inode extent. 
-		 * 
-		 * NOTE: The fileset and pxd fields MUST remain in 
+		 * do not apply after-image records which precede this
+		 * record in the log with the any of the 4 page block
+		 * numbers in this inode extent.
+		 *
+		 * NOTE: The fileset and pxd fields MUST remain in
 		 *       the same fields in the REDOPAGE record format.
 		 *
 		 */
@@ -319,12 +319,10 @@
 		 * do not apply records which precede this record in the log
 		 * with the same inode number.
 		 *
-		 * NOREDILE must be the first to be written at commit
+		 * NOREDOFILE must be the first to be written at commit
 		 * (last to be read in logredo()) - it prevents
 		 * replay of preceding updates of all preceding generations
-		 * of the inumber esp. the on-disk inode itself, 
-		 * but does NOT prevent
-		 * replay of the 
+		 * of the inumber esp. the on-disk inode itself.
 		 */
 		struct {
 			__le32 fileset;	/* 4: fileset number */
@@ -332,7 +330,7 @@
 		} noredofile;
 
 		/*
-		 *      ? NEWPAGE: 
+		 *      ? NEWPAGE:
 		 *
 		 * metadata type dependent
 		 */
@@ -464,7 +462,7 @@
 	s64 l_blkno;		/* 8: log page block number */
 	caddr_t l_ldata;	/* 4: data page */
 	struct page *l_page;	/* The page itself */
-	uint l_offset;		/* Offset of l_ldata within the page */	
+	uint l_offset;		/* Offset of l_ldata within the page */
 
 	wait_queue_head_t l_ioevent;	/* 4: i/o done event */
 };
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index f5afc12..0cccd1c 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -461,7 +461,7 @@
 				goto add_failed;
 		if (!bio->bi_size)
 			goto dump_bio;
-		
+
 		submit_bio(WRITE, bio);
 	}
 	if (redirty)
@@ -648,7 +648,7 @@
 			jfs_err("logical_size = %d, size = %d",
 				mp->logical_size, size);
 			dump_stack();
-			goto unlock; 
+			goto unlock;
 		}
 		mp->count++;
 		lock_metapage(mp);
@@ -658,7 +658,7 @@
 					  "__get_metapage: using a "
 					  "discarded metapage");
 				discard_metapage(mp);
-				goto unlock; 
+				goto unlock;
 			}
 			clear_bit(META_discard, &mp->flag);
 		}
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
index 01a5a45..d94f8d9 100644
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_METAPAGE
@@ -33,7 +33,7 @@
 	unsigned long flag;	/* See Below */
 	unsigned long count;	/* Reference count */
 	void *data;		/* Data pointer */
-	sector_t index; 	/* block address of page */
+	sector_t index;		/* block address of page */
 	wait_queue_head_t wait;
 
 	/* implementation */
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
index 032d111..4dd4798 100644
--- a/fs/jfs/jfs_mount.c
+++ b/fs/jfs/jfs_mount.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -21,18 +21,18 @@
  *
  * note: file system in transition to aggregate/fileset:
  *
- * file system mount is interpreted as the mount of aggregate, 
- * if not already mounted, and mount of the single/only fileset in 
+ * file system mount is interpreted as the mount of aggregate,
+ * if not already mounted, and mount of the single/only fileset in
  * the aggregate;
  *
  * a file system/aggregate is represented by an internal inode
  * (aka mount inode) initialized with aggregate superblock;
- * each vfs represents a fileset, and points to its "fileset inode 
+ * each vfs represents a fileset, and points to its "fileset inode
  * allocation map inode" (aka fileset inode):
- * (an aggregate itself is structured recursively as a filset: 
- * an internal vfs is constructed and points to its "fileset inode 
- * allocation map inode" (aka aggregate inode) where each inode 
- * represents a fileset inode) so that inode number is mapped to 
+ * (an aggregate itself is structured recursively as a filset:
+ * an internal vfs is constructed and points to its "fileset inode
+ * allocation map inode" (aka aggregate inode) where each inode
+ * represents a fileset inode) so that inode number is mapped to
  * on-disk inode in uniform way at both aggregate and fileset level;
  *
  * each vnode/inode of a fileset is linked to its vfs (to facilitate
@@ -41,7 +41,7 @@
  * per aggregate information, e.g., block size, etc.) as well as
  * its file set inode.
  *
- *   aggregate 
+ *   aggregate
  *   ipmnt
  *   mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap;
  *             fileset vfs     -> vp(1) <-> ... <-> vp(n) <->vproot;
@@ -88,7 +88,7 @@
 	struct inode *ipbmap = NULL;
 
 	/*
-	 * read/validate superblock 
+	 * read/validate superblock
 	 * (initialize mount inode from the superblock)
 	 */
 	if ((rc = chkSuper(sb))) {
@@ -238,7 +238,7 @@
  */
 int jfs_mount_rw(struct super_block *sb, int remount)
 {
-	struct jfs_sb_info *sbi = JFS_SBI(sb);  
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
 	int rc;
 
 	/*
@@ -291,7 +291,7 @@
 /*
  *	chkSuper()
  *
- * validate the superblock of the file system to be mounted and 
+ * validate the superblock of the file system to be mounted and
  * get the file system parameters.
  *
  * returns
@@ -426,7 +426,7 @@
 			jfs_err("updateSuper: bad state");
 	} else if (sbi->state == FM_DIRTY)
 		return 0;
-	
+
 	if ((rc = readSuper(sb, &bh)))
 		return rc;
 
@@ -486,9 +486,9 @@
  * for this file system past this point in log.
  * it is harmless if mount fails.
  *
- * note: MOUNT record is at aggregate level, not at fileset level, 
+ * note: MOUNT record is at aggregate level, not at fileset level,
  * since log records of previous mounts of a fileset
- * (e.g., AFTER record of extent allocation) have to be processed 
+ * (e.g., AFTER record of extent allocation) have to be processed
  * to update block allocation map at aggregate level.
  */
 static int logMOUNT(struct super_block *sb)
diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h
index 682cf1a..884fc21 100644
--- a/fs/jfs/jfs_superblock.h
+++ b/fs/jfs/jfs_superblock.h
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef	_H_JFS_SUPERBLOCK
@@ -21,14 +21,14 @@
 /*
  * make the magic number something a human could read
  */
-#define JFS_MAGIC 	"JFS1"	/* Magic word */
+#define JFS_MAGIC	"JFS1"	/* Magic word */
 
 #define JFS_VERSION	2	/* Version number: Version 2 */
 
 #define LV_NAME_SIZE	11	/* MUST BE 11 for OS/2 boot sector */
 
-/* 
- *	aggregate superblock 
+/*
+ *	aggregate superblock
  *
  * The name superblock is too close to super_block, so the name has been
  * changed to jfs_superblock.  The utilities are still using the old name.
@@ -40,7 +40,7 @@
 	__le64 s_size;		/* 8: aggregate size in hardware/LVM blocks;
 				 * VFS: number of blocks
 				 */
-	__le32 s_bsize;		/* 4: aggregate block size in bytes; 
+	__le32 s_bsize;		/* 4: aggregate block size in bytes;
 				 * VFS: fragment size
 				 */
 	__le16 s_l2bsize;	/* 2: log2 of s_bsize */
@@ -54,7 +54,7 @@
 	__le32 s_flag;		/* 4: aggregate attributes:
 				 *    see jfs_filsys.h
 				 */
-	__le32 s_state;		/* 4: mount/unmount/recovery state: 
+	__le32 s_state;		/* 4: mount/unmount/recovery state:
 				 *    see jfs_filsys.h
 				 */
 	__le32 s_compress;		/* 4: > 0 if data compression */
@@ -75,11 +75,11 @@
 	struct timestruc_t s_time;	/* 8: time last updated */
 
 	__le32 s_fsckloglen;	/* 4: Number of filesystem blocks reserved for
-				 *    the fsck service log.  
+				 *    the fsck service log.
 				 *    N.B. These blocks are divided among the
 				 *         versions kept.  This is not a per
 				 *         version size.
-				 *    N.B. These blocks are included in the 
+				 *    N.B. These blocks are included in the
 				 *         length field of s_fsckpxd.
 				 */
 	s8 s_fscklog;		/* 1: which fsck service log is most recent
@@ -87,7 +87,7 @@
 				 *    1 => the first one
 				 *    2 => the 2nd one
 				 */
-	char s_fpack[11];	/* 11: file system volume name 
+	char s_fpack[11];	/* 11: file system volume name
 				 *     N.B. This must be 11 bytes to
 				 *          conform with the OS/2 BootSector
 				 *          requirements
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index ebfa6c0..81f6f04 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -2026,8 +2026,6 @@
 		 * truncate entry XAD[twm == next - 1]:
 		 */
 		if (twm == next - 1) {
-			struct pxd_lock *pxdlock;
-
 			/* format a maplock for txUpdateMap() to update bmap
 			 * to free truncated delta extent of the truncated
 			 * entry XAD[next - 1];
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
index 0e4dc45..7863cf2 100644
--- a/fs/jfs/jfs_txnmgr.h
+++ b/fs/jfs/jfs_txnmgr.h
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_TXNMGR
@@ -179,7 +179,7 @@
 	/* (8) */
 
 	struct lv lv[20];	/* 40: */
-}; 				/* (48) */
+};				/* (48) */
 
 #define dt_lock	linelock
 
@@ -211,8 +211,8 @@
  * at tlock.lock/linelock: watch for alignment;
  * N.B. next field may be set by linelock, and should not
  * be modified by maplock;
- * N.B. index of the first pxdlock specifies index of next 
- * free maplock (i.e., number of maplock) in the tlock; 
+ * N.B. index of the first pxdlock specifies index of next
+ * free maplock (i.e., number of maplock) in the tlock;
  */
 struct maplock {
 	lid_t next;		/* 2: */
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
index 21eaf7a..a386f48 100644
--- a/fs/jfs/jfs_umount.c
+++ b/fs/jfs/jfs_umount.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -22,8 +22,8 @@
  * note: file system in transition to aggregate/fileset:
  * (ref. jfs_mount.c)
  *
- * file system unmount is interpreted as mount of the single/only 
- * fileset in the aggregate and, if unmount of the last fileset, 
+ * file system unmount is interpreted as mount of the single/only
+ * fileset in the aggregate and, if unmount of the last fileset,
  * as unmount of the aggerate;
  */
 
@@ -60,13 +60,13 @@
 	jfs_info("UnMount JFS: sb:0x%p", sb);
 
 	/*
-	 *      update superblock and close log 
+	 *      update superblock and close log
 	 *
 	 * if mounted read-write and log based recovery was enabled
 	 */
 	if ((log = sbi->log))
 		/*
-		 * Wait for outstanding transactions to be written to log: 
+		 * Wait for outstanding transactions to be written to log:
 		 */
 		jfs_flush_journal(log, 2);
 
@@ -112,17 +112,17 @@
 
 	/*
 	 * ensure all file system file pages are propagated to their
-	 * home blocks on disk (and their in-memory buffer pages are 
+	 * home blocks on disk (and their in-memory buffer pages are
 	 * invalidated) BEFORE updating file system superblock state
-	 * (to signify file system is unmounted cleanly, and thus in 
-	 * consistent state) and log superblock active file system 
+	 * (to signify file system is unmounted cleanly, and thus in
+	 * consistent state) and log superblock active file system
 	 * list (to signify skip logredo()).
 	 */
 	if (log) {		/* log = NULL if read-only mount */
 		updateSuper(sb, FM_CLEAN);
 
 		/*
-		 * close log: 
+		 * close log:
 		 *
 		 * remove file system from log active file system list.
 		 */
@@ -142,7 +142,7 @@
 		return 0;
 
 	/*
-	 * close log: 
+	 * close log:
 	 *
 	 * remove file system from log active file system list.
 	 */
diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c
index f327dec..c7de6f5 100644
--- a/fs/jfs/jfs_unicode.c
+++ b/fs/jfs/jfs_unicode.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -57,8 +57,8 @@
 					warn--;
 					warn_again--;
 					printk(KERN_ERR
-			"non-latin1 character 0x%x found in JFS file name\n", 
-		       			       le16_to_cpu(from[i]));
+			"non-latin1 character 0x%x found in JFS file name\n",
+					       le16_to_cpu(from[i]));
 					printk(KERN_ERR
 				"mount with iocharset=utf8 to access\n");
 				}
@@ -124,7 +124,7 @@
 	    kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS);
 
 	if (uniName->name == NULL)
-		return -ENOSPC;
+		return -ENOMEM;
 
 	uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
 				       length, nls_tab);
diff --git a/fs/jfs/jfs_unicode.h b/fs/jfs/jfs_unicode.h
index 69e25eb..3fbb3a2 100644
--- a/fs/jfs/jfs_unicode.h
+++ b/fs/jfs/jfs_unicode.h
@@ -1,19 +1,19 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_UNICODE
diff --git a/fs/jfs/jfs_uniupr.c b/fs/jfs/jfs_uniupr.c
index 4ab185d..cfe5066 100644
--- a/fs/jfs/jfs_uniupr.c
+++ b/fs/jfs/jfs_uniupr.c
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
index 25e9990..88b6cc5 100644
--- a/fs/jfs/jfs_xattr.h
+++ b/fs/jfs/jfs_xattr.h
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index c92307d..e98eb03 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 /*
@@ -2428,7 +2428,7 @@
  * return:
  */
 int xtAppend(tid_t tid,		/* transaction id */
-	     struct inode *ip, int xflag, s64 xoff, s32 maxblocks,	
+	     struct inode *ip, int xflag, s64 xoff, s32 maxblocks,
 	     s32 * xlenp,	/* (in/out) */
 	     s64 * xaddrp,	/* (in/out) */
 	     int flag)
@@ -2499,7 +2499,7 @@
 	pxdlist.maxnpxd = pxdlist.npxd = 0;
 	pxd = &pxdlist.pxd[0];
 	nblocks = JFS_SBI(ip->i_sb)->nbperpage;
-	for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {	
+	for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {
 		if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {
 			PXDaddress(pxd, xaddr);
 			PXDlength(pxd, nblocks);
@@ -2514,7 +2514,7 @@
 		goto out;
 	}
 
-	xlen = min(xlen, maxblocks);	
+	xlen = min(xlen, maxblocks);
 
 	/*
 	 * allocate data extent requested
diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h
index af668a8..164f6f2 100644
--- a/fs/jfs/jfs_xtree.h
+++ b/fs/jfs/jfs_xtree.h
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_XTREE
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index b8d16a6..a6a8c16 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -41,7 +41,7 @@
 /*
  * NAME:	free_ea_wmap(inode)
  *
- * FUNCTION:	free uncommitted extended attributes from working map 
+ * FUNCTION:	free uncommitted extended attributes from working map
  *
  */
 static inline void free_ea_wmap(struct inode *inode)
@@ -62,7 +62,7 @@
  * FUNCTION:	create a regular file in the parent directory <dip>
  *		with name = <from dentry> and mode = <mode>
  *
- * PARAMETER:	dip 	- parent directory vnode
+ * PARAMETER:	dip	- parent directory vnode
  *		dentry	- dentry of new file
  *		mode	- create mode (rwxrwxrwx).
  *		nd- nd struct
@@ -97,8 +97,8 @@
 	 * begin the transaction before we search the directory.
 	 */
 	ip = ialloc(dip, mode);
-	if (ip == NULL) {
-		rc = -ENOSPC;
+	if (IS_ERR(ip)) {
+		rc = PTR_ERR(ip);
 		goto out2;
 	}
 
@@ -190,7 +190,7 @@
  * FUNCTION:	create a child directory in the parent directory <dip>
  *		with name = <from dentry> and mode = <mode>
  *
- * PARAMETER:	dip 	- parent directory vnode
+ * PARAMETER:	dip	- parent directory vnode
  *		dentry	- dentry of child directory
  *		mode	- create mode (rwxrwxrwx).
  *
@@ -231,8 +231,8 @@
 	 * begin the transaction before we search the directory.
 	 */
 	ip = ialloc(dip, S_IFDIR | mode);
-	if (ip == NULL) {
-		rc = -ENOSPC;
+	if (IS_ERR(ip)) {
+		rc = PTR_ERR(ip);
 		goto out2;
 	}
 
@@ -324,7 +324,7 @@
  *
  * FUNCTION:	remove a link to child directory
  *
- * PARAMETER:	dip 	- parent inode
+ * PARAMETER:	dip	- parent inode
  *		dentry	- child directory dentry
  *
  * RETURN:	-EINVAL	- if name is . or ..
@@ -332,10 +332,10 @@
  *		errors from subroutines
  *
  * note:
- * if other threads have the directory open when the last link 
- * is removed, the "." and ".." entries, if present, are removed before 
- * rmdir() returns and no new entries may be created in the directory, 
- * but the directory is not removed until the last reference to 
+ * if other threads have the directory open when the last link
+ * is removed, the "." and ".." entries, if present, are removed before
+ * rmdir() returns and no new entries may be created in the directory,
+ * but the directory is not removed until the last reference to
  * the directory is released (cf.unlink() of regular file).
  */
 static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
@@ -446,11 +446,11 @@
 /*
  * NAME:	jfs_unlink(dip, dentry)
  *
- * FUNCTION:	remove a link to object <vp> named by <name> 
+ * FUNCTION:	remove a link to object <vp> named by <name>
  *		from parent directory <dvp>
  *
- * PARAMETER:	dip 	- inode of parent directory
- *		dentry 	- dentry of object to be removed
+ * PARAMETER:	dip	- inode of parent directory
+ *		dentry	- dentry of object to be removed
  *
  * RETURN:	errors from subroutines
  *
@@ -598,7 +598,7 @@
  *
  * FUNCTION:    for non-directory, called by jfs_remove(),
  *		truncate a regular file, directory or symbolic
- *		link to zero length. return 0 if type is not 
+ *		link to zero length. return 0 if type is not
  *		one of these.
  *
  *		if the file is currently associated with a VM segment
@@ -608,7 +608,7 @@
  *		map by ctrunc1.
  *		if there is no VM segment on entry, the resources are
  *		freed in both work and permanent map.
- *		(? for temporary file - memory object is cached even 
+ *		(? for temporary file - memory object is cached even
  *		after no reference:
  *		reference count > 0 -   )
  *
@@ -662,7 +662,7 @@
 
 	/*
 	 * free xtree/data (truncate to zero length):
-	 * free xtree/data pages from cache if COMMIT_PWMAP, 
+	 * free xtree/data pages from cache if COMMIT_PWMAP,
 	 * free xtree/data blocks from persistent block map, and
 	 * free xtree/data blocks from working block map if COMMIT_PWMAP;
 	 */
@@ -677,7 +677,7 @@
  * NAME:	jfs_free_zero_link()
  *
  * FUNCTION:    for non-directory, called by iClose(),
- *		free resources of a file from cache and WORKING map 
+ *		free resources of a file from cache and WORKING map
  *		for a file previously committed with zero link count
  *		while associated with a pager object,
  *
@@ -762,7 +762,7 @@
  * FUNCTION:	create a link to <vp> by the name = <name>
  *		in the parent directory <dvp>
  *
- * PARAMETER:	vp 	- target object
+ * PARAMETER:	vp	- target object
  *		dvp	- parent directory of new link
  *		name	- name of new link to target object
  *		crp	- credential
@@ -858,8 +858,8 @@
  *		        in directory <dip>
  *
  * PARAMETER:	dip	    - parent directory vnode
- *		        dentry 	- dentry of symbolic link
- *		        name    - the path name of the existing object 
+ *		        dentry	- dentry of symbolic link
+ *		        name    - the path name of the existing object
  *			              that will be the source of the link
  *
  * RETURN:	errors from subroutines
@@ -906,8 +906,8 @@
 	 * (iAlloc() returns new, locked inode)
 	 */
 	ip = ialloc(dip, S_IFLNK | 0777);
-	if (ip == NULL) {
-		rc = -ENOSPC;
+	if (IS_ERR(ip)) {
+		rc = PTR_ERR(ip);
 		goto out2;
 	}
 
@@ -926,7 +926,7 @@
 	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 
 	/* fix symlink access permission
-	 * (dir_create() ANDs in the u.u_cmask, 
+	 * (dir_create() ANDs in the u.u_cmask,
 	 * but symlinks really need to be 777 access)
 	 */
 	ip->i_mode |= 0777;
@@ -967,7 +967,7 @@
 		ip->i_mapping->a_ops = &jfs_aops;
 
 		/*
-		 * even though the data of symlink object (source 
+		 * even though the data of symlink object (source
 		 * path name) is treated as non-journaled user data,
 		 * it is read/written thru buffer cache for performance.
 		 */
@@ -978,7 +978,6 @@
 		xlen = xsize >> JFS_SBI(sb)->l2bsize;
 		if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
 			txAbort(tid, 0);
-			rc = -ENOSPC;
 			goto out3;
 		}
 		extent = xaddr;
@@ -1176,7 +1175,7 @@
 			/* free block resources */
 			if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
 				txAbort(tid, 1);	/* Marks FS Dirty */
-				rc = new_size;		
+				rc = new_size;
 				goto out4;
 			}
 			tblk = tid_to_tblock(tid);
@@ -1292,7 +1291,7 @@
 		new_size = xtTruncate_pmap(tid, new_ip, new_size);
 		if (new_size < 0) {
 			txAbort(tid, 1);
-			rc = new_size;		
+			rc = new_size;
 		} else
 			rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
 		txEnd(tid);
@@ -1350,8 +1349,8 @@
 		goto out;
 
 	ip = ialloc(dir, mode);
-	if (ip == NULL) {
-		rc = -ENOSPC;
+	if (IS_ERR(ip)) {
+		rc = PTR_ERR(ip);
 		goto out1;
 	}
 	jfs_ip = JFS_IP(ip);
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index 4518036..79d625f 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
 
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 143bcd1..9c1c6e0 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -82,7 +82,7 @@
 			"as read-only\n",
 			sb->s_id);
 		sb->s_flags |= MS_RDONLY;
-	} 
+	}
 
 	/* nothing is done for continue beyond marking the superblock dirty */
 }
@@ -422,7 +422,7 @@
 
 	sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
 	if (!sbi)
-		return -ENOSPC;
+		return -ENOMEM;
 	sb->s_fs_info = sbi;
 	sbi->sb = sb;
 	sbi->uid = sbi->gid = sbi->umask = -1;
@@ -775,7 +775,7 @@
 	int rc;
 
 	jfs_inode_cachep =
-	    kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, 
+	    kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
 			    SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
 			    init_once, NULL);
 	if (jfs_inode_cachep == NULL)
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index 16477b3..cee43f3 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 7a10e19..4c7985e 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -57,7 +57,7 @@
  *
  *   0            4                   4 + EA_SIZE(ea1)
  *   +------------+-------------------+--------------------+-----
- *   | Overall EA | First FEA Element | Second FEA Element | ..... 
+ *   | Overall EA | First FEA Element | Second FEA Element | .....
  *   | List Size  |                   |                    |
  *   +------------+-------------------+--------------------+-----
  *
@@ -155,9 +155,9 @@
 
 /*
  * NAME: ea_write_inline
- *                                                                    
+ *
  * FUNCTION: Attempt to write an EA inline if area is available
- *                                                                    
+ *
  * PRE CONDITIONS:
  *	Already verified that the specified EA is small enough to fit inline
  *
@@ -216,10 +216,10 @@
 
 /*
  * NAME: ea_write
- *                                                                    
+ *
  * FUNCTION: Write an EA for an inode
- *                                                                    
- * PRE CONDITIONS: EA has been verified 
+ *
+ * PRE CONDITIONS: EA has been verified
  *
  * PARAMETERS:
  *	ip	- Inode pointer
@@ -340,9 +340,9 @@
 
 /*
  * NAME: ea_read_inline
- *                                                                    
+ *
  * FUNCTION: Read an inlined EA into user's buffer
- *                                                                    
+ *
  * PARAMETERS:
  *	ip	- Inode pointer
  *	ealist	- Pointer to buffer to fill in with EA
@@ -372,9 +372,9 @@
 
 /*
  * NAME: ea_read
- *                                                                    
+ *
  * FUNCTION: copy EA data into user's buffer
- *                                                                    
+ *
  * PARAMETERS:
  *	ip	- Inode pointer
  *	ealist	- Pointer to buffer to fill in with EA
@@ -406,7 +406,7 @@
 		return -EIO;
 	}
 
-	/* 
+	/*
 	 * Figure out how many blocks were allocated when this EA list was
 	 * originally written to disk.
 	 */
@@ -443,14 +443,14 @@
 
 /*
  * NAME: ea_get
- *                                                                    
+ *
  * FUNCTION: Returns buffer containing existing extended attributes.
  *	     The size of the buffer will be the larger of the existing
  *	     attributes size, or min_size.
  *
  *	     The buffer, which may be inlined in the inode or in the
- * 	     page cache must be release by calling ea_release or ea_put
- *                                                                    
+ *	     page cache must be release by calling ea_release or ea_put
+ *
  * PARAMETERS:
  *	inode	- Inode pointer
  *	ea_buf	- Structure to be populated with ealist and its metadata
@@ -1054,7 +1054,7 @@
 
 	/* compute required size of list */
 	for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
-	    	if (can_list(ea))
+		if (can_list(ea))
 			size += name_size(ea) + 1;
 	}
 
@@ -1069,7 +1069,7 @@
 	/* Copy attribute names to buffer */
 	buffer = data;
 	for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
-	    	if (can_list(ea)) {
+		if (can_list(ea)) {
 			int namelen = copy_name(buffer, ea);
 			buffer += namelen + 1;
 		}
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index f95cc3f..e8c7765 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -144,42 +144,12 @@
  */
 
 /*
- * Someone has sent us an SM_NOTIFY. Ensure we bind to the new port number,
- * that we mark locks for reclaiming, and that we bump the pseudo NSM state.
- */
-static void nlmclnt_prepare_reclaim(struct nlm_host *host)
-{
-	down_write(&host->h_rwsem);
-	host->h_monitored = 0;
-	host->h_state++;
-	host->h_nextrebind = 0;
-	nlm_rebind_host(host);
-
-	/*
-	 * Mark the locks for reclaiming.
-	 */
-	list_splice_init(&host->h_granted, &host->h_reclaim);
-
-	dprintk("NLM: reclaiming locks for host %s\n", host->h_name);
-}
-
-static void nlmclnt_finish_reclaim(struct nlm_host *host)
-{
-	host->h_reclaiming = 0;
-	up_write(&host->h_rwsem);
-	dprintk("NLM: done reclaiming locks for host %s", host->h_name);
-}
-
-/*
  * Reclaim all locks on server host. We do this by spawning a separate
  * reclaimer thread.
  */
 void
-nlmclnt_recovery(struct nlm_host *host, u32 newstate)
+nlmclnt_recovery(struct nlm_host *host)
 {
-	if (host->h_nsmstate == newstate)
-		return;
-	host->h_nsmstate = newstate;
 	if (!host->h_reclaiming++) {
 		nlm_get_host(host);
 		__module_get(THIS_MODULE);
@@ -199,18 +169,30 @@
 	daemonize("%s-reclaim", host->h_name);
 	allow_signal(SIGKILL);
 
+	down_write(&host->h_rwsem);
+
 	/* This one ensures that our parent doesn't terminate while the
 	 * reclaim is in progress */
 	lock_kernel();
-	lockd_up();
+	lockd_up(0); /* note: this cannot fail as lockd is already running */
 
-	nlmclnt_prepare_reclaim(host);
-	/* First, reclaim all locks that have been marked. */
+	dprintk("lockd: reclaiming locks for host %s", host->h_name);
+
 restart:
 	nsmstate = host->h_nsmstate;
+
+	/* Force a portmap getport - the peer's lockd will
+	 * most likely end up on a different port.
+	 */
+	host->h_nextrebind = jiffies;
+	nlm_rebind_host(host);
+
+	/* First, reclaim all locks that have been granted. */
+	list_splice_init(&host->h_granted, &host->h_reclaim);
 	list_for_each_entry_safe(fl, next, &host->h_reclaim, fl_u.nfs_fl.list) {
 		list_del_init(&fl->fl_u.nfs_fl.list);
 
+		/* Why are we leaking memory here? --okir */
 		if (signalled())
 			continue;
 		if (nlmclnt_reclaim(host, fl) != 0)
@@ -218,11 +200,13 @@
 		list_add_tail(&fl->fl_u.nfs_fl.list, &host->h_granted);
 		if (host->h_nsmstate != nsmstate) {
 			/* Argh! The server rebooted again! */
-			list_splice_init(&host->h_granted, &host->h_reclaim);
 			goto restart;
 		}
 	}
-	nlmclnt_finish_reclaim(host);
+
+	host->h_reclaiming = 0;
+	up_write(&host->h_rwsem);
+	dprintk("NLM: done reclaiming locks for host %s", host->h_name);
 
 	/* Now, wake up all processes that sleep on a blocked lock */
 	list_for_each_entry(block, &nlm_blocked, b_list) {
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 271e216..3d84f60 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -36,14 +36,14 @@
 /*
  * Cookie counter for NLM requests
  */
-static u32	nlm_cookie = 0x1234;
+static atomic_t	nlm_cookie = ATOMIC_INIT(0x1234);
 
-static inline void nlmclnt_next_cookie(struct nlm_cookie *c)
+void nlmclnt_next_cookie(struct nlm_cookie *c)
 {
-	memcpy(c->data, &nlm_cookie, 4);
-	memset(c->data+4, 0, 4);
+	u32	cookie = atomic_inc_return(&nlm_cookie);
+
+	memcpy(c->data, &cookie, 4);
 	c->len=4;
-	nlm_cookie++;
 }
 
 static struct nlm_lockowner *nlm_get_lockowner(struct nlm_lockowner *lockowner)
@@ -129,11 +129,11 @@
 	nlmclnt_next_cookie(&argp->cookie);
 	argp->state   = nsm_local_state;
 	memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
-	lock->caller  = system_utsname.nodename;
+	lock->caller  = utsname()->nodename;
 	lock->oh.data = req->a_owner;
 	lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
 				(unsigned int)fl->fl_u.nfs_fl.owner->pid,
-				system_utsname.nodename);
+				utsname()->nodename);
 	lock->svid = fl->fl_u.nfs_fl.owner->pid;
 	lock->fl.fl_start = fl->fl_start;
 	lock->fl.fl_end = fl->fl_end;
@@ -153,6 +153,7 @@
 {
 	struct rpc_clnt		*client = NFS_CLIENT(inode);
 	struct sockaddr_in	addr;
+	struct nfs_server	*nfssrv = NFS_SERVER(inode);
 	struct nlm_host		*host;
 	struct nlm_rqst		*call;
 	sigset_t		oldset;
@@ -166,7 +167,9 @@
 	}
 
 	rpc_peeraddr(client, (struct sockaddr *) &addr, sizeof(addr));
-	host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers);
+	host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers,
+				   nfssrv->nfs_client->cl_hostname,
+				   strlen(nfssrv->nfs_client->cl_hostname));
 	if (host == NULL)
 		return -ENOLCK;
 
@@ -499,7 +502,7 @@
 	unsigned char fl_flags = fl->fl_flags;
 	int status = -ENOLCK;
 
-	if (!host->h_monitored && nsm_monitor(host) < 0) {
+	if (nsm_monitor(host) < 0) {
 		printk(KERN_NOTICE "lockd: failed to monitor %s\n",
 					host->h_name);
 		goto out;
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index a0d0b58..fb24a97 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -27,46 +27,60 @@
 #define NLM_HOST_EXPIRE		((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ)
 #define NLM_HOST_COLLECT	((nrhosts > NLM_HOST_MAX)? 120 * HZ :  60 * HZ)
 
-static struct nlm_host *	nlm_hosts[NLM_HOST_NRHASH];
+static struct hlist_head	nlm_hosts[NLM_HOST_NRHASH];
 static unsigned long		next_gc;
 static int			nrhosts;
 static DEFINE_MUTEX(nlm_host_mutex);
 
 
 static void			nlm_gc_hosts(void);
+static struct nsm_handle *	__nsm_find(const struct sockaddr_in *,
+					const char *, int, int);
 
 /*
  * Find an NLM server handle in the cache. If there is none, create it.
  */
 struct nlm_host *
-nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version)
+nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version,
+			const char *hostname, int hostname_len)
 {
-	return nlm_lookup_host(0, sin, proto, version);
+	return nlm_lookup_host(0, sin, proto, version,
+			       hostname, hostname_len);
 }
 
 /*
  * Find an NLM client handle in the cache. If there is none, create it.
  */
 struct nlm_host *
-nlmsvc_lookup_host(struct svc_rqst *rqstp)
+nlmsvc_lookup_host(struct svc_rqst *rqstp,
+			const char *hostname, int hostname_len)
 {
 	return nlm_lookup_host(1, &rqstp->rq_addr,
-			       rqstp->rq_prot, rqstp->rq_vers);
+			       rqstp->rq_prot, rqstp->rq_vers,
+			       hostname, hostname_len);
 }
 
 /*
  * Common host lookup routine for server & client
  */
 struct nlm_host *
-nlm_lookup_host(int server, struct sockaddr_in *sin,
-					int proto, int version)
+nlm_lookup_host(int server, const struct sockaddr_in *sin,
+					int proto, int version,
+					const char *hostname,
+					int hostname_len)
 {
-	struct nlm_host	*host, **hp;
-	u32		addr;
+	struct hlist_head *chain;
+	struct hlist_node *pos;
+	struct nlm_host	*host;
+	struct nsm_handle *nsm = NULL;
 	int		hash;
 
-	dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n",
-			(unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version);
+	dprintk("lockd: nlm_lookup_host(%u.%u.%u.%u, p=%d, v=%d, my role=%s, name=%.*s)\n",
+			NIPQUAD(sin->sin_addr.s_addr), proto, version,
+			server? "server" : "client",
+			hostname_len,
+			hostname? hostname : "<none>");
+
 
 	hash = NLM_ADDRHASH(sin->sin_addr.s_addr);
 
@@ -76,7 +90,22 @@
 	if (time_after_eq(jiffies, next_gc))
 		nlm_gc_hosts();
 
-	for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) {
+	/* We may keep several nlm_host objects for a peer, because each
+	 * nlm_host is identified by
+	 * (address, protocol, version, server/client)
+	 * We could probably simplify this a little by putting all those
+	 * different NLM rpc_clients into one single nlm_host object.
+	 * This would allow us to have one nlm_host per address.
+	 */
+	chain = &nlm_hosts[hash];
+	hlist_for_each_entry(host, pos, chain, h_hash) {
+		if (!nlm_cmp_addr(&host->h_addr, sin))
+			continue;
+
+		/* See if we have an NSM handle for this client */
+		if (!nsm)
+			nsm = host->h_nsmhandle;
+
 		if (host->h_proto != proto)
 			continue;
 		if (host->h_version != version)
@@ -84,28 +113,30 @@
 		if (host->h_server != server)
 			continue;
 
-		if (nlm_cmp_addr(&host->h_addr, sin)) {
-			if (hp != nlm_hosts + hash) {
-				*hp = host->h_next;
-				host->h_next = nlm_hosts[hash];
-				nlm_hosts[hash] = host;
-			}
-			nlm_get_host(host);
-			mutex_unlock(&nlm_host_mutex);
-			return host;
-		}
-	}
+		/* Move to head of hash chain. */
+		hlist_del(&host->h_hash);
+		hlist_add_head(&host->h_hash, chain);
 
-	/* Ooops, no host found, create it */
-	dprintk("lockd: creating host entry\n");
+		nlm_get_host(host);
+		goto out;
+	}
+	if (nsm)
+		atomic_inc(&nsm->sm_count);
+
+	host = NULL;
+
+	/* Sadly, the host isn't in our hash table yet. See if
+	 * we have an NSM handle for it. If not, create one.
+	 */
+	if (!nsm && !(nsm = nsm_find(sin, hostname, hostname_len)))
+		goto out;
 
 	host = kzalloc(sizeof(*host), GFP_KERNEL);
-	if (!host)
-		goto nohost;
-
-	addr = sin->sin_addr.s_addr;
-	sprintf(host->h_name, "%u.%u.%u.%u", NIPQUAD(addr));
-
+	if (!host) {
+		nsm_release(nsm);
+		goto out;
+	}
+	host->h_name	   = nsm->sm_name;
 	host->h_addr       = *sin;
 	host->h_addr.sin_port = 0;	/* ouch! */
 	host->h_version    = version;
@@ -119,9 +150,9 @@
 	init_rwsem(&host->h_rwsem);
 	host->h_state      = 0;			/* pseudo NSM state */
 	host->h_nsmstate   = 0;			/* real NSM state */
+	host->h_nsmhandle  = nsm;
 	host->h_server	   = server;
-	host->h_next       = nlm_hosts[hash];
-	nlm_hosts[hash]    = host;
+	hlist_add_head(&host->h_hash, chain);
 	INIT_LIST_HEAD(&host->h_lockowners);
 	spin_lock_init(&host->h_lock);
 	INIT_LIST_HEAD(&host->h_granted);
@@ -130,35 +161,39 @@
 	if (++nrhosts > NLM_HOST_MAX)
 		next_gc = 0;
 
-nohost:
+out:
 	mutex_unlock(&nlm_host_mutex);
 	return host;
 }
 
-struct nlm_host *
-nlm_find_client(void)
+/*
+ * Destroy a host
+ */
+static void
+nlm_destroy_host(struct nlm_host *host)
 {
-	/* find a nlm_host for a client for which h_killed == 0.
-	 * and return it
+	struct rpc_clnt	*clnt;
+
+	BUG_ON(!list_empty(&host->h_lockowners));
+	BUG_ON(atomic_read(&host->h_count));
+
+	/*
+	 * Release NSM handle and unmonitor host.
 	 */
-	int hash;
-	mutex_lock(&nlm_host_mutex);
-	for (hash = 0 ; hash < NLM_HOST_NRHASH; hash++) {
-		struct nlm_host *host, **hp;
-		for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) {
-			if (host->h_server &&
-			    host->h_killed == 0) {
-				nlm_get_host(host);
-				mutex_unlock(&nlm_host_mutex);
-				return host;
-			}
+	nsm_unmonitor(host);
+
+	if ((clnt = host->h_rpcclnt) != NULL) {
+		if (atomic_read(&clnt->cl_users)) {
+			printk(KERN_WARNING
+				"lockd: active RPC handle\n");
+			clnt->cl_dead = 1;
+		} else {
+			rpc_destroy_client(host->h_rpcclnt);
 		}
 	}
-	mutex_unlock(&nlm_host_mutex);
-	return NULL;
+	kfree(host);
 }
 
-				
 /*
  * Create the NLM RPC client for an NLM peer
  */
@@ -260,22 +295,82 @@
 }
 
 /*
+ * We were notified that the host indicated by address &sin
+ * has rebooted.
+ * Release all resources held by that peer.
+ */
+void nlm_host_rebooted(const struct sockaddr_in *sin,
+				const char *hostname, int hostname_len,
+				u32 new_state)
+{
+	struct hlist_head *chain;
+	struct hlist_node *pos;
+	struct nsm_handle *nsm;
+	struct nlm_host	*host;
+
+	dprintk("lockd: nlm_host_rebooted(%s, %u.%u.%u.%u)\n",
+			hostname, NIPQUAD(sin->sin_addr));
+
+	/* Find the NSM handle for this peer */
+	if (!(nsm = __nsm_find(sin, hostname, hostname_len, 0)))
+		return;
+
+	/* When reclaiming locks on this peer, make sure that
+	 * we set up a new notification */
+	nsm->sm_monitored = 0;
+
+	/* Mark all hosts tied to this NSM state as having rebooted.
+	 * We run the loop repeatedly, because we drop the host table
+	 * lock for this.
+	 * To avoid processing a host several times, we match the nsmstate.
+	 */
+again:	mutex_lock(&nlm_host_mutex);
+	for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+		hlist_for_each_entry(host, pos, chain, h_hash) {
+			if (host->h_nsmhandle == nsm
+			 && host->h_nsmstate != new_state) {
+				host->h_nsmstate = new_state;
+				host->h_state++;
+
+				nlm_get_host(host);
+				mutex_unlock(&nlm_host_mutex);
+
+				if (host->h_server) {
+					/* We're server for this guy, just ditch
+					 * all the locks he held. */
+					nlmsvc_free_host_resources(host);
+				} else {
+					/* He's the server, initiate lock recovery. */
+					nlmclnt_recovery(host);
+				}
+
+				nlm_release_host(host);
+				goto again;
+			}
+		}
+	}
+
+	mutex_unlock(&nlm_host_mutex);
+}
+
+/*
  * Shut down the hosts module.
  * Note that this routine is called only at server shutdown time.
  */
 void
 nlm_shutdown_hosts(void)
 {
+	struct hlist_head *chain;
+	struct hlist_node *pos;
 	struct nlm_host	*host;
-	int		i;
 
 	dprintk("lockd: shutting down host module\n");
 	mutex_lock(&nlm_host_mutex);
 
 	/* First, make all hosts eligible for gc */
 	dprintk("lockd: nuking all hosts...\n");
-	for (i = 0; i < NLM_HOST_NRHASH; i++) {
-		for (host = nlm_hosts[i]; host; host = host->h_next)
+	for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+		hlist_for_each_entry(host, pos, chain, h_hash)
 			host->h_expires = jiffies - 1;
 	}
 
@@ -287,8 +382,8 @@
 	if (nrhosts) {
 		printk(KERN_WARNING "lockd: couldn't shutdown host module!\n");
 		dprintk("lockd: %d hosts left:\n", nrhosts);
-		for (i = 0; i < NLM_HOST_NRHASH; i++) {
-			for (host = nlm_hosts[i]; host; host = host->h_next) {
+		for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+			hlist_for_each_entry(host, pos, chain, h_hash) {
 				dprintk("       %s (cnt %d use %d exp %ld)\n",
 					host->h_name, atomic_read(&host->h_count),
 					host->h_inuse, host->h_expires);
@@ -305,45 +400,32 @@
 static void
 nlm_gc_hosts(void)
 {
-	struct nlm_host	**q, *host;
-	struct rpc_clnt	*clnt;
-	int		i;
+	struct hlist_head *chain;
+	struct hlist_node *pos, *next;
+	struct nlm_host	*host;
 
 	dprintk("lockd: host garbage collection\n");
-	for (i = 0; i < NLM_HOST_NRHASH; i++) {
-		for (host = nlm_hosts[i]; host; host = host->h_next)
+	for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+		hlist_for_each_entry(host, pos, chain, h_hash)
 			host->h_inuse = 0;
 	}
 
 	/* Mark all hosts that hold locks, blocks or shares */
 	nlmsvc_mark_resources();
 
-	for (i = 0; i < NLM_HOST_NRHASH; i++) {
-		q = &nlm_hosts[i];
-		while ((host = *q) != NULL) {
+	for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+		hlist_for_each_entry_safe(host, pos, next, chain, h_hash) {
 			if (atomic_read(&host->h_count) || host->h_inuse
 			 || time_before(jiffies, host->h_expires)) {
 				dprintk("nlm_gc_hosts skipping %s (cnt %d use %d exp %ld)\n",
 					host->h_name, atomic_read(&host->h_count),
 					host->h_inuse, host->h_expires);
-				q = &host->h_next;
 				continue;
 			}
 			dprintk("lockd: delete host %s\n", host->h_name);
-			*q = host->h_next;
-			/* Don't unmonitor hosts that have been invalidated */
-			if (host->h_monitored && !host->h_killed)
-				nsm_unmonitor(host);
-			if ((clnt = host->h_rpcclnt) != NULL) {
-				if (atomic_read(&clnt->cl_users)) {
-					printk(KERN_WARNING
-						"lockd: active RPC handle\n");
-					clnt->cl_dead = 1;
-				} else {
-					rpc_destroy_client(host->h_rpcclnt);
-				}
-			}
-			kfree(host);
+			hlist_del_init(&host->h_hash);
+
+			nlm_destroy_host(host);
 			nrhosts--;
 		}
 	}
@@ -351,3 +433,88 @@
 	next_gc = jiffies + NLM_HOST_COLLECT;
 }
 
+
+/*
+ * Manage NSM handles
+ */
+static LIST_HEAD(nsm_handles);
+static DEFINE_MUTEX(nsm_mutex);
+
+static struct nsm_handle *
+__nsm_find(const struct sockaddr_in *sin,
+		const char *hostname, int hostname_len,
+		int create)
+{
+	struct nsm_handle *nsm = NULL;
+	struct list_head *pos;
+
+	if (!sin)
+		return NULL;
+
+	if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
+		if (printk_ratelimit()) {
+			printk(KERN_WARNING "Invalid hostname \"%.*s\" "
+					    "in NFS lock request\n",
+				hostname_len, hostname);
+		}
+		return NULL;
+	}
+
+	mutex_lock(&nsm_mutex);
+	list_for_each(pos, &nsm_handles) {
+		nsm = list_entry(pos, struct nsm_handle, sm_link);
+
+		if (hostname && nsm_use_hostnames) {
+			if (strlen(nsm->sm_name) != hostname_len
+			 || memcmp(nsm->sm_name, hostname, hostname_len))
+				continue;
+		} else if (!nlm_cmp_addr(&nsm->sm_addr, sin))
+			continue;
+		atomic_inc(&nsm->sm_count);
+		goto out;
+	}
+
+	if (!create) {
+		nsm = NULL;
+		goto out;
+	}
+
+	nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
+	if (nsm != NULL) {
+		nsm->sm_addr = *sin;
+		nsm->sm_name = (char *) (nsm + 1);
+		memcpy(nsm->sm_name, hostname, hostname_len);
+		nsm->sm_name[hostname_len] = '\0';
+		atomic_set(&nsm->sm_count, 1);
+
+		list_add(&nsm->sm_link, &nsm_handles);
+	}
+
+out:
+	mutex_unlock(&nsm_mutex);
+	return nsm;
+}
+
+struct nsm_handle *
+nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len)
+{
+	return __nsm_find(sin, hostname, hostname_len, 1);
+}
+
+/*
+ * Release an NSM handle
+ */
+void
+nsm_release(struct nsm_handle *nsm)
+{
+	if (!nsm)
+		return;
+	if (atomic_dec_and_test(&nsm->sm_count)) {
+		mutex_lock(&nsm_mutex);
+		if (atomic_read(&nsm->sm_count) == 0) {
+			list_del(&nsm->sm_link);
+			kfree(nsm);
+		}
+		mutex_unlock(&nsm_mutex);
+	}
+}
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 5954dcb..e0179f8 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -24,13 +24,13 @@
 /*
  * Local NSM state
  */
-u32				nsm_local_state;
+int				nsm_local_state;
 
 /*
  * Common procedure for SM_MON/SM_UNMON calls
  */
 static int
-nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res)
+nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 {
 	struct rpc_clnt	*clnt;
 	int		status;
@@ -46,10 +46,11 @@
 		goto out;
 	}
 
-	args.addr = host->h_addr.sin_addr.s_addr;
-	args.proto= (host->h_proto<<1) | host->h_server;
+	memset(&args, 0, sizeof(args));
+	args.mon_name = nsm->sm_name;
+	args.addr = nsm->sm_addr.sin_addr.s_addr;
 	args.prog = NLM_PROGRAM;
-	args.vers = host->h_version;
+	args.vers = 3;
 	args.proc = NLMPROC_NSM_NOTIFY;
 	memset(res, 0, sizeof(*res));
 
@@ -70,17 +71,22 @@
 int
 nsm_monitor(struct nlm_host *host)
 {
+	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
 	int		status;
 
 	dprintk("lockd: nsm_monitor(%s)\n", host->h_name);
+	BUG_ON(nsm == NULL);
 
-	status = nsm_mon_unmon(host, SM_MON, &res);
+	if (nsm->sm_monitored)
+		return 0;
+
+	status = nsm_mon_unmon(nsm, SM_MON, &res);
 
 	if (status < 0 || res.status != 0)
 		printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name);
 	else
-		host->h_monitored = 1;
+		nsm->sm_monitored = 1;
 	return status;
 }
 
@@ -90,16 +96,26 @@
 int
 nsm_unmonitor(struct nlm_host *host)
 {
+	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
-	int		status;
+	int		status = 0;
 
-	dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name);
+	if (nsm == NULL)
+		return 0;
+	host->h_nsmhandle = NULL;
 
-	status = nsm_mon_unmon(host, SM_UNMON, &res);
-	if (status < 0)
-		printk(KERN_NOTICE "lockd: cannot unmonitor %s\n", host->h_name);
-	else
-		host->h_monitored = 0;
+	if (atomic_read(&nsm->sm_count) == 1
+	 && nsm->sm_monitored && !nsm->sm_sticky) {
+		dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name);
+
+		status = nsm_mon_unmon(nsm, SM_UNMON, &res);
+		if (status < 0)
+			printk(KERN_NOTICE "lockd: cannot unmonitor %s\n",
+					host->h_name);
+		else
+			nsm->sm_monitored = 0;
+	}
+	nsm_release(nsm);
 	return status;
 }
 
@@ -135,7 +151,7 @@
 static u32 *
 xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
 {
-	char	buffer[20];
+	char	buffer[20], *name;
 
 	/*
 	 * Use the dotted-quad IP address of the remote host as
@@ -143,9 +159,14 @@
 	 * hostname first for whatever remote hostname it receives,
 	 * so this works alright.
 	 */
-	sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
-	if (!(p = xdr_encode_string(p, buffer))
-	 || !(p = xdr_encode_string(p, system_utsname.nodename)))
+	if (nsm_use_hostnames) {
+		name = argp->mon_name;
+	} else {
+		sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
+		name = buffer;
+	}
+	if (!(p = xdr_encode_string(p, name))
+	 || !(p = xdr_encode_string(p, utsname()->nodename)))
 		return ERR_PTR(-EIO);
 	*p++ = htonl(argp->prog);
 	*p++ = htonl(argp->vers);
@@ -160,9 +181,11 @@
 	p = xdr_encode_common(rqstp, p, argp);
 	if (IS_ERR(p))
 		return PTR_ERR(p);
+
+	/* Surprise - there may even be room for an IPv6 address now */
 	*p++ = argp->addr;
-	*p++ = argp->vers;
-	*p++ = argp->proto;
+	*p++ = 0;
+	*p++ = 0;
 	*p++ = 0;
 	rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p);
 	return 0;
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 9a991b5..6341392 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -31,7 +31,9 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
+#include <net/ip.h>
 #include <linux/lockd/lockd.h>
+#include <linux/lockd/sm_inter.h>
 #include <linux/nfs.h>
 
 #define NLMDBG_FACILITY		NLMDBG_SVC
@@ -46,6 +48,7 @@
 static DEFINE_MUTEX(nlmsvc_mutex);
 static unsigned int		nlmsvc_users;
 static pid_t			nlmsvc_pid;
+static struct svc_serv		*nlmsvc_serv;
 int				nlmsvc_grace_period;
 unsigned long			nlmsvc_timeout;
 
@@ -59,6 +62,7 @@
 static unsigned long		nlm_grace_period;
 static unsigned long		nlm_timeout = LOCKD_DFLT_TIMEO;
 static int			nlm_udpport, nlm_tcpport;
+int				nsm_use_hostnames = 0;
 
 /*
  * Constants needed for the sysctl interface.
@@ -96,7 +100,6 @@
 static void
 lockd(struct svc_rqst *rqstp)
 {
-	struct svc_serv	*serv = rqstp->rq_server;
 	int		err = 0;
 	unsigned long grace_period_expire;
 
@@ -112,6 +115,7 @@
 	 * Let our maker know we're running.
 	 */
 	nlmsvc_pid = current->pid;
+	nlmsvc_serv = rqstp->rq_server;
 	complete(&lockd_start_done);
 
 	daemonize("lockd");
@@ -161,7 +165,7 @@
 		 * Find a socket with data available and call its
 		 * recvfrom routine.
 		 */
-		err = svc_recv(serv, rqstp, timeout);
+		err = svc_recv(rqstp, timeout);
 		if (err == -EAGAIN || err == -EINTR)
 			continue;
 		if (err < 0) {
@@ -174,7 +178,7 @@
 		dprintk("lockd: request from %08x\n",
 			(unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr));
 
-		svc_process(serv, rqstp);
+		svc_process(rqstp);
 
 	}
 
@@ -189,6 +193,7 @@
 			nlmsvc_invalidate_all();
 		nlm_shutdown_hosts();
 		nlmsvc_pid = 0;
+		nlmsvc_serv = NULL;
 	} else
 		printk(KERN_DEBUG
 			"lockd: new process, skipping host shutdown\n");
@@ -205,54 +210,77 @@
 	module_put_and_exit(0);
 }
 
+
+static int find_socket(struct svc_serv *serv, int proto)
+{
+	struct svc_sock *svsk;
+	int found = 0;
+	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+		if (svsk->sk_sk->sk_protocol == proto) {
+			found = 1;
+			break;
+		}
+	return found;
+}
+
+static int make_socks(struct svc_serv *serv, int proto)
+{
+	/* Make any sockets that are needed but not present.
+	 * If nlm_udpport or nlm_tcpport were set as module
+	 * options, make those sockets unconditionally
+	 */
+	static int		warned;
+	int err = 0;
+	if (proto == IPPROTO_UDP || nlm_udpport)
+		if (!find_socket(serv, IPPROTO_UDP))
+			err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport);
+	if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport))
+		if (!find_socket(serv, IPPROTO_TCP))
+			err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport);
+	if (!err)
+		warned = 0;
+	else if (warned++ == 0)
+		printk(KERN_WARNING
+		       "lockd_up: makesock failed, error=%d\n", err);
+	return err;
+}
+
 /*
  * Bring up the lockd process if it's not already up.
  */
 int
-lockd_up(void)
+lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
 {
-	static int		warned;
 	struct svc_serv *	serv;
 	int			error = 0;
 
 	mutex_lock(&nlmsvc_mutex);
 	/*
-	 * Unconditionally increment the user count ... this is
-	 * the number of clients who _want_ a lockd process.
-	 */
-	nlmsvc_users++; 
-	/*
 	 * Check whether we're already up and running.
 	 */
-	if (nlmsvc_pid)
+	if (nlmsvc_pid) {
+		if (proto)
+			error = make_socks(nlmsvc_serv, proto);
 		goto out;
+	}
 
 	/*
 	 * Sanity check: if there's no pid,
 	 * we should be the first user ...
 	 */
-	if (nlmsvc_users > 1)
+	if (nlmsvc_users)
 		printk(KERN_WARNING
 			"lockd_up: no pid, %d users??\n", nlmsvc_users);
 
 	error = -ENOMEM;
-	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE);
+	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
 	if (!serv) {
 		printk(KERN_WARNING "lockd_up: create service failed\n");
 		goto out;
 	}
 
-	if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0 
-#ifdef CONFIG_NFSD_TCP
-	 || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0
-#endif
-		) {
-		if (warned++ == 0) 
-			printk(KERN_WARNING
-				"lockd_up: makesock failed, error=%d\n", error);
+	if ((error = make_socks(serv, proto)) < 0)
 		goto destroy_and_out;
-	} 
-	warned = 0;
 
 	/*
 	 * Create the kernel thread and wait for it to start.
@@ -272,6 +300,8 @@
 destroy_and_out:
 	svc_destroy(serv);
 out:
+	if (!error)
+		nlmsvc_users++;
 	mutex_unlock(&nlmsvc_mutex);
 	return error;
 }
@@ -367,6 +397,22 @@
 		.extra1		= (int *) &nlm_port_min,
 		.extra2		= (int *) &nlm_port_max,
 	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "nsm_use_hostnames",
+		.data		= &nsm_use_hostnames,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "nsm_local_state",
+		.data		= &nsm_local_state,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{ .ctl_name = 0 }
 };
 
@@ -455,6 +501,7 @@
 		  &nlm_udpport, 0644);
 module_param_call(nlm_tcpport, param_set_port, param_get_int,
 		  &nlm_tcpport, 0644);
+module_param(nsm_use_hostnames, bool, 0644);
 
 /*
  * Initialising and terminating the module.
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index a2dd9cc..fa370f6 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -38,8 +38,8 @@
 		return nlm_lck_denied_nolocks;
 
 	/* Obtain host handle */
-	if (!(host = nlmsvc_lookup_host(rqstp))
-	 || (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0))
+	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
+	 || (argp->monitor && nsm_monitor(host) < 0))
 		goto no_locks;
 	*hostp = host;
 
@@ -260,7 +260,9 @@
 	struct nlm_rqst	*call;
 	int stat;
 
-	host = nlmsvc_lookup_host(rqstp);
+	host = nlmsvc_lookup_host(rqstp,
+				  argp->lock.caller,
+				  argp->lock.len);
 	if (host == NULL)
 		return rpc_system_err;
 
@@ -420,10 +422,6 @@
 					      void	        *resp)
 {
 	struct sockaddr_in	saddr = rqstp->rq_addr;
-	int			vers = argp->vers;
-	int			prot = argp->proto >> 1;
-
-	struct nlm_host		*host;
 
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
@@ -438,21 +436,10 @@
 	/* Obtain the host pointer for this NFS server and try to
 	 * reclaim all locks we hold on this server.
 	 */
+	memset(&saddr, 0, sizeof(saddr));
 	saddr.sin_addr.s_addr = argp->addr;
+	nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state);
 
-	if ((argp->proto & 1)==0) {
-		if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
-			nlmclnt_recovery(host, argp->state);
-			nlm_release_host(host);
-		}
-	} else {
-		/* If we run on an NFS server, delete all locks held by the client */
-
-		if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
-			nlmsvc_free_host_resources(host);
-			nlm_release_host(host);
-		}
-	}
 	return rpc_success;
 }
 
@@ -468,7 +455,7 @@
 
         dprintk("lockd: GRANTED_RES   called\n");
 
-        nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status);
+        nlmsvc_grant_reply(&argp->cookie, argp->status);
         return rpc_success;
 }
 
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index c9d4197..814c606 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -40,7 +40,7 @@
 
 static void nlmsvc_release_block(struct nlm_block *block);
 static void	nlmsvc_insert_block(struct nlm_block *block, unsigned long);
-static int	nlmsvc_remove_block(struct nlm_block *block);
+static void	nlmsvc_remove_block(struct nlm_block *block);
 
 static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock);
 static void nlmsvc_freegrantargs(struct nlm_rqst *call);
@@ -49,7 +49,7 @@
 /*
  * The list of blocked locks to retry
  */
-static struct nlm_block *	nlm_blocked;
+static LIST_HEAD(nlm_blocked);
 
 /*
  * Insert a blocked lock into the global list
@@ -57,48 +57,44 @@
 static void
 nlmsvc_insert_block(struct nlm_block *block, unsigned long when)
 {
-	struct nlm_block **bp, *b;
+	struct nlm_block *b;
+	struct list_head *pos;
 
 	dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when);
-	kref_get(&block->b_count);
-	if (block->b_queued)
-		nlmsvc_remove_block(block);
-	bp = &nlm_blocked;
+	if (list_empty(&block->b_list)) {
+		kref_get(&block->b_count);
+	} else {
+		list_del_init(&block->b_list);
+	}
+
+	pos = &nlm_blocked;
 	if (when != NLM_NEVER) {
 		if ((when += jiffies) == NLM_NEVER)
 			when ++;
-		while ((b = *bp) && time_before_eq(b->b_when,when) && b->b_when != NLM_NEVER)
-			bp = &b->b_next;
-	} else
-		while ((b = *bp) != 0)
-			bp = &b->b_next;
+		list_for_each(pos, &nlm_blocked) {
+			b = list_entry(pos, struct nlm_block, b_list);
+			if (time_after(b->b_when,when) || b->b_when == NLM_NEVER)
+				break;
+		}
+		/* On normal exit from the loop, pos == &nlm_blocked,
+		 * so we will be adding to the end of the list - good
+		 */
+	}
 
-	block->b_queued = 1;
+	list_add_tail(&block->b_list, pos);
 	block->b_when = when;
-	block->b_next = b;
-	*bp = block;
 }
 
 /*
  * Remove a block from the global list
  */
-static int
+static inline void
 nlmsvc_remove_block(struct nlm_block *block)
 {
-	struct nlm_block **bp, *b;
-
-	if (!block->b_queued)
-		return 1;
-	for (bp = &nlm_blocked; (b = *bp) != 0; bp = &b->b_next) {
-		if (b == block) {
-			*bp = block->b_next;
-			block->b_queued = 0;
-			nlmsvc_release_block(block);
-			return 1;
-		}
+	if (!list_empty(&block->b_list)) {
+		list_del_init(&block->b_list);
+		nlmsvc_release_block(block);
 	}
-
-	return 0;
 }
 
 /*
@@ -107,14 +103,14 @@
 static struct nlm_block *
 nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock)
 {
-	struct nlm_block	**head, *block;
+	struct nlm_block	*block;
 	struct file_lock	*fl;
 
 	dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
 				file, lock->fl.fl_pid,
 				(long long)lock->fl.fl_start,
 				(long long)lock->fl.fl_end, lock->fl.fl_type);
-	for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) {
+	list_for_each_entry(block, &nlm_blocked, b_list) {
 		fl = &block->b_call->a_args.lock.fl;
 		dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
 				block->b_file, fl->fl_pid,
@@ -143,20 +139,20 @@
  * Find a block with a given NLM cookie.
  */
 static inline struct nlm_block *
-nlmsvc_find_block(struct nlm_cookie *cookie,  struct sockaddr_in *sin)
+nlmsvc_find_block(struct nlm_cookie *cookie)
 {
 	struct nlm_block *block;
 
-	for (block = nlm_blocked; block; block = block->b_next) {
-		dprintk("cookie: head of blocked queue %p, block %p\n", 
-			nlm_blocked, block);
-		if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie)
-				&& nlm_cmp_addr(sin, &block->b_host->h_addr))
-			break;
+	list_for_each_entry(block, &nlm_blocked, b_list) {
+		if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie))
+			goto found;
 	}
 
-	if (block != NULL)
-		kref_get(&block->b_count);
+	return NULL;
+
+found:
+	dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block);
+	kref_get(&block->b_count);
 	return block;
 }
 
@@ -169,6 +165,11 @@
  * request, but (as I found out later) that's because some implementations
  * do just this. Never mind the standards comittees, they support our
  * logging industries.
+ *
+ * 10 years later: I hope we can safely ignore these old and broken
+ * clients by now. Let's fix this so we can uniquely identify an incoming
+ * GRANTED_RES message by cookie, without having to rely on the client's IP
+ * address. --okir
  */
 static inline struct nlm_block *
 nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
@@ -179,7 +180,7 @@
 	struct nlm_rqst		*call = NULL;
 
 	/* Create host handle for callback */
-	host = nlmsvc_lookup_host(rqstp);
+	host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len);
 	if (host == NULL)
 		return NULL;
 
@@ -192,6 +193,8 @@
 	if (block == NULL)
 		goto failed;
 	kref_init(&block->b_count);
+	INIT_LIST_HEAD(&block->b_list);
+	INIT_LIST_HEAD(&block->b_flist);
 
 	if (!nlmsvc_setgrantargs(call, lock))
 		goto failed_free;
@@ -199,7 +202,7 @@
 	/* Set notifier function for VFS, and init args */
 	call->a_args.lock.fl.fl_flags |= FL_SLEEP;
 	call->a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations;
-	call->a_args.cookie = *cookie;	/* see above */
+	nlmclnt_next_cookie(&call->a_args.cookie);
 
 	dprintk("lockd: created block %p...\n", block);
 
@@ -210,8 +213,7 @@
 	file->f_count++;
 
 	/* Add to file's list of blocks */
-	block->b_fnext  = file->f_blocks;
-	file->f_blocks  = block;
+	list_add(&block->b_flist, &file->f_blocks);
 
 	/* Set up RPC arguments for callback */
 	block->b_call = call;
@@ -248,19 +250,13 @@
 {
 	struct nlm_block *block = container_of(kref, struct nlm_block, b_count);
 	struct nlm_file		*file = block->b_file;
-	struct nlm_block	**bp;
 
 	dprintk("lockd: freeing block %p...\n", block);
 
-	down(&file->f_sema);
 	/* Remove block from file's list of blocks */
-	for (bp = &file->f_blocks; *bp; bp = &(*bp)->b_fnext) {
-		if (*bp == block) {
-			*bp = block->b_fnext;
-			break;
-		}
-	}
-	up(&file->f_sema);
+	mutex_lock(&file->f_mutex);
+	list_del_init(&block->b_flist);
+	mutex_unlock(&file->f_mutex);
 
 	nlmsvc_freegrantargs(block->b_call);
 	nlm_release_call(block->b_call);
@@ -274,47 +270,32 @@
 		kref_put(&block->b_count, nlmsvc_free_block);
 }
 
-static void nlmsvc_act_mark(struct nlm_host *host, struct nlm_file *file)
+/*
+ * Loop over all blocks and delete blocks held by
+ * a matching host.
+ */
+void nlmsvc_traverse_blocks(struct nlm_host *host,
+			struct nlm_file *file,
+			nlm_host_match_fn_t match)
 {
-	struct nlm_block *block;
-
-	down(&file->f_sema);
-	for (block = file->f_blocks; block != NULL; block = block->b_fnext)
-		block->b_host->h_inuse = 1;
-	up(&file->f_sema);
-}
-
-static void nlmsvc_act_unlock(struct nlm_host *host, struct nlm_file *file)
-{
-	struct nlm_block *block;
+	struct nlm_block *block, *next;
 
 restart:
-	down(&file->f_sema);
-	for (block = file->f_blocks; block != NULL; block = block->b_fnext) {
-		if (host != NULL && host != block->b_host)
+	mutex_lock(&file->f_mutex);
+	list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) {
+		if (!match(block->b_host, host))
 			continue;
-		if (!block->b_queued)
+		/* Do not destroy blocks that are not on
+		 * the global retry list - why? */
+		if (list_empty(&block->b_list))
 			continue;
 		kref_get(&block->b_count);
-		up(&file->f_sema);
+		mutex_unlock(&file->f_mutex);
 		nlmsvc_unlink_block(block);
 		nlmsvc_release_block(block);
 		goto restart;
 	}
-	up(&file->f_sema);
-}
-
-/*
- * Loop over all blocks and perform the action specified.
- * (NLM_ACT_CHECK handled by nlmsvc_inspect_file).
- */
-void
-nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action)
-{
-	if (action == NLM_ACT_MARK)
-		nlmsvc_act_mark(host, file);
-	else
-		nlmsvc_act_unlock(host, file);
+	mutex_unlock(&file->f_mutex);
 }
 
 /*
@@ -325,7 +306,7 @@
 {
 	locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
 	memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
-	call->a_args.lock.caller = system_utsname.nodename;
+	call->a_args.lock.caller = utsname()->nodename;
 	call->a_args.lock.oh.len = lock->oh.len;
 
 	/* set default data area */
@@ -373,7 +354,7 @@
 	lock->fl.fl_flags &= ~FL_SLEEP;
 again:
 	/* Lock file against concurrent access */
-	down(&file->f_sema);
+	mutex_lock(&file->f_mutex);
 	/* Get existing block (in case client is busy-waiting) */
 	block = nlmsvc_lookup_block(file, lock);
 	if (block == NULL) {
@@ -411,10 +392,10 @@
 
 	/* If we don't have a block, create and initialize it. Then
 	 * retry because we may have slept in kmalloc. */
-	/* We have to release f_sema as nlmsvc_create_block may try to
+	/* We have to release f_mutex as nlmsvc_create_block may try to
 	 * to claim it while doing host garbage collection */
 	if (newblock == NULL) {
-		up(&file->f_sema);
+		mutex_unlock(&file->f_mutex);
 		dprintk("lockd: blocking on this lock (allocating).\n");
 		if (!(newblock = nlmsvc_create_block(rqstp, file, lock, cookie)))
 			return nlm_lck_denied_nolocks;
@@ -424,7 +405,7 @@
 	/* Append to list of blocked */
 	nlmsvc_insert_block(newblock, NLM_NEVER);
 out:
-	up(&file->f_sema);
+	mutex_unlock(&file->f_mutex);
 	nlmsvc_release_block(newblock);
 	nlmsvc_release_block(block);
 	dprintk("lockd: nlmsvc_lock returned %u\n", ret);
@@ -451,6 +432,7 @@
 				(long long)conflock->fl.fl_start,
 				(long long)conflock->fl.fl_end);
 		conflock->caller = "somehost";	/* FIXME */
+		conflock->len = strlen(conflock->caller);
 		conflock->oh.len = 0;		/* don't return OH info */
 		conflock->svid = conflock->fl.fl_pid;
 		return nlm_lck_denied;
@@ -507,9 +489,9 @@
 				(long long)lock->fl.fl_start,
 				(long long)lock->fl.fl_end);
 
-	down(&file->f_sema);
+	mutex_lock(&file->f_mutex);
 	block = nlmsvc_lookup_block(file, lock);
-	up(&file->f_sema);
+	mutex_unlock(&file->f_mutex);
 	if (block != NULL) {
 		status = nlmsvc_unlink_block(block);
 		nlmsvc_release_block(block);
@@ -527,10 +509,10 @@
 static void
 nlmsvc_notify_blocked(struct file_lock *fl)
 {
-	struct nlm_block	**bp, *block;
+	struct nlm_block	*block;
 
 	dprintk("lockd: VFS unblock notification for block %p\n", fl);
-	for (bp = &nlm_blocked; (block = *bp) != 0; bp = &block->b_next) {
+	list_for_each_entry(block, &nlm_blocked, b_list) {
 		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
 			nlmsvc_insert_block(block, 0);
 			svc_wake_up(block->b_daemon);
@@ -663,17 +645,14 @@
  * block.
  */
 void
-nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status)
+nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
 {
 	struct nlm_block	*block;
-	struct nlm_file		*file;
 
-	dprintk("grant_reply: looking for cookie %x, host (%08x), s=%d \n", 
-		*(unsigned int *)(cookie->data), 
-		ntohl(rqstp->rq_addr.sin_addr.s_addr), status);
-	if (!(block = nlmsvc_find_block(cookie, &rqstp->rq_addr)))
+	dprintk("grant_reply: looking for cookie %x, s=%d \n",
+		*(unsigned int *)(cookie->data), status);
+	if (!(block = nlmsvc_find_block(cookie)))
 		return;
-	file = block->b_file;
 
 	if (block) {
 		if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
@@ -696,16 +675,19 @@
 unsigned long
 nlmsvc_retry_blocked(void)
 {
-	struct nlm_block	*block;
+	unsigned long	timeout = MAX_SCHEDULE_TIMEOUT;
+	struct nlm_block *block;
 
-	dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
-			nlm_blocked,
-			nlm_blocked? nlm_blocked->b_when : 0);
-	while ((block = nlm_blocked) != 0) {
+	while (!list_empty(&nlm_blocked)) {
+		block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
+
 		if (block->b_when == NLM_NEVER)
 			break;
-	        if (time_after(block->b_when,jiffies))
+	        if (time_after(block->b_when,jiffies)) {
+			timeout = block->b_when - jiffies;
 			break;
+		}
+
 		dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
 			block, block->b_when);
 		kref_get(&block->b_count);
@@ -713,8 +695,5 @@
 		nlmsvc_release_block(block);
 	}
 
-	if ((block = nlm_blocked) && block->b_when != NLM_NEVER)
-		return (block->b_when - jiffies);
-
-	return MAX_SCHEDULE_TIMEOUT;
+	return timeout;
 }
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index dbb66a3..75b2c81 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -66,8 +66,8 @@
 		return nlm_lck_denied_nolocks;
 
 	/* Obtain host handle */
-	if (!(host = nlmsvc_lookup_host(rqstp))
-	 || (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0))
+	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
+	 || (argp->monitor && nsm_monitor(host) < 0))
 		goto no_locks;
 	*hostp = host;
 
@@ -287,7 +287,9 @@
 	struct nlm_rqst	*call;
 	int stat;
 
-	host = nlmsvc_lookup_host(rqstp);
+	host = nlmsvc_lookup_host(rqstp,
+				  argp->lock.caller,
+				  argp->lock.len);
 	if (host == NULL)
 		return rpc_system_err;
 
@@ -449,9 +451,6 @@
 					      void	        *resp)
 {
 	struct sockaddr_in	saddr = rqstp->rq_addr;
-	int			vers = argp->vers;
-	int			prot = argp->proto >> 1;
-	struct nlm_host		*host;
 
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
@@ -466,19 +465,9 @@
 	/* Obtain the host pointer for this NFS server and try to
 	 * reclaim all locks we hold on this server.
 	 */
+	memset(&saddr, 0, sizeof(saddr));
 	saddr.sin_addr.s_addr = argp->addr;
-	if ((argp->proto & 1)==0) {
-		if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
-			nlmclnt_recovery(host, argp->state);
-			nlm_release_host(host);
-		}
-	} else {
-		/* If we run on an NFS server, delete all locks held by the client */
-		if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
-			nlmsvc_free_host_resources(host);
-			nlm_release_host(host);
-		}
-	}
+	nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state);
 
 	return rpc_success;
 }
@@ -495,7 +484,7 @@
 
 	dprintk("lockd: GRANTED_RES   called\n");
 
-	nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status);
+	nlmsvc_grant_reply(&argp->cookie, argp->status);
 	return rpc_success;
 }
 
diff --git a/fs/lockd/svcshare.c b/fs/lockd/svcshare.c
index 27288c8..b9926ce 100644
--- a/fs/lockd/svcshare.c
+++ b/fs/lockd/svcshare.c
@@ -85,24 +85,20 @@
 }
 
 /*
- * Traverse all shares for a given file (and host).
- * NLM_ACT_CHECK is handled by nlmsvc_inspect_file.
+ * Traverse all shares for a given file, and delete
+ * those owned by the given (type of) host
  */
-void
-nlmsvc_traverse_shares(struct nlm_host *host, struct nlm_file *file, int action)
+void nlmsvc_traverse_shares(struct nlm_host *host, struct nlm_file *file,
+		nlm_host_match_fn_t match)
 {
 	struct nlm_share	*share, **shpp;
 
 	shpp = &file->f_shares;
 	while ((share = *shpp) !=  NULL) {
-		if (action == NLM_ACT_MARK)
-			share->s_host->h_inuse = 1;
-		else if (action == NLM_ACT_UNLOCK) {
-			if (host == NULL || host == share->s_host) {
-				*shpp = share->s_next;
-				kfree(share);
-				continue;
-			}
+		if (match(share->s_host, host)) {
+			*shpp = share->s_next;
+			kfree(share);
+			continue;
 		}
 		shpp = &share->s_next;
 	}
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index a92dd98f..514f5f2 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -25,9 +25,9 @@
 /*
  * Global file hash table
  */
-#define FILE_HASH_BITS		5
+#define FILE_HASH_BITS		7
 #define FILE_NRHASH		(1<<FILE_HASH_BITS)
-static struct nlm_file *	nlm_files[FILE_NRHASH];
+static struct hlist_head	nlm_files[FILE_NRHASH];
 static DEFINE_MUTEX(nlm_file_mutex);
 
 #ifdef NFSD_DEBUG
@@ -82,6 +82,7 @@
 nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
 					struct nfs_fh *f)
 {
+	struct hlist_node *pos;
 	struct nlm_file	*file;
 	unsigned int	hash;
 	u32		nfserr;
@@ -93,7 +94,7 @@
 	/* Lock file table */
 	mutex_lock(&nlm_file_mutex);
 
-	for (file = nlm_files[hash]; file; file = file->f_next)
+	hlist_for_each_entry(file, pos, &nlm_files[hash], f_list)
 		if (!nfs_compare_fh(&file->f_handle, f))
 			goto found;
 
@@ -105,8 +106,9 @@
 		goto out_unlock;
 
 	memcpy(&file->f_handle, f, sizeof(struct nfs_fh));
-	file->f_hash = hash;
-	init_MUTEX(&file->f_sema);
+	mutex_init(&file->f_mutex);
+	INIT_HLIST_NODE(&file->f_list);
+	INIT_LIST_HEAD(&file->f_blocks);
 
 	/* Open the file. Note that this must not sleep for too long, else
 	 * we would lock up lockd:-) So no NFS re-exports, folks.
@@ -115,12 +117,11 @@
 	 * the file.
 	 */
 	if ((nfserr = nlmsvc_ops->fopen(rqstp, f, &file->f_file)) != 0) {
-		dprintk("lockd: open failed (nfserr %d)\n", ntohl(nfserr));
+		dprintk("lockd: open failed (error %d)\n", nfserr);
 		goto out_free;
 	}
 
-	file->f_next = nlm_files[hash];
-	nlm_files[hash] = file;
+	hlist_add_head(&file->f_list, &nlm_files[hash]);
 
 found:
 	dprintk("lockd: found file %p (count %d)\n", file, file->f_count);
@@ -149,22 +150,14 @@
 static inline void
 nlm_delete_file(struct nlm_file *file)
 {
-	struct nlm_file	**fp, *f;
-
 	nlm_debug_print_file("closing file", file);
-
-	fp = nlm_files + file->f_hash;
-	while ((f = *fp) != NULL) {
-		if (f == file) {
-			*fp = file->f_next;
-			nlmsvc_ops->fclose(file->f_file);
-			kfree(file);
-			return;
-		}
-		fp = &f->f_next;
+	if (!hlist_unhashed(&file->f_list)) {
+		hlist_del(&file->f_list);
+		nlmsvc_ops->fclose(file->f_file);
+		kfree(file);
+	} else {
+		printk(KERN_WARNING "lockd: attempt to release unknown file!\n");
 	}
-
-	printk(KERN_WARNING "lockd: attempt to release unknown file!\n");
 }
 
 /*
@@ -172,7 +165,8 @@
  * action.
  */
 static int
-nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, int action)
+nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file,
+			nlm_host_match_fn_t match)
 {
 	struct inode	 *inode = nlmsvc_file_inode(file);
 	struct file_lock *fl;
@@ -186,16 +180,10 @@
 
 		/* update current lock count */
 		file->f_locks++;
-		lockhost = (struct nlm_host *) fl->fl_owner;
-		if (action == NLM_ACT_MARK)
-			lockhost->h_inuse = 1;
-		else if (action == NLM_ACT_CHECK)
-			return 1;
-		else if (action == NLM_ACT_UNLOCK) {
-			struct file_lock lock = *fl;
 
-			if (host && lockhost != host)
-				continue;
+		lockhost = (struct nlm_host *) fl->fl_owner;
+		if (match(lockhost, host)) {
+			struct file_lock lock = *fl;
 
 			lock.fl_type  = F_UNLCK;
 			lock.fl_start = 0;
@@ -213,53 +201,66 @@
 }
 
 /*
- * Operate on a single file
+ * Inspect a single file
  */
 static inline int
-nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, int action)
+nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, nlm_host_match_fn_t match)
 {
-	if (action == NLM_ACT_CHECK) {
-		/* Fast path for mark and sweep garbage collection */
-		if (file->f_count || file->f_blocks || file->f_shares)
+	nlmsvc_traverse_blocks(host, file, match);
+	nlmsvc_traverse_shares(host, file, match);
+	return nlm_traverse_locks(host, file, match);
+}
+
+/*
+ * Quick check whether there are still any locks, blocks or
+ * shares on a given file.
+ */
+static inline int
+nlm_file_inuse(struct nlm_file *file)
+{
+	struct inode	 *inode = nlmsvc_file_inode(file);
+	struct file_lock *fl;
+
+	if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares)
+		return 1;
+
+	for (fl = inode->i_flock; fl; fl = fl->fl_next) {
+		if (fl->fl_lmops == &nlmsvc_lock_operations)
 			return 1;
-	} else {
-		nlmsvc_traverse_blocks(host, file, action);
-		nlmsvc_traverse_shares(host, file, action);
 	}
-	return nlm_traverse_locks(host, file, action);
+	file->f_locks = 0;
+	return 0;
 }
 
 /*
  * Loop over all files in the file table.
  */
 static int
-nlm_traverse_files(struct nlm_host *host, int action)
+nlm_traverse_files(struct nlm_host *host, nlm_host_match_fn_t match)
 {
-	struct nlm_file	*file, **fp;
+	struct hlist_node *pos, *next;
+	struct nlm_file	*file;
 	int i, ret = 0;
 
 	mutex_lock(&nlm_file_mutex);
 	for (i = 0; i < FILE_NRHASH; i++) {
-		fp = nlm_files + i;
-		while ((file = *fp) != NULL) {
+		hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) {
 			file->f_count++;
 			mutex_unlock(&nlm_file_mutex);
 
 			/* Traverse locks, blocks and shares of this file
 			 * and update file->f_locks count */
-			if (nlm_inspect_file(host, file, action))
+			if (nlm_inspect_file(host, file, match))
 				ret = 1;
 
 			mutex_lock(&nlm_file_mutex);
 			file->f_count--;
 			/* No more references to this file. Let go of it. */
-			if (!file->f_blocks && !file->f_locks
+			if (list_empty(&file->f_blocks) && !file->f_locks
 			 && !file->f_shares && !file->f_count) {
-				*fp = file->f_next;
+				hlist_del(&file->f_list);
 				nlmsvc_ops->fclose(file->f_file);
 				kfree(file);
-			} else {
-				fp = &file->f_next;
 			}
 		}
 	}
@@ -286,23 +287,54 @@
 	mutex_lock(&nlm_file_mutex);
 
 	/* If there are no more locks etc, delete the file */
-	if(--file->f_count == 0) {
-		if(!nlm_inspect_file(NULL, file, NLM_ACT_CHECK))
-			nlm_delete_file(file);
-	}
+	if (--file->f_count == 0 && !nlm_file_inuse(file))
+		nlm_delete_file(file);
 
 	mutex_unlock(&nlm_file_mutex);
 }
 
 /*
+ * Helpers function for resource traversal
+ *
+ * nlmsvc_mark_host:
+ *	used by the garbage collector; simply sets h_inuse.
+ *	Always returns 0.
+ *
+ * nlmsvc_same_host:
+ *	returns 1 iff the two hosts match. Used to release
+ *	all resources bound to a specific host.
+ *
+ * nlmsvc_is_client:
+ *	returns 1 iff the host is a client.
+ *	Used by nlmsvc_invalidate_all
+ */
+static int
+nlmsvc_mark_host(struct nlm_host *host, struct nlm_host *dummy)
+{
+	host->h_inuse = 1;
+	return 0;
+}
+
+static int
+nlmsvc_same_host(struct nlm_host *host, struct nlm_host *other)
+{
+	return host == other;
+}
+
+static int
+nlmsvc_is_client(struct nlm_host *host, struct nlm_host *dummy)
+{
+	return host->h_server;
+}
+
+/*
  * Mark all hosts that still hold resources
  */
 void
 nlmsvc_mark_resources(void)
 {
 	dprintk("lockd: nlmsvc_mark_resources\n");
-
-	nlm_traverse_files(NULL, NLM_ACT_MARK);
+	nlm_traverse_files(NULL, nlmsvc_mark_host);
 }
 
 /*
@@ -313,23 +345,25 @@
 {
 	dprintk("lockd: nlmsvc_free_host_resources\n");
 
-	if (nlm_traverse_files(host, NLM_ACT_UNLOCK))
+	if (nlm_traverse_files(host, nlmsvc_same_host)) {
 		printk(KERN_WARNING
-			"lockd: couldn't remove all locks held by %s",
+			"lockd: couldn't remove all locks held by %s\n",
 			host->h_name);
+		BUG();
+	}
 }
 
 /*
- * delete all hosts structs for clients
+ * Remove all locks held for clients
  */
 void
 nlmsvc_invalidate_all(void)
 {
-	struct nlm_host *host;
-	while ((host = nlm_find_client()) != NULL) {
-		nlmsvc_free_host_resources(host);
-		host->h_expires = 0;
-		host->h_killed = 1;
-		nlm_release_host(host);
-	}
+	/* Release all locks held by NFS clients.
+	 * Previously, the code would call
+	 * nlmsvc_free_host_resources for each client in
+	 * turn, which is about as inefficient as it gets.
+	 * Now we just do it once in nlm_traverse_files.
+	 */
+	nlm_traverse_files(NULL, nlmsvc_is_client);
 }
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 033ea4a..61c46fa 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -515,7 +515,7 @@
  */
 #define NLM_void_sz		0
 #define NLM_cookie_sz		1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
-#define NLM_caller_sz		1+XDR_QUADLEN(sizeof(system_utsname.nodename))
+#define NLM_caller_sz		1+XDR_QUADLEN(sizeof(utsname()->nodename))
 #define NLM_netobj_sz		1+XDR_QUADLEN(XDR_MAX_NETOBJ)
 /* #define NLM_owner_sz		1+XDR_QUADLEN(NLM_MAXOWNER) */
 #define NLM_fhandle_sz		1+XDR_QUADLEN(NFS2_FHSIZE)
diff --git a/fs/locks.c b/fs/locks.c
index 21dfadf..e0b6a80 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1514,7 +1514,7 @@
 		goto out_unlock;
 	}
 
-	error = f_setown(filp, current->pid, 0);
+	error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
 out_unlock:
 	unlock_kernel();
 	return error;
diff --git a/fs/namespace.c b/fs/namespace.c
index 66d921e..55442a6 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -133,7 +133,7 @@
 
 static inline int check_mnt(struct vfsmount *mnt)
 {
-	return mnt->mnt_namespace == current->namespace;
+	return mnt->mnt_namespace == current->nsproxy->namespace;
 }
 
 static void touch_namespace(struct namespace *ns)
@@ -830,7 +830,7 @@
 	if (parent_nd) {
 		detach_mnt(source_mnt, parent_nd);
 		attach_mnt(source_mnt, nd);
-		touch_namespace(current->namespace);
+		touch_namespace(current->nsproxy->namespace);
 	} else {
 		mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
 		commit_tree(source_mnt);
@@ -1441,7 +1441,7 @@
  */
 struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
 {
-	struct namespace *namespace = tsk->namespace;
+	struct namespace *namespace = tsk->nsproxy->namespace;
 	struct namespace *new_ns;
 	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
 	struct vfsmount *p, *q;
@@ -1508,7 +1508,7 @@
 
 int copy_namespace(int flags, struct task_struct *tsk)
 {
-	struct namespace *namespace = tsk->namespace;
+	struct namespace *namespace = tsk->nsproxy->namespace;
 	struct namespace *new_ns;
 	int err = 0;
 
@@ -1531,7 +1531,7 @@
 		goto out;
 	}
 
-	tsk->namespace = new_ns;
+	tsk->nsproxy->namespace = new_ns;
 
 out:
 	put_namespace(namespace);
@@ -1754,7 +1754,7 @@
 	detach_mnt(user_nd.mnt, &root_parent);
 	attach_mnt(user_nd.mnt, &old_nd);     /* mount old root on put_old */
 	attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
-	touch_namespace(current->namespace);
+	touch_namespace(current->nsproxy->namespace);
 	spin_unlock(&vfsmount_lock);
 	chroot_fs_refs(&user_nd, &new_nd);
 	security_sb_post_pivotroot(&user_nd, &new_nd);
@@ -1780,7 +1780,6 @@
 {
 	struct vfsmount *mnt;
 	struct namespace *namespace;
-	struct task_struct *g, *p;
 
 	mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
 	if (IS_ERR(mnt))
@@ -1796,13 +1795,8 @@
 	namespace->root = mnt;
 	mnt->mnt_namespace = namespace;
 
-	init_task.namespace = namespace;
-	read_lock(&tasklist_lock);
-	do_each_thread(g, p) {
-		get_namespace(namespace);
-		p->namespace = namespace;
-	} while_each_thread(g, p);
-	read_unlock(&tasklist_lock);
+	init_task.nsproxy->namespace = namespace;
+	get_namespace(namespace);
 
 	set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
 	set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a3ee113..7933e2e 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -58,7 +58,6 @@
  */
 static void nfs_callback_svc(struct svc_rqst *rqstp)
 {
-	struct svc_serv *serv = rqstp->rq_server;
 	int err;
 
 	__module_get(THIS_MODULE);
@@ -80,7 +79,7 @@
 		/*
 		 * Listen for a request on the socket
 		 */
-		err = svc_recv(serv, rqstp, MAX_SCHEDULE_TIMEOUT);
+		err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
 		if (err == -EAGAIN || err == -EINTR)
 			continue;
 		if (err < 0) {
@@ -91,7 +90,7 @@
 		}
 		dprintk("%s: request from %u.%u.%u.%u\n", __FUNCTION__,
 				NIPQUAD(rqstp->rq_addr.sin_addr.s_addr));
-		svc_process(serv, rqstp);
+		svc_process(rqstp);
 	}
 
 	svc_exit_thread(rqstp);
@@ -116,7 +115,7 @@
 		goto out;
 	init_completion(&nfs_callback_info.started);
 	init_completion(&nfs_callback_info.stopped);
-	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE);
+	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
 	ret = -ENOMEM;
 	if (!serv)
 		goto out_err;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ec1938d..8106f3b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -460,7 +460,8 @@
 		goto out;
 	if (server->flags & NFS_MOUNT_NONLM)
 		goto out;
-	error = lockd_up();
+	error = lockd_up((server->flags & NFS_MOUNT_TCP) ?
+			IPPROTO_TCP : IPPROTO_UDP);
 	if (error < 0)
 		server->flags |= NFS_MOUNT_NONLM;
 	else
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index c0a754e..1d656a6 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -312,7 +312,7 @@
 	/* Override them by options set on kernel command-line */
 	root_nfs_parse(name, buf);
 
-	cp = system_utsname.nodename;
+	cp = utsname()->nodename;
 	if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
 		printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
 		return -1;
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 01bc68c..e13fa23 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -319,12 +319,25 @@
 
 static struct cache_head *export_table[EXPORT_HASHMAX];
 
+static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
+{
+	int i;
+
+	for (i = 0; i < fsloc->locations_count; i++) {
+		kfree(fsloc->locations[i].path);
+		kfree(fsloc->locations[i].hosts);
+	}
+	kfree(fsloc->locations);
+}
+
 static void svc_export_put(struct kref *ref)
 {
 	struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
 	dput(exp->ex_dentry);
 	mntput(exp->ex_mnt);
 	auth_domain_put(exp->ex_client);
+	kfree(exp->ex_path);
+	nfsd4_fslocs_free(&exp->ex_fslocs);
 	kfree(exp);
 }
 
@@ -370,7 +383,7 @@
 	 */
 	if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
 	    !(flags & NFSEXP_FSID)) {
-		dprintk("exp_export: export of non-dev fs without fsid");
+		dprintk("exp_export: export of non-dev fs without fsid\n");
 		return -EINVAL;
 	}
 	if (!inode->i_sb->s_export_op) {
@@ -386,6 +399,69 @@
 
 }
 
+#ifdef CONFIG_NFSD_V4
+
+static int
+fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
+{
+	int len;
+	int migrated, i, err;
+
+	len = qword_get(mesg, buf, PAGE_SIZE);
+	if (len != 5 || memcmp(buf, "fsloc", 5))
+		return 0;
+
+	/* listsize */
+	err = get_int(mesg, &fsloc->locations_count);
+	if (err)
+		return err;
+	if (fsloc->locations_count > MAX_FS_LOCATIONS)
+		return -EINVAL;
+	if (fsloc->locations_count == 0)
+		return 0;
+
+	fsloc->locations = kzalloc(fsloc->locations_count
+			* sizeof(struct nfsd4_fs_location), GFP_KERNEL);
+	if (!fsloc->locations)
+		return -ENOMEM;
+	for (i=0; i < fsloc->locations_count; i++) {
+		/* colon separated host list */
+		err = -EINVAL;
+		len = qword_get(mesg, buf, PAGE_SIZE);
+		if (len <= 0)
+			goto out_free_all;
+		err = -ENOMEM;
+		fsloc->locations[i].hosts = kstrdup(buf, GFP_KERNEL);
+		if (!fsloc->locations[i].hosts)
+			goto out_free_all;
+		err = -EINVAL;
+		/* slash separated path component list */
+		len = qword_get(mesg, buf, PAGE_SIZE);
+		if (len <= 0)
+			goto out_free_all;
+		err = -ENOMEM;
+		fsloc->locations[i].path = kstrdup(buf, GFP_KERNEL);
+		if (!fsloc->locations[i].path)
+			goto out_free_all;
+	}
+	/* migrated */
+	err = get_int(mesg, &migrated);
+	if (err)
+		goto out_free_all;
+	err = -EINVAL;
+	if (migrated < 0 || migrated > 1)
+		goto out_free_all;
+	fsloc->migrated = migrated;
+	return 0;
+out_free_all:
+	nfsd4_fslocs_free(fsloc);
+	return err;
+}
+
+#else /* CONFIG_NFSD_V4 */
+static inline int fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) { return 0; }
+#endif
+
 static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 {
 	/* client path expiry [flags anonuid anongid fsid] */
@@ -398,6 +474,7 @@
 	int an_int;
 
 	nd.dentry = NULL;
+	exp.ex_path = NULL;
 
 	if (mesg[mlen-1] != '\n')
 		return -EINVAL;
@@ -428,6 +505,10 @@
 	exp.ex_client = dom;
 	exp.ex_mnt = nd.mnt;
 	exp.ex_dentry = nd.dentry;
+	exp.ex_path = kstrdup(buf, GFP_KERNEL);
+	err = -ENOMEM;
+	if (!exp.ex_path)
+		goto out;
 
 	/* expiry */
 	err = -EINVAL;
@@ -435,6 +516,11 @@
 	if (exp.h.expiry_time == 0)
 		goto out;
 
+	/* fs locations */
+	exp.ex_fslocs.locations = NULL;
+	exp.ex_fslocs.locations_count = 0;
+	exp.ex_fslocs.migrated = 0;
+
 	/* flags */
 	err = get_int(&mesg, &an_int);
 	if (err == -ENOENT)
@@ -460,6 +546,10 @@
 
 		err = check_export(nd.dentry->d_inode, exp.ex_flags);
 		if (err) goto out;
+
+		err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
+		if (err)
+			goto out;
 	}
 
 	expp = svc_export_lookup(&exp);
@@ -473,6 +563,7 @@
 	else
 		exp_put(expp);
  out:
+ 	kfree(exp.ex_path);
 	if (nd.dentry)
 		path_release(&nd);
  out_no_path:
@@ -482,7 +573,8 @@
 	return err;
 }
 
-static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong);
+static void exp_flags(struct seq_file *m, int flag, int fsid,
+		uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fslocs);
 
 static int svc_export_show(struct seq_file *m,
 			   struct cache_detail *cd,
@@ -501,8 +593,8 @@
 	seq_putc(m, '(');
 	if (test_bit(CACHE_VALID, &h->flags) && 
 	    !test_bit(CACHE_NEGATIVE, &h->flags))
-		exp_flags(m, exp->ex_flags, exp->ex_fsid, 
-			  exp->ex_anon_uid, exp->ex_anon_gid);
+		exp_flags(m, exp->ex_flags, exp->ex_fsid,
+			  exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
 	seq_puts(m, ")\n");
 	return 0;
 }
@@ -524,6 +616,10 @@
 	new->ex_client = item->ex_client;
 	new->ex_dentry = dget(item->ex_dentry);
 	new->ex_mnt = mntget(item->ex_mnt);
+	new->ex_path = NULL;
+	new->ex_fslocs.locations = NULL;
+	new->ex_fslocs.locations_count = 0;
+	new->ex_fslocs.migrated = 0;
 }
 
 static void export_update(struct cache_head *cnew, struct cache_head *citem)
@@ -535,6 +631,14 @@
 	new->ex_anon_uid = item->ex_anon_uid;
 	new->ex_anon_gid = item->ex_anon_gid;
 	new->ex_fsid = item->ex_fsid;
+	new->ex_path = item->ex_path;
+	item->ex_path = NULL;
+	new->ex_fslocs.locations = item->ex_fslocs.locations;
+	item->ex_fslocs.locations = NULL;
+	new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
+	item->ex_fslocs.locations_count = 0;
+	new->ex_fslocs.migrated = item->ex_fslocs.migrated;
+	item->ex_fslocs.migrated = 0;
 }
 
 static struct cache_head *svc_export_alloc(void)
@@ -1048,36 +1152,28 @@
 exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
 	       struct cache_req *creq)
 {
-	struct svc_expkey *fsid_key;
 	struct svc_export *exp;
 	int rv;
 	u32 fsidv[2];
 
 	mk_fsid_v1(fsidv, 0);
 
-	fsid_key = exp_find_key(clp, 1, fsidv, creq);
-	if (IS_ERR(fsid_key) && PTR_ERR(fsid_key) == -EAGAIN)
+	exp = exp_find(clp, 1, fsidv, creq);
+	if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN)
 		return nfserr_dropit;
-	if (!fsid_key || IS_ERR(fsid_key))
-		return nfserr_perm;
-
-	exp = exp_get_by_name(clp, fsid_key->ek_mnt, fsid_key->ek_dentry, creq);
 	if (exp == NULL)
-		rv = nfserr_perm;
+		return nfserr_perm;
 	else if (IS_ERR(exp))
-		rv = nfserrno(PTR_ERR(exp));
-	else {
-		rv = fh_compose(fhp, exp,
-				fsid_key->ek_dentry, NULL);
-		exp_put(exp);
-	}
-	cache_put(&fsid_key->h, &svc_expkey_cache);
+		return nfserrno(PTR_ERR(exp));
+	rv = fh_compose(fhp, exp, exp->ex_dentry, NULL);
+	exp_put(exp);
 	return rv;
 }
 
 /* Iterator */
 
 static void *e_start(struct seq_file *m, loff_t *pos)
+	__acquires(svc_export_cache.hash_lock)
 {
 	loff_t n = *pos;
 	unsigned hash, export;
@@ -1086,7 +1182,7 @@
 	exp_readlock();
 	read_lock(&svc_export_cache.hash_lock);
 	if (!n--)
-		return (void *)1;
+		return SEQ_START_TOKEN;
 	hash = n >> 32;
 	export = n & ((1LL<<32) - 1);
 
@@ -1110,7 +1206,7 @@
 	struct cache_head *ch = p;
 	int hash = (*pos >> 32);
 
-	if (p == (void *)1)
+	if (p == SEQ_START_TOKEN)
 		hash = 0;
 	else if (ch->next == NULL) {
 		hash++;
@@ -1131,6 +1227,7 @@
 }
 
 static void e_stop(struct seq_file *m, void *p)
+	__releases(svc_export_cache.hash_lock)
 {
 	read_unlock(&svc_export_cache.hash_lock);
 	exp_readunlock();
@@ -1156,7 +1253,8 @@
 	{ 0, {"", ""}}
 };
 
-static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong)
+static void exp_flags(struct seq_file *m, int flag, int fsid,
+		uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fsloc)
 {
 	int first = 0;
 	struct flags *flg;
@@ -1172,21 +1270,34 @@
 		seq_printf(m, "%sanonuid=%d", first++?",":"", anonu);
 	if (anong != (gid_t)-2 && anong != (0x10000-2))
 		seq_printf(m, "%sanongid=%d", first++?",":"", anong);
+	if (fsloc && fsloc->locations_count > 0) {
+		char *loctype = (fsloc->migrated) ? "refer" : "replicas";
+		int i;
+
+		seq_printf(m, "%s%s=", first++?",":"", loctype);
+		seq_escape(m, fsloc->locations[0].path, ",;@ \t\n\\");
+		seq_putc(m, '@');
+		seq_escape(m, fsloc->locations[0].hosts, ",;@ \t\n\\");
+		for (i = 1; i < fsloc->locations_count; i++) {
+			seq_putc(m, ';');
+			seq_escape(m, fsloc->locations[i].path, ",;@ \t\n\\");
+			seq_putc(m, '@');
+			seq_escape(m, fsloc->locations[i].hosts, ",;@ \t\n\\");
+		}
+	}
 }
 
 static int e_show(struct seq_file *m, void *p)
 {
 	struct cache_head *cp = p;
 	struct svc_export *exp = container_of(cp, struct svc_export, h);
-	svc_client *clp;
 
-	if (p == (void *)1) {
+	if (p == SEQ_START_TOKEN) {
 		seq_puts(m, "# Version 1.1\n");
 		seq_puts(m, "# Path Client(Flags) # IPs\n");
 		return 0;
 	}
 
-	clp = exp->ex_client;
 	cache_get(&exp->h);
 	if (cache_check(&svc_export_cache, &exp->h, NULL))
 		return 0;
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index fc95c4d..9187755 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nfsd/nfsacl.c
+ * linux/fs/nfsd/nfs2acl.c
  *
  * Process version 2 NFSACL requests.
  *
@@ -241,7 +241,7 @@
 
 	rqstp->rq_res.page_len = w;
 	while (w > 0) {
-		if (!svc_take_res_page(rqstp))
+		if (!rqstp->rq_respages[rqstp->rq_resused++])
 			return 0;
 		w -= PAGE_SIZE;
 	}
@@ -333,4 +333,5 @@
 		.vs_proc	= nfsd_acl_procedures2,
 		.vs_dispatch	= nfsd_dispatch,
 		.vs_xdrsize	= NFS3_SVC_XDRSIZE,
+		.vs_hidden	= 1,
 };
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 16e10c1..d4bdc00 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -185,7 +185,7 @@
 
 		rqstp->rq_res.page_len = w;
 		while (w > 0) {
-			if (!svc_take_res_page(rqstp))
+			if (!rqstp->rq_respages[rqstp->rq_resused++])
 				return 0;
 			w -= PAGE_SIZE;
 		}
@@ -263,5 +263,6 @@
 		.vs_proc	= nfsd_acl_procedures3,
 		.vs_dispatch	= nfsd_dispatch,
 		.vs_xdrsize	= NFS3_SVC_XDRSIZE,
+		.vs_hidden	= 1,
 };
 
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index f61142a..a5ebc7d 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -160,6 +160,7 @@
 				        struct nfsd3_readres  *resp)
 {
 	int	nfserr;
+	u32	max_blocksize = svc_max_payload(rqstp);
 
 	dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
 				SVCFH_fmt(&argp->fh),
@@ -172,15 +173,15 @@
 	 */
 
 	resp->count = argp->count;
-	if (NFSSVC_MAXBLKSIZE < resp->count)
-		resp->count = NFSSVC_MAXBLKSIZE;
+	if (max_blocksize < resp->count)
+		resp->count = max_blocksize;
 
 	svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
 
 	fh_copy(&resp->fh, &argp->fh);
 	nfserr = nfsd_read(rqstp, &resp->fh, NULL,
 				  argp->offset,
-			   	  argp->vec, argp->vlen,
+			   	  rqstp->rq_vec, argp->vlen,
 				  &resp->count);
 	if (nfserr == 0) {
 		struct inode	*inode = resp->fh.fh_dentry->d_inode;
@@ -210,7 +211,7 @@
 	resp->committed = argp->stable;
 	nfserr = nfsd_write(rqstp, &resp->fh, NULL,
 				   argp->offset,
-				   argp->vec, argp->vlen,
+				   rqstp->rq_vec, argp->vlen,
 				   argp->len,
 				   &resp->committed);
 	resp->count = argp->count;
@@ -538,15 +539,16 @@
 					   struct nfsd3_fsinfores *resp)
 {
 	int	nfserr;
+	u32	max_blocksize = svc_max_payload(rqstp);
 
 	dprintk("nfsd: FSINFO(3)   %s\n",
 				SVCFH_fmt(&argp->fh));
 
-	resp->f_rtmax  = NFSSVC_MAXBLKSIZE;
-	resp->f_rtpref = NFSSVC_MAXBLKSIZE;
+	resp->f_rtmax  = max_blocksize;
+	resp->f_rtpref = max_blocksize;
 	resp->f_rtmult = PAGE_SIZE;
-	resp->f_wtmax  = NFSSVC_MAXBLKSIZE;
-	resp->f_wtpref = NFSSVC_MAXBLKSIZE;
+	resp->f_wtmax  = max_blocksize;
+	resp->f_wtpref = max_blocksize;
 	resp->f_wtmult = PAGE_SIZE;
 	resp->f_dtpref = PAGE_SIZE;
 	resp->f_maxfilesize = ~(u32) 0;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 243d94b..247d518 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -330,6 +330,7 @@
 {
 	unsigned int len;
 	int v,pn;
+	u32 max_blocksize = svc_max_payload(rqstp);
 
 	if (!(p = decode_fh(p, &args->fh))
 	 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -337,17 +338,16 @@
 
 	len = args->count = ntohl(*p++);
 
-	if (len > NFSSVC_MAXBLKSIZE)
-		len = NFSSVC_MAXBLKSIZE;
+	if (len > max_blocksize)
+		len = max_blocksize;
 
 	/* set up the kvec */
 	v=0;
 	while (len > 0) {
-		pn = rqstp->rq_resused;
-		svc_take_page(rqstp);
-		args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
-		args->vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
-		len -= args->vec[v].iov_len;
+		pn = rqstp->rq_resused++;
+		rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
+		rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
+		len -= rqstp->rq_vec[v].iov_len;
 		v++;
 	}
 	args->vlen = v;
@@ -359,6 +359,7 @@
 					struct nfsd3_writeargs *args)
 {
 	unsigned int len, v, hdr;
+	u32 max_blocksize = svc_max_payload(rqstp);
 
 	if (!(p = decode_fh(p, &args->fh))
 	 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -373,22 +374,22 @@
 	    rqstp->rq_arg.len - hdr < len)
 		return 0;
 
-	args->vec[0].iov_base = (void*)p;
-	args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
+	rqstp->rq_vec[0].iov_base = (void*)p;
+	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
 
-	if (len > NFSSVC_MAXBLKSIZE)
-		len = NFSSVC_MAXBLKSIZE;
+	if (len > max_blocksize)
+		len = max_blocksize;
 	v=  0;
-	while (len > args->vec[v].iov_len) {
-		len -= args->vec[v].iov_len;
+	while (len > rqstp->rq_vec[v].iov_len) {
+		len -= rqstp->rq_vec[v].iov_len;
 		v++;
-		args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
-		args->vec[v].iov_len = PAGE_SIZE;
+		rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
+		rqstp->rq_vec[v].iov_len = PAGE_SIZE;
 	}
-	args->vec[v].iov_len = len;
+	rqstp->rq_vec[v].iov_len = len;
 	args->vlen = v+1;
 
-	return args->count == args->len && args->vec[0].iov_len > 0;
+	return args->count == args->len && rqstp->rq_vec[0].iov_len > 0;
 }
 
 int
@@ -446,11 +447,11 @@
 	 * This page appears in the rq_res.pages list, but as pages_len is always
 	 * 0, it won't get in the way
 	 */
-	svc_take_page(rqstp);
 	len = ntohl(*p++);
 	if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
 		return 0;
-	args->tname = new = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+	args->tname = new =
+		page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 	args->tlen = len;
 	/* first copy and check from the first page */
 	old = (char*)p;
@@ -522,8 +523,8 @@
 {
 	if (!(p = decode_fh(p, &args->fh)))
 		return 0;
-	svc_take_page(rqstp);
-	args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+	args->buffer =
+		page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
 	return xdr_argsize_check(rqstp, p);
 }
@@ -554,8 +555,8 @@
 	if (args->count > PAGE_SIZE)
 		args->count = PAGE_SIZE;
 
-	svc_take_page(rqstp);
-	args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+	args->buffer =
+		page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
 	return xdr_argsize_check(rqstp, p);
 }
@@ -565,6 +566,7 @@
 					struct nfsd3_readdirargs *args)
 {
 	int len, pn;
+	u32 max_blocksize = svc_max_payload(rqstp);
 
 	if (!(p = decode_fh(p, &args->fh)))
 		return 0;
@@ -573,13 +575,12 @@
 	args->dircount = ntohl(*p++);
 	args->count    = ntohl(*p++);
 
-	len = (args->count > NFSSVC_MAXBLKSIZE) ? NFSSVC_MAXBLKSIZE :
+	len = (args->count > max_blocksize) ? max_blocksize :
 						  args->count;
 	args->count = len;
 
 	while (len > 0) {
-		pn = rqstp->rq_resused;
-		svc_take_page(rqstp);
+		pn = rqstp->rq_resused++;
 		if (!args->buffer)
 			args->buffer = page_address(rqstp->rq_respages[pn]);
 		len -= PAGE_SIZE;
@@ -668,7 +669,6 @@
 		rqstp->rq_res.page_len = resp->len;
 		if (resp->len & 3) {
 			/* need to pad the tail */
-			rqstp->rq_restailpage = 0;
 			rqstp->rq_res.tail[0].iov_base = p;
 			*p = 0;
 			rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
@@ -693,7 +693,6 @@
 		rqstp->rq_res.page_len = resp->count;
 		if (resp->count & 3) {
 			/* need to pad the tail */
-			rqstp->rq_restailpage = 0;
 			rqstp->rq_res.tail[0].iov_base = p;
 			*p = 0;
 			rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
@@ -768,7 +767,6 @@
 		rqstp->rq_res.page_len = (resp->count) << 2;
 
 		/* add the 'tail' to the end of the 'head' page - page 0. */
-		rqstp->rq_restailpage = 0;
 		rqstp->rq_res.tail[0].iov_base = p;
 		*p++ = 0;		/* no more entries */
 		*p++ = htonl(resp->common.err == nfserr_eof);
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index edb107e..5d94555 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -63,6 +63,8 @@
 #define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
 		| NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
 
+#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS | NFS4_ACE_IDENTIFIER_GROUP)
+
 #define MASK_EQUAL(mask1, mask2) \
 	( ((mask1) & NFS4_ACE_MASK_ALL) == ((mask2) & NFS4_ACE_MASK_ALL) )
 
@@ -96,24 +98,26 @@
 /* XXX: modify functions to return NFS errors; they're only ever
  * used by nfs code, after all.... */
 
-static int
-mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
-{
-	u32 ignore = 0;
+/* We only map from NFSv4 to POSIX ACLs when setting ACLs, when we err on the
+ * side of being more restrictive, so the mode bit mapping below is
+ * pessimistic.  An optimistic version would be needed to handle DENY's,
+ * but we espect to coalesce all ALLOWs and DENYs before mapping to mode
+ * bits. */
 
-	if (!(flags & NFS4_ACL_DIR))
-		ignore |= NFS4_ACE_DELETE_CHILD; /* ignore it */
-	perm |= ignore;
+static void
+low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
+{
+	u32 write_mode = NFS4_WRITE_MODE;
+
+	if (flags & NFS4_ACL_DIR)
+		write_mode |= NFS4_ACE_DELETE_CHILD;
 	*mode = 0;
 	if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE)
 		*mode |= ACL_READ;
-	if ((perm & NFS4_WRITE_MODE) == NFS4_WRITE_MODE)
+	if ((perm & write_mode) == write_mode)
 		*mode |= ACL_WRITE;
 	if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE)
 		*mode |= ACL_EXECUTE;
-	if (!MASK_EQUAL(perm, ignore|mask_from_posix(*mode, flags)))
-		return -EINVAL;
-	return 0;
 }
 
 struct ace_container {
@@ -338,38 +342,6 @@
 	return;
 }
 
-static int
-write_pace(struct nfs4_ace *ace, struct posix_acl *pacl,
-		struct posix_acl_entry **pace, short tag, unsigned int flags)
-{
-	struct posix_acl_entry *this = *pace;
-
-	if (*pace == pacl->a_entries + pacl->a_count)
-		return -EINVAL; /* fell off the end */
-	(*pace)++;
-	this->e_tag = tag;
-	if (tag == ACL_USER_OBJ)
-		flags |= NFS4_ACL_OWNER;
-	if (mode_from_nfs4(ace->access_mask, &this->e_perm, flags))
-		return -EINVAL;
-	this->e_id = (tag == ACL_USER || tag == ACL_GROUP ?
-			ace->who : ACL_UNDEFINED_ID);
-	return 0;
-}
-
-static struct nfs4_ace *
-get_next_v4_ace(struct list_head **p, struct list_head *head)
-{
-	struct nfs4_ace *ace;
-
-	*p = (*p)->next;
-	if (*p == head)
-		return NULL;
-	ace = list_entry(*p, struct nfs4_ace, l_ace);
-
-	return ace;
-}
-
 int
 nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
 		struct posix_acl **dpacl, unsigned int flags)
@@ -385,42 +357,23 @@
 		goto out;
 
 	error = nfs4_acl_split(acl, dacl);
-	if (error < 0)
+	if (error)
 		goto out_acl;
 
-	if (pacl != NULL) {
-		if (acl->naces == 0) {
-			error = -ENODATA;
-			goto try_dpacl;
-		}
-
-		*pacl = _nfsv4_to_posix_one(acl, flags);
-		if (IS_ERR(*pacl)) {
-			error = PTR_ERR(*pacl);
-			*pacl = NULL;
-			goto out_acl;
-		}
+	*pacl = _nfsv4_to_posix_one(acl, flags);
+	if (IS_ERR(*pacl)) {
+		error = PTR_ERR(*pacl);
+		*pacl = NULL;
+		goto out_acl;
 	}
 
-try_dpacl:
-	if (dpacl != NULL) {
-		if (dacl->naces == 0) {
-			if (pacl == NULL || *pacl == NULL)
-				error = -ENODATA;
-			goto out_acl;
-		}
-
-		error = 0;
-		*dpacl = _nfsv4_to_posix_one(dacl, flags);
-		if (IS_ERR(*dpacl)) {
-			error = PTR_ERR(*dpacl);
-			*dpacl = NULL;
-			goto out_acl;
-		}
+	*dpacl = _nfsv4_to_posix_one(dacl, flags);
+	if (IS_ERR(*dpacl)) {
+		error = PTR_ERR(*dpacl);
+		*dpacl = NULL;
 	}
-
 out_acl:
-	if (error && pacl) {
+	if (error) {
 		posix_acl_release(*pacl);
 		*pacl = NULL;
 	}
@@ -429,349 +382,311 @@
 	return error;
 }
 
-static int
-same_who(struct nfs4_ace *a, struct nfs4_ace *b)
-{
-	return a->whotype == b->whotype &&
-		(a->whotype != NFS4_ACL_WHO_NAMED || a->who == b->who);
-}
+/*
+ * While processing the NFSv4 ACE, this maintains bitmasks representing
+ * which permission bits have been allowed and which denied to a given
+ * entity: */
+struct posix_ace_state {
+	u32 allow;
+	u32 deny;
+};
+
+struct posix_user_ace_state {
+	uid_t uid;
+	struct posix_ace_state perms;
+};
+
+struct posix_ace_state_array {
+	int n;
+	struct posix_user_ace_state aces[];
+};
+
+/*
+ * While processing the NFSv4 ACE, this maintains the partial permissions
+ * calculated so far: */
+
+struct posix_acl_state {
+	struct posix_ace_state owner;
+	struct posix_ace_state group;
+	struct posix_ace_state other;
+	struct posix_ace_state everyone;
+	struct posix_ace_state mask; /* Deny unused in this case */
+	struct posix_ace_state_array *users;
+	struct posix_ace_state_array *groups;
+};
 
 static int
-complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny,
-		unsigned int flags)
+init_state(struct posix_acl_state *state, int cnt)
 {
-	int ignore = 0;
-	if (!(flags & NFS4_ACL_DIR))
-		ignore |= NFS4_ACE_DELETE_CHILD;
-	return MASK_EQUAL(ignore|deny_mask(allow->access_mask, flags),
-			  ignore|deny->access_mask) &&
-		allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
-		deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE &&
-		allow->flag == deny->flag &&
-		same_who(allow, deny);
+	int alloc;
+
+	memset(state, 0, sizeof(struct posix_acl_state));
+	/*
+	 * In the worst case, each individual acl could be for a distinct
+	 * named user or group, but we don't no which, so we allocate
+	 * enough space for either:
+	 */
+	alloc = sizeof(struct posix_ace_state_array)
+		+ cnt*sizeof(struct posix_ace_state);
+	state->users = kzalloc(alloc, GFP_KERNEL);
+	if (!state->users)
+		return -ENOMEM;
+	state->groups = kzalloc(alloc, GFP_KERNEL);
+	if (!state->groups) {
+		kfree(state->users);
+		return -ENOMEM;
+	}
+	return 0;
 }
 
-static inline int
-user_obj_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-		struct posix_acl *pacl, struct posix_acl_entry **pace,
-		unsigned int flags)
-{
-	int error = -EINVAL;
-	struct nfs4_ace *ace, *ace2;
-
-	ace = get_next_v4_ace(p, &n4acl->ace_head);
-	if (ace == NULL)
-		goto out;
-	if (ace2type(ace) != ACL_USER_OBJ)
-		goto out;
-	error = write_pace(ace, pacl, pace, ACL_USER_OBJ, flags);
-	if (error < 0)
-		goto out;
-	error = -EINVAL;
-	ace2 = get_next_v4_ace(p, &n4acl->ace_head);
-	if (ace2 == NULL)
-		goto out;
-	if (!complementary_ace_pair(ace, ace2, flags))
-		goto out;
-	error = 0;
-out:
-	return error;
+static void
+free_state(struct posix_acl_state *state) {
+	kfree(state->users);
+	kfree(state->groups);
 }
 
-static inline int
-users_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-		struct nfs4_ace **mask_ace,
-		struct posix_acl *pacl, struct posix_acl_entry **pace,
-		unsigned int flags)
+static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate)
 {
-	int error = -EINVAL;
-	struct nfs4_ace *ace, *ace2;
-
-	ace = get_next_v4_ace(p, &n4acl->ace_head);
-	if (ace == NULL)
-		goto out;
-	while (ace2type(ace) == ACL_USER) {
-		if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
-			goto out;
-		if (*mask_ace &&
-			!MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
-			goto out;
-		*mask_ace = ace;
-		ace = get_next_v4_ace(p, &n4acl->ace_head);
-		if (ace == NULL)
-			goto out;
-		if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
-			goto out;
-		error = write_pace(ace, pacl, pace, ACL_USER, flags);
-		if (error < 0)
-			goto out;
-		error = -EINVAL;
-		ace2 = get_next_v4_ace(p, &n4acl->ace_head);
-		if (ace2 == NULL)
-			goto out;
-		if (!complementary_ace_pair(ace, ace2, flags))
-			goto out;
-		if ((*mask_ace)->flag != ace2->flag ||
-				!same_who(*mask_ace, ace2))
-			goto out;
-		ace = get_next_v4_ace(p, &n4acl->ace_head);
-		if (ace == NULL)
-			goto out;
-	}
-	error = 0;
-out:
-	return error;
+	state->mask.allow |= astate->allow;
 }
 
-static inline int
-group_obj_and_groups_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-		struct nfs4_ace **mask_ace,
-		struct posix_acl *pacl, struct posix_acl_entry **pace,
-		unsigned int flags)
+/*
+ * Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
+ * READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
+ * to traditional read/write/execute permissions.
+ *
+ * It's problematic to reject acls that use certain mode bits, because it
+ * places the burden on users to learn the rules about which bits one
+ * particular server sets, without giving the user a lot of help--we return an
+ * error that could mean any number of different things.  To make matters
+ * worse, the problematic bits might be introduced by some application that's
+ * automatically mapping from some other acl model.
+ *
+ * So wherever possible we accept anything, possibly erring on the side of
+ * denying more permissions than necessary.
+ *
+ * However we do reject *explicit* DENY's of a few bits representing
+ * permissions we could never deny:
+ */
+
+static inline int check_deny(u32 mask, int isowner)
 {
-	int error = -EINVAL;
-	struct nfs4_ace *ace, *ace2;
-	struct ace_container *ac;
-	struct list_head group_l;
-
-	INIT_LIST_HEAD(&group_l);
-	ace = list_entry(*p, struct nfs4_ace, l_ace);
-
-	/* group owner (mask and allow aces) */
-
-	if (pacl->a_count != 3) {
-		/* then the group owner should be preceded by mask */
-		if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
-			goto out;
-		if (*mask_ace &&
-			!MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
-			goto out;
-		*mask_ace = ace;
-		ace = get_next_v4_ace(p, &n4acl->ace_head);
-		if (ace == NULL)
-			goto out;
-
-		if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace))
-			goto out;
-	}
-
-	if (ace2type(ace) != ACL_GROUP_OBJ)
-		goto out;
-
-	ac = kmalloc(sizeof(*ac), GFP_KERNEL);
-	error = -ENOMEM;
-	if (ac == NULL)
-		goto out;
-	ac->ace = ace;
-	list_add_tail(&ac->ace_l, &group_l);
-
-	error = -EINVAL;
-	if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
-		goto out;
-
-	error = write_pace(ace, pacl, pace, ACL_GROUP_OBJ, flags);
-	if (error < 0)
-		goto out;
-
-	error = -EINVAL;
-	ace = get_next_v4_ace(p, &n4acl->ace_head);
-	if (ace == NULL)
-		goto out;
-
-	/* groups (mask and allow aces) */
-
-	while (ace2type(ace) == ACL_GROUP) {
-		if (*mask_ace == NULL)
-			goto out;
-
-		if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE ||
-			!MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
-			goto out;
-		*mask_ace = ace;
-
-		ace = get_next_v4_ace(p, &n4acl->ace_head);
-		if (ace == NULL)
-			goto out;
-		ac = kmalloc(sizeof(*ac), GFP_KERNEL);
-		error = -ENOMEM;
-		if (ac == NULL)
-			goto out;
-		error = -EINVAL;
-		if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE ||
-				!same_who(ace, *mask_ace))
-			goto out;
-
-		ac->ace = ace;
-		list_add_tail(&ac->ace_l, &group_l);
-
-		error = write_pace(ace, pacl, pace, ACL_GROUP, flags);
-		if (error < 0)
-			goto out;
-		error = -EINVAL;
-		ace = get_next_v4_ace(p, &n4acl->ace_head);
-		if (ace == NULL)
-			goto out;
-	}
-
-	/* group owner (deny ace) */
-
-	if (ace2type(ace) != ACL_GROUP_OBJ)
-		goto out;
-	ac = list_entry(group_l.next, struct ace_container, ace_l);
-	ace2 = ac->ace;
-	if (!complementary_ace_pair(ace2, ace, flags))
-		goto out;
-	list_del(group_l.next);
-	kfree(ac);
-
-	/* groups (deny aces) */
-
-	while (!list_empty(&group_l)) {
-		ace = get_next_v4_ace(p, &n4acl->ace_head);
-		if (ace == NULL)
-			goto out;
-		if (ace2type(ace) != ACL_GROUP)
-			goto out;
-		ac = list_entry(group_l.next, struct ace_container, ace_l);
-		ace2 = ac->ace;
-		if (!complementary_ace_pair(ace2, ace, flags))
-			goto out;
-		list_del(group_l.next);
-		kfree(ac);
-	}
-
-	ace = get_next_v4_ace(p, &n4acl->ace_head);
-	if (ace == NULL)
-		goto out;
-	if (ace2type(ace) != ACL_OTHER)
-		goto out;
-	error = 0;
-out:
-	while (!list_empty(&group_l)) {
-		ac = list_entry(group_l.next, struct ace_container, ace_l);
-		list_del(group_l.next);
-		kfree(ac);
-	}
-	return error;
+	if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
+		return -EINVAL;
+	if (!isowner)
+		return 0;
+	if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
+		return -EINVAL;
+	return 0;
 }
 
-static inline int
-mask_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-		struct nfs4_ace **mask_ace,
-		struct posix_acl *pacl, struct posix_acl_entry **pace,
-		unsigned int flags)
+static struct posix_acl *
+posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 {
-	int error = -EINVAL;
-	struct nfs4_ace *ace;
+	struct posix_acl_entry *pace;
+	struct posix_acl *pacl;
+	int nace;
+	int i, error = 0;
 
-	ace = list_entry(*p, struct nfs4_ace, l_ace);
-	if (pacl->a_count != 3) {
-		if (*mask_ace == NULL)
-			goto out;
-		(*mask_ace)->access_mask = deny_mask((*mask_ace)->access_mask, flags);
-		write_pace(*mask_ace, pacl, pace, ACL_MASK, flags);
+	nace = 4 + state->users->n + state->groups->n;
+	pacl = posix_acl_alloc(nace, GFP_KERNEL);
+	if (!pacl)
+		return ERR_PTR(-ENOMEM);
+
+	pace = pacl->a_entries;
+	pace->e_tag = ACL_USER_OBJ;
+	error = check_deny(state->owner.deny, 1);
+	if (error)
+		goto out_err;
+	low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
+	pace->e_id = ACL_UNDEFINED_ID;
+
+	for (i=0; i < state->users->n; i++) {
+		pace++;
+		pace->e_tag = ACL_USER;
+		error = check_deny(state->users->aces[i].perms.deny, 0);
+		if (error)
+			goto out_err;
+		low_mode_from_nfs4(state->users->aces[i].perms.allow,
+					&pace->e_perm, flags);
+		pace->e_id = state->users->aces[i].uid;
+		add_to_mask(state, &state->users->aces[i].perms);
 	}
-	error = 0;
-out:
-	return error;
+
+	pace++;
+	pace->e_tag = ACL_GROUP_OBJ;
+	error = check_deny(state->group.deny, 0);
+	if (error)
+		goto out_err;
+	low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
+	pace->e_id = ACL_UNDEFINED_ID;
+	add_to_mask(state, &state->group);
+
+	for (i=0; i < state->groups->n; i++) {
+		pace++;
+		pace->e_tag = ACL_GROUP;
+		error = check_deny(state->groups->aces[i].perms.deny, 0);
+		if (error)
+			goto out_err;
+		low_mode_from_nfs4(state->groups->aces[i].perms.allow,
+					&pace->e_perm, flags);
+		pace->e_id = state->groups->aces[i].uid;
+		add_to_mask(state, &state->groups->aces[i].perms);
+	}
+
+	pace++;
+	pace->e_tag = ACL_MASK;
+	low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
+	pace->e_id = ACL_UNDEFINED_ID;
+
+	pace++;
+	pace->e_tag = ACL_OTHER;
+	error = check_deny(state->other.deny, 0);
+	if (error)
+		goto out_err;
+	low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
+	pace->e_id = ACL_UNDEFINED_ID;
+
+	return pacl;
+out_err:
+	posix_acl_release(pacl);
+	return ERR_PTR(error);
 }
 
-static inline int
-other_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-		struct posix_acl *pacl, struct posix_acl_entry **pace,
-		unsigned int flags)
+static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
 {
-	int error = -EINVAL;
-	struct nfs4_ace *ace, *ace2;
-
-	ace = list_entry(*p, struct nfs4_ace, l_ace);
-	if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
-		goto out;
-	error = write_pace(ace, pacl, pace, ACL_OTHER, flags);
-	if (error < 0)
-		goto out;
-	error = -EINVAL;
-	ace2 = get_next_v4_ace(p, &n4acl->ace_head);
-	if (ace2 == NULL)
-		goto out;
-	if (!complementary_ace_pair(ace, ace2, flags))
-		goto out;
-	error = 0;
-out:
-	return error;
+	/* Allow all bits in the mask not already denied: */
+	astate->allow |= mask & ~astate->deny;
 }
 
-static int
-calculate_posix_ace_count(struct nfs4_acl *n4acl)
+static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
 {
-	if (n4acl->naces == 6) /* owner, owner group, and other only */
-		return 3;
-	else { /* Otherwise there must be a mask entry. */
-		/* Also, the remaining entries are for named users and
-		 * groups, and come in threes (mask, allow, deny): */
-		if (n4acl->naces < 7)
-			return -EINVAL;
-		if ((n4acl->naces - 7) % 3)
-			return -EINVAL;
-		return 4 + (n4acl->naces - 7)/3;
+	/* Deny all bits in the mask not already allowed: */
+	astate->deny |= mask & ~astate->allow;
+}
+
+static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
+{
+	int i;
+
+	for (i = 0; i < a->n; i++)
+		if (a->aces[i].uid == uid)
+			return i;
+	/* Not found: */
+	a->n++;
+	a->aces[i].uid = uid;
+	a->aces[i].perms.allow = state->everyone.allow;
+	a->aces[i].perms.deny  = state->everyone.deny;
+
+	return i;
+}
+
+static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
+{
+	int i;
+
+	for (i=0; i < a->n; i++)
+		deny_bits(&a->aces[i].perms, mask);
+}
+
+static void allow_bits_array(struct posix_ace_state_array *a, u32 mask)
+{
+	int i;
+
+	for (i=0; i < a->n; i++)
+		allow_bits(&a->aces[i].perms, mask);
+}
+
+static void process_one_v4_ace(struct posix_acl_state *state,
+				struct nfs4_ace *ace)
+{
+	u32 mask = ace->access_mask;
+	int i;
+
+	switch (ace2type(ace)) {
+	case ACL_USER_OBJ:
+		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+			allow_bits(&state->owner, mask);
+		} else {
+			deny_bits(&state->owner, mask);
+		}
+		break;
+	case ACL_USER:
+		i = find_uid(state, state->users, ace->who);
+		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+			allow_bits(&state->users->aces[i].perms, mask);
+		} else {
+			deny_bits(&state->users->aces[i].perms, mask);
+			mask = state->users->aces[i].perms.deny;
+			deny_bits(&state->owner, mask);
+		}
+		break;
+	case ACL_GROUP_OBJ:
+		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+			allow_bits(&state->group, mask);
+		} else {
+			deny_bits(&state->group, mask);
+			mask = state->group.deny;
+			deny_bits(&state->owner, mask);
+			deny_bits(&state->everyone, mask);
+			deny_bits_array(state->users, mask);
+			deny_bits_array(state->groups, mask);
+		}
+		break;
+	case ACL_GROUP:
+		i = find_uid(state, state->groups, ace->who);
+		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+			allow_bits(&state->groups->aces[i].perms, mask);
+		} else {
+			deny_bits(&state->groups->aces[i].perms, mask);
+			mask = state->groups->aces[i].perms.deny;
+			deny_bits(&state->owner, mask);
+			deny_bits(&state->group, mask);
+			deny_bits(&state->everyone, mask);
+			deny_bits_array(state->users, mask);
+			deny_bits_array(state->groups, mask);
+		}
+		break;
+	case ACL_OTHER:
+		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+			allow_bits(&state->owner, mask);
+			allow_bits(&state->group, mask);
+			allow_bits(&state->other, mask);
+			allow_bits(&state->everyone, mask);
+			allow_bits_array(state->users, mask);
+			allow_bits_array(state->groups, mask);
+		} else {
+			deny_bits(&state->owner, mask);
+			deny_bits(&state->group, mask);
+			deny_bits(&state->other, mask);
+			deny_bits(&state->everyone, mask);
+			deny_bits_array(state->users, mask);
+			deny_bits_array(state->groups, mask);
+		}
 	}
 }
 
-
 static struct posix_acl *
 _nfsv4_to_posix_one(struct nfs4_acl *n4acl, unsigned int flags)
 {
+	struct posix_acl_state state;
 	struct posix_acl *pacl;
-	int error = -EINVAL, nace = 0;
-	struct list_head *p;
-	struct nfs4_ace *mask_ace = NULL;
-	struct posix_acl_entry *pace;
+	struct nfs4_ace *ace;
+	int ret;
 
-	nace = calculate_posix_ace_count(n4acl);
-	if (nace < 0)
-		goto out_err;
+	ret = init_state(&state, n4acl->naces);
+	if (ret)
+		return ERR_PTR(ret);
 
-	pacl = posix_acl_alloc(nace, GFP_KERNEL);
-	error = -ENOMEM;
-	if (pacl == NULL)
-		goto out_err;
+	list_for_each_entry(ace, &n4acl->ace_head, l_ace)
+		process_one_v4_ace(&state, ace);
 
-	pace = &pacl->a_entries[0];
-	p = &n4acl->ace_head;
+	pacl = posix_state_to_acl(&state, flags);
 
-	error = user_obj_from_v4(n4acl, &p, pacl, &pace, flags);
-	if (error)
-		goto out_acl;
+	free_state(&state);
 
-	error = users_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
-	if (error)
-		goto out_acl;
-
-	error = group_obj_and_groups_from_v4(n4acl, &p, &mask_ace, pacl, &pace,
-						flags);
-	if (error)
-		goto out_acl;
-
-	error = mask_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
-	if (error)
-		goto out_acl;
-	error = other_from_v4(n4acl, &p, pacl, &pace, flags);
-	if (error)
-		goto out_acl;
-
-	error = -EINVAL;
-	if (p->next != &n4acl->ace_head)
-		goto out_acl;
-	if (pace != pacl->a_entries + pacl->a_count)
-		goto out_acl;
-
-	sort_pacl(pacl);
-
-	return pacl;
-out_acl:
-	posix_acl_release(pacl);
-out_err:
-	pacl = ERR_PTR(error);
+	if (!IS_ERR(pacl))
+		sort_pacl(pacl);
 	return pacl;
 }
 
@@ -785,22 +700,41 @@
 	list_for_each_safe(h, n, &acl->ace_head) {
 		ace = list_entry(h, struct nfs4_ace, l_ace);
 
-		if ((ace->flag & NFS4_INHERITANCE_FLAGS)
-				!= NFS4_INHERITANCE_FLAGS)
+		if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
+		    ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
+			return -EINVAL;
+
+		if (ace->flag & ~NFS4_SUPPORTED_FLAGS)
+			return -EINVAL;
+
+		switch (ace->flag & NFS4_INHERITANCE_FLAGS) {
+		case 0:
+			/* Leave this ace in the effective acl: */
 			continue;
-
-		error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
+		case NFS4_INHERITANCE_FLAGS:
+			/* Add this ace to the default acl and remove it
+			 * from the effective acl: */
+			error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
 				ace->access_mask, ace->whotype, ace->who);
-		if (error < 0)
-			goto out;
-
-		list_del(h);
-		kfree(ace);
-		acl->naces--;
+			if (error)
+				return error;
+			list_del(h);
+			kfree(ace);
+			acl->naces--;
+			break;
+		case NFS4_INHERITANCE_FLAGS & ~NFS4_ACE_INHERIT_ONLY_ACE:
+			/* Add this ace to the default, but leave it in
+			 * the effective acl as well: */
+			error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
+				ace->access_mask, ace->whotype, ace->who);
+			if (error)
+				return error;
+			break;
+		default:
+			return -EINVAL;
+		}
 	}
-
-out:
-	return error;
+	return 0;
 }
 
 static short
@@ -930,23 +864,6 @@
 	return -1;
 }
 
-static inline int
-match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
-{
-	switch (ace->whotype) {
-		case NFS4_ACL_WHO_NAMED:
-			return who == ace->who;
-		case NFS4_ACL_WHO_OWNER:
-			return who == owner;
-		case NFS4_ACL_WHO_GROUP:
-			return who == group;
-		case NFS4_ACL_WHO_EVERYONE:
-			return 1;
-		default:
-			return 0;
-	}
-}
-
 EXPORT_SYMBOL(nfs4_acl_new);
 EXPORT_SYMBOL(nfs4_acl_free);
 EXPORT_SYMBOL(nfs4_acl_add_ace);
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 8583d99..f6ca9fb 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -131,7 +131,7 @@
 #define READ_BUF(nbytes)  do { \
 	p = xdr_inline_decode(xdr, nbytes); \
 	if (!p) { \
-		dprintk("NFSD: %s: reply buffer overflowed in line %d.", \
+		dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \
 			__FUNCTION__, __LINE__); \
 		return -EIO; \
 	} \
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index ee4eff2..8333db1 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -600,7 +600,7 @@
 			&setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
 		nfs4_unlock_state();
 		if (status) {
-			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!");
+			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
 			return status;
 		}
 	}
@@ -646,7 +646,7 @@
 	*p++ = nfssvc_boot.tv_usec;
 
 	status =  nfsd_write(rqstp, current_fh, filp, write->wr_offset,
-			write->wr_vec, write->wr_vlen, write->wr_buflen,
+			rqstp->rq_vec, write->wr_vlen, write->wr_buflen,
 			&write->wr_how_written);
 	if (filp)
 		fput(filp);
@@ -802,13 +802,29 @@
 		* SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
 		* require a valid current filehandle
 		*/
-		if ((!current_fh->fh_dentry) &&
-		   !((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) ||
-		   (op->opnum == OP_SETCLIENTID) ||
-		   (op->opnum == OP_SETCLIENTID_CONFIRM) ||
-		   (op->opnum == OP_RENEW) || (op->opnum == OP_RESTOREFH) ||
-		   (op->opnum == OP_RELEASE_LOCKOWNER))) {
-			op->status = nfserr_nofilehandle;
+		if (!current_fh->fh_dentry) {
+			if (!((op->opnum == OP_PUTFH) ||
+			      (op->opnum == OP_PUTROOTFH) ||
+			      (op->opnum == OP_SETCLIENTID) ||
+			      (op->opnum == OP_SETCLIENTID_CONFIRM) ||
+			      (op->opnum == OP_RENEW) ||
+			      (op->opnum == OP_RESTOREFH) ||
+			      (op->opnum == OP_RELEASE_LOCKOWNER))) {
+				op->status = nfserr_nofilehandle;
+				goto encode_op;
+			}
+		}
+		/* Check must be done at start of each operation, except
+		 * for GETATTR and ops not listed as returning NFS4ERR_MOVED
+		 */
+		else if (current_fh->fh_export->ex_fslocs.migrated &&
+			 !((op->opnum == OP_GETATTR) ||
+			   (op->opnum == OP_PUTROOTFH) ||
+			   (op->opnum == OP_PUTPUBFH) ||
+			   (op->opnum == OP_RENEW) ||
+			   (op->opnum == OP_SETCLIENTID) ||
+			   (op->opnum == OP_RELEASE_LOCKOWNER))) {
+			op->status = nfserr_moved;
 			goto encode_op;
 		}
 		switch (op->opnum) {
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index e35d7e5..1cbd2e4 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -184,7 +184,7 @@
 
 static int
 nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
-		loff_t offset, ino_t ino, unsigned int d_type)
+		loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct dentry_list_arg *dla = arg;
 	struct list_head *dentries = &dla->dentries;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5446a08..41fc241 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -60,6 +60,14 @@
 
 #define NFSDDBG_FACILITY		NFSDDBG_XDR
 
+/*
+ * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
+ * directory in order to indicate to the client that a filesystem boundary is present
+ * We use a fixed fsid for a referral
+ */
+#define NFS4_REFERRAL_FSID_MAJOR	0x8000000ULL
+#define NFS4_REFERRAL_FSID_MINOR	0x8000000ULL
+
 static int
 check_filename(char *str, int len, int err)
 {
@@ -198,8 +206,7 @@
 		p = new;
 		memcpy(p, argp->tmp, nbytes);
 	} else {
-		if (p != argp->tmpp)
-			BUG();
+		BUG_ON(p != argp->tmpp);
 		argp->tmpp = NULL;
 	}
 	if (defer_free(argp, kfree, p)) {
@@ -927,26 +934,26 @@
 		printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); 
 		goto xdr_error;
 	}
-	write->wr_vec[0].iov_base = p;
-	write->wr_vec[0].iov_len = avail;
+	argp->rqstp->rq_vec[0].iov_base = p;
+	argp->rqstp->rq_vec[0].iov_len = avail;
 	v = 0;
 	len = write->wr_buflen;
-	while (len > write->wr_vec[v].iov_len) {
-		len -= write->wr_vec[v].iov_len;
+	while (len > argp->rqstp->rq_vec[v].iov_len) {
+		len -= argp->rqstp->rq_vec[v].iov_len;
 		v++;
-		write->wr_vec[v].iov_base = page_address(argp->pagelist[0]);
+		argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]);
 		argp->pagelist++;
 		if (argp->pagelen >= PAGE_SIZE) {
-			write->wr_vec[v].iov_len = PAGE_SIZE;
+			argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE;
 			argp->pagelen -= PAGE_SIZE;
 		} else {
-			write->wr_vec[v].iov_len = argp->pagelen;
+			argp->rqstp->rq_vec[v].iov_len = argp->pagelen;
 			argp->pagelen -= len;
 		}
 	}
-	argp->end = (u32*) (write->wr_vec[v].iov_base + write->wr_vec[v].iov_len);
-	argp->p = (u32*)  (write->wr_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
-	write->wr_vec[v].iov_len = len;
+	argp->end = (u32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
+	argp->p = (u32*)  (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
+	argp->rqstp->rq_vec[v].iov_len = len;
 	write->wr_vlen = v+1;
 
 	DECODE_TAIL;
@@ -1224,6 +1231,119 @@
  			stateowner->so_replay.rp_buflen); 	\
 	} } while (0);
 
+/* Encode as an array of strings the string given with components
+ * seperated @sep.
+ */
+static int nfsd4_encode_components(char sep, char *components,
+				   u32 **pp, int *buflen)
+{
+	u32 *p = *pp;
+	u32 *countp = p;
+	int strlen, count=0;
+	char *str, *end;
+
+	dprintk("nfsd4_encode_components(%s)\n", components);
+	if ((*buflen -= 4) < 0)
+		return nfserr_resource;
+	WRITE32(0); /* We will fill this in with @count later */
+	end = str = components;
+	while (*end) {
+		for (; *end && (*end != sep); end++)
+			; /* Point to end of component */
+		strlen = end - str;
+		if (strlen) {
+			if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
+				return nfserr_resource;
+			WRITE32(strlen);
+			WRITEMEM(str, strlen);
+			count++;
+		}
+		else
+			end++;
+		str = end;
+	}
+	*pp = p;
+	p = countp;
+	WRITE32(count);
+	return 0;
+}
+
+/*
+ * encode a location element of a fs_locations structure
+ */
+static int nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
+				    u32 **pp, int *buflen)
+{
+	int status;
+	u32 *p = *pp;
+
+	status = nfsd4_encode_components(':', location->hosts, &p, buflen);
+	if (status)
+		return status;
+	status = nfsd4_encode_components('/', location->path, &p, buflen);
+	if (status)
+		return status;
+	*pp = p;
+	return 0;
+}
+
+/*
+ * Return the path to an export point in the pseudo filesystem namespace
+ * Returned string is safe to use as long as the caller holds a reference
+ * to @exp.
+ */
+static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp)
+{
+	struct svc_fh tmp_fh;
+	char *path, *rootpath;
+	int stat;
+
+	fh_init(&tmp_fh, NFS4_FHSIZE);
+	stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle);
+	if (stat)
+		return ERR_PTR(stat);
+	rootpath = tmp_fh.fh_export->ex_path;
+
+	path = exp->ex_path;
+
+	if (strncmp(path, rootpath, strlen(rootpath))) {
+		printk("nfsd: fs_locations failed;"
+			"%s is not contained in %s\n", path, rootpath);
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+
+	return path + strlen(rootpath);
+}
+
+/*
+ *  encode a fs_locations structure
+ */
+static int nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
+				     struct svc_export *exp,
+				     u32 **pp, int *buflen)
+{
+	int status, i;
+	u32 *p = *pp;
+	struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
+	char *root = nfsd4_path(rqstp, exp);
+
+	if (IS_ERR(root))
+		return PTR_ERR(root);
+	status = nfsd4_encode_components('/', root, &p, buflen);
+	if (status)
+		return status;
+	if ((*buflen -= 4) < 0)
+		return nfserr_resource;
+	WRITE32(fslocs->locations_count);
+	for (i=0; i<fslocs->locations_count; i++) {
+		status = nfsd4_encode_fs_location4(&fslocs->locations[i],
+						   &p, buflen);
+		if (status)
+			return status;
+	}
+	*pp = p;
+	return 0;
+}
 
 static u32 nfs4_ftypes[16] = {
         NF4BAD,  NF4FIFO, NF4CHR, NF4BAD,
@@ -1273,6 +1393,25 @@
 	return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
 }
 
+#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
+			      FATTR4_WORD0_RDATTR_ERROR)
+#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
+
+static int fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
+{
+	/* As per referral draft:  */
+	if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
+	    *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
+		if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
+	            *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
+			*rdattr_err = NFSERR_MOVED;
+		else
+			return nfserr_moved;
+	}
+	*bmval0 &= WORD0_ABSENT_FS_ATTRS;
+	*bmval1 &= WORD1_ABSENT_FS_ATTRS;
+	return 0;
+}
 
 /*
  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
@@ -1295,6 +1434,7 @@
 	u32 *attrlenp;
 	u32 dummy;
 	u64 dummy64;
+	u32 rdattr_err = 0;
 	u32 *p = buffer;
 	int status;
 	int aclsupport = 0;
@@ -1304,6 +1444,12 @@
 	BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
 	BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
 
+	if (exp->ex_fslocs.migrated) {
+		status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
+		if (status)
+			goto out;
+	}
+
 	status = vfs_getattr(exp->ex_mnt, dentry, &stat);
 	if (status)
 		goto out_nfserr;
@@ -1335,6 +1481,11 @@
 				goto out_nfserr;
 		}
 	}
+	if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
+		if (exp->ex_fslocs.locations == NULL) {
+			bmval0 &= ~FATTR4_WORD0_FS_LOCATIONS;
+		}
+	}
 	if ((buflen -= 16) < 0)
 		goto out_resource;
 
@@ -1344,12 +1495,15 @@
 	attrlenp = p++;                /* to be backfilled later */
 
 	if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
+		u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0;
 		if ((buflen -= 12) < 0)
 			goto out_resource;
+		if (!aclsupport)
+			word0 &= ~FATTR4_WORD0_ACL;
+		if (!exp->ex_fslocs.locations)
+			word0 &= ~FATTR4_WORD0_FS_LOCATIONS;
 		WRITE32(2);
-		WRITE32(aclsupport ?
-			NFSD_SUPPORTED_ATTRS_WORD0 :
-			NFSD_SUPPORTED_ATTRS_WORD0 & ~FATTR4_WORD0_ACL);
+		WRITE32(word0);
 		WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
 	}
 	if (bmval0 & FATTR4_WORD0_TYPE) {
@@ -1403,7 +1557,10 @@
 	if (bmval0 & FATTR4_WORD0_FSID) {
 		if ((buflen -= 16) < 0)
 			goto out_resource;
-		if (is_fsid(fhp, rqstp->rq_reffh)) {
+		if (exp->ex_fslocs.migrated) {
+			WRITE64(NFS4_REFERRAL_FSID_MAJOR);
+			WRITE64(NFS4_REFERRAL_FSID_MINOR);
+		} else if (is_fsid(fhp, rqstp->rq_reffh)) {
 			WRITE64((u64)exp->ex_fsid);
 			WRITE64((u64)0);
 		} else {
@@ -1426,7 +1583,7 @@
 	if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
 		if ((buflen -= 4) < 0)
 			goto out_resource;
-		WRITE32(0);
+		WRITE32(rdattr_err);
 	}
 	if (bmval0 & FATTR4_WORD0_ACL) {
 		struct nfs4_ace *ace;
@@ -1514,6 +1671,13 @@
 			goto out_resource;
 		WRITE64((u64) statfs.f_files);
 	}
+	if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
+		status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
+		if (status == nfserr_resource)
+			goto out_resource;
+		if (status)
+			goto out;
+	}
 	if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
 		if ((buflen -= 4) < 0)
 			goto out_resource;
@@ -1537,12 +1701,12 @@
 	if (bmval0 & FATTR4_WORD0_MAXREAD) {
 		if ((buflen -= 8) < 0)
 			goto out_resource;
-		WRITE64((u64) NFSSVC_MAXBLKSIZE);
+		WRITE64((u64) svc_max_payload(rqstp));
 	}
 	if (bmval0 & FATTR4_WORD0_MAXWRITE) {
 		if ((buflen -= 8) < 0)
 			goto out_resource;
-		WRITE64((u64) NFSSVC_MAXBLKSIZE);
+		WRITE64((u64) svc_max_payload(rqstp));
 	}
 	if (bmval1 & FATTR4_WORD1_MODE) {
 		if ((buflen -= 4) < 0)
@@ -1846,7 +2010,6 @@
 	nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
 				    resp->p, &buflen, getattr->ga_bmval,
 				    resp->rqstp);
-
 	if (!nfserr)
 		resp->p += buflen;
 	return nfserr;
@@ -2040,7 +2203,8 @@
 }
 
 static int
-nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read)
+nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr,
+		  struct nfsd4_read *read)
 {
 	u32 eof;
 	int v, pn;
@@ -2055,31 +2219,33 @@
 
 	RESERVE_SPACE(8); /* eof flag and byte count */
 
-	maxcount = NFSSVC_MAXBLKSIZE;
+	maxcount = svc_max_payload(resp->rqstp);
 	if (maxcount > read->rd_length)
 		maxcount = read->rd_length;
 
 	len = maxcount;
 	v = 0;
 	while (len > 0) {
-		pn = resp->rqstp->rq_resused;
-		svc_take_page(resp->rqstp);
-		read->rd_iov[v].iov_base = page_address(resp->rqstp->rq_respages[pn]);
-		read->rd_iov[v].iov_len = len < PAGE_SIZE ? len : PAGE_SIZE;
+		pn = resp->rqstp->rq_resused++;
+		resp->rqstp->rq_vec[v].iov_base =
+			page_address(resp->rqstp->rq_respages[pn]);
+		resp->rqstp->rq_vec[v].iov_len =
+			len < PAGE_SIZE ? len : PAGE_SIZE;
 		v++;
 		len -= PAGE_SIZE;
 	}
 	read->rd_vlen = v;
 
 	nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp,
-			read->rd_offset, read->rd_iov, read->rd_vlen,
+			read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
 			&maxcount);
 
 	if (nfserr == nfserr_symlink)
 		nfserr = nfserr_inval;
 	if (nfserr)
 		return nfserr;
-	eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size);
+	eof = (read->rd_offset + maxcount >=
+	       read->rd_fhp->fh_dentry->d_inode->i_size);
 
 	WRITE32(eof);
 	WRITE32(maxcount);
@@ -2089,7 +2255,6 @@
 	resp->xbuf->page_len = maxcount;
 
 	/* Use rest of head for padding and remaining ops: */
-	resp->rqstp->rq_restailpage = 0;
 	resp->xbuf->tail[0].iov_base = p;
 	resp->xbuf->tail[0].iov_len = 0;
 	if (maxcount&3) {
@@ -2114,8 +2279,7 @@
 	if (resp->xbuf->page_len)
 		return nfserr_resource;
 
-	svc_take_page(resp->rqstp);
-	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
+	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
 
 	maxcount = PAGE_SIZE;
 	RESERVE_SPACE(4);
@@ -2139,7 +2303,6 @@
 	resp->xbuf->page_len = maxcount;
 
 	/* Use rest of head for padding and remaining ops: */
-	resp->rqstp->rq_restailpage = 0;
 	resp->xbuf->tail[0].iov_base = p;
 	resp->xbuf->tail[0].iov_len = 0;
 	if (maxcount&3) {
@@ -2190,8 +2353,7 @@
 		goto err_no_verf;
 	}
 
-	svc_take_page(resp->rqstp);
-	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
+	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
 	readdir->common.err = 0;
 	readdir->buflen = maxcount;
 	readdir->buffer = page;
@@ -2216,10 +2378,10 @@
 	p = readdir->buffer;
 	*p++ = 0;	/* no more entries */
 	*p++ = htonl(readdir->common.err == nfserr_eof);
-	resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
+	resp->xbuf->page_len = ((char*)p) - (char*)page_address(
+		resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
 
 	/* Use rest of head for padding and remaining ops: */
-	resp->rqstp->rq_restailpage = 0;
 	resp->xbuf->tail[0].iov_base = tailbase;
 	resp->xbuf->tail[0].iov_len = 0;
 	resp->p = resp->xbuf->tail[0].iov_base;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 7046ac9..39aed90 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -23,10 +23,14 @@
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/ctype.h>
 
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
+#include <linux/lockd/bind.h>
 #include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/svcsock.h>
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
 #include <linux/nfsd/xdr.h>
@@ -35,8 +39,6 @@
 
 #include <asm/uaccess.h>
 
-unsigned int nfsd_versbits = ~0;
-
 /*
  *	We have a single directory with 9 nodes in it.
  */
@@ -52,7 +54,10 @@
 	NFSD_List,
 	NFSD_Fh,
 	NFSD_Threads,
+	NFSD_Pool_Threads,
 	NFSD_Versions,
+	NFSD_Ports,
+	NFSD_MaxBlkSize,
 	/*
 	 * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
 	 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -75,7 +80,10 @@
 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_pool_threads(struct file *file, char *buf, size_t size);
 static ssize_t write_versions(struct file *file, char *buf, size_t size);
+static ssize_t write_ports(struct file *file, char *buf, size_t size);
+static ssize_t write_maxblksize(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);
@@ -91,7 +99,10 @@
 	[NFSD_Getfs] = write_getfs,
 	[NFSD_Fh] = write_filehandle,
 	[NFSD_Threads] = write_threads,
+	[NFSD_Pool_Threads] = write_pool_threads,
 	[NFSD_Versions] = write_versions,
+	[NFSD_Ports] = write_ports,
+	[NFSD_MaxBlkSize] = write_maxblksize,
 #ifdef CONFIG_NFSD_V4
 	[NFSD_Leasetime] = write_leasetime,
 	[NFSD_RecoveryDir] = write_recoverydir,
@@ -358,6 +369,72 @@
 	return strlen(buf);
 }
 
+extern int nfsd_nrpools(void);
+extern int nfsd_get_nrthreads(int n, int *);
+extern int nfsd_set_nrthreads(int n, int *);
+
+static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
+{
+	/* if size > 0, look for an array of number of threads per node
+	 * and apply them  then write out number of threads per node as reply
+	 */
+	char *mesg = buf;
+	int i;
+	int rv;
+	int len;
+    	int npools = nfsd_nrpools();
+	int *nthreads;
+
+	if (npools == 0) {
+		/*
+		 * NFS is shut down.  The admin can start it by
+		 * writing to the threads file but NOT the pool_threads
+		 * file, sorry.  Report zero threads.
+		 */
+		strcpy(buf, "0\n");
+		return strlen(buf);
+	}
+
+	nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
+	if (nthreads == NULL)
+		return -ENOMEM;
+
+	if (size > 0) {
+		for (i = 0; i < npools; i++) {
+			rv = get_int(&mesg, &nthreads[i]);
+			if (rv == -ENOENT)
+				break;		/* fewer numbers than pools */
+			if (rv)
+				goto out_free;	/* syntax error */
+			rv = -EINVAL;
+			if (nthreads[i] < 0)
+				goto out_free;
+		}
+		rv = nfsd_set_nrthreads(i, nthreads);
+		if (rv)
+			goto out_free;
+	}
+
+	rv = nfsd_get_nrthreads(npools, nthreads);
+	if (rv)
+		goto out_free;
+
+	mesg = buf;
+	size = SIMPLE_TRANSACTION_LIMIT;
+	for (i = 0; i < npools && size > 0; i++) {
+		snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
+		len = strlen(mesg);
+		size -= len;
+		mesg += len;
+	}
+
+	return (mesg-buf);
+
+out_free:
+	kfree(nthreads);
+	return rv;
+}
+
 static ssize_t write_versions(struct file *file, char *buf, size_t size)
 {
 	/*
@@ -372,6 +449,10 @@
 
 	if (size>0) {
 		if (nfsd_serv)
+			/* Cannot change versions without updating
+			 * nfsd_serv->sv_xdrsize, and reallocing
+			 * rq_argp and rq_resp
+			 */
 			return -EBUSY;
 		if (buf[size-1] != '\n')
 			return -EINVAL;
@@ -390,10 +471,7 @@
 			case 2:
 			case 3:
 			case 4:
-				if (sign != '-')
-					NFSCTL_VERSET(nfsd_versbits, num);
-				else
-					NFSCTL_VERUNSET(nfsd_versbits, num);
+				nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
 				break;
 			default:
 				return -EINVAL;
@@ -404,16 +482,15 @@
 		/* 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;
+		nfsd_reset_versions();
 	}
 	/* Now write current state into reply buffer */
 	len = 0;
 	sep = "";
 	for (num=2 ; num <= 4 ; num++)
-		if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+		if (nfsd_vers(num, NFSD_AVAIL)) {
 			len += sprintf(buf+len, "%s%c%d", sep,
-				       NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+				       nfsd_vers(num, NFSD_TEST)?'+':'-',
 				       num);
 			sep = " ";
 		}
@@ -421,6 +498,95 @@
 	return len;
 }
 
+static ssize_t write_ports(struct file *file, char *buf, size_t size)
+{
+	if (size == 0) {
+		int len = 0;
+		lock_kernel();
+		if (nfsd_serv)
+			len = svc_sock_names(buf, nfsd_serv, NULL);
+		unlock_kernel();
+		return len;
+	}
+	/* Either a single 'fd' number is written, in which
+	 * case it must be for a socket of a supported family/protocol,
+	 * and we use it as an nfsd socket, or
+	 * A '-' followed by the 'name' of a socket in which case
+	 * we close the socket.
+	 */
+	if (isdigit(buf[0])) {
+		char *mesg = buf;
+		int fd;
+		int err;
+		err = get_int(&mesg, &fd);
+		if (err)
+			return -EINVAL;
+		if (fd < 0)
+			return -EINVAL;
+		err = nfsd_create_serv();
+		if (!err) {
+			int proto = 0;
+			err = svc_addsock(nfsd_serv, fd, buf, &proto);
+			if (err >= 0) {
+				err = lockd_up(proto);
+				if (err < 0)
+					svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf);
+			}
+			/* Decrease the count, but don't shutdown the
+			 * the service
+			 */
+			lock_kernel();
+			nfsd_serv->sv_nrthreads--;
+			unlock_kernel();
+		}
+		return err < 0 ? err : 0;
+	}
+	if (buf[0] == '-') {
+		char *toclose = kstrdup(buf+1, GFP_KERNEL);
+		int len = 0;
+		if (!toclose)
+			return -ENOMEM;
+		lock_kernel();
+		if (nfsd_serv)
+			len = svc_sock_names(buf, nfsd_serv, toclose);
+		unlock_kernel();
+		if (len >= 0)
+			lockd_down();
+		kfree(toclose);
+		return len;
+	}
+	return -EINVAL;
+}
+
+int nfsd_max_blksize;
+
+static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
+{
+	char *mesg = buf;
+	if (size > 0) {
+		int bsize;
+		int rv = get_int(&mesg, &bsize);
+		if (rv)
+			return rv;
+		/* force bsize into allowed range and
+		 * required alignment.
+		 */
+		if (bsize < 1024)
+			bsize = 1024;
+		if (bsize > NFSSVC_MAXBLKSIZE)
+			bsize = NFSSVC_MAXBLKSIZE;
+		bsize &= ~(1024-1);
+		lock_kernel();
+		if (nfsd_serv && nfsd_serv->sv_nrthreads) {
+			unlock_kernel();
+			return -EBUSY;
+		}
+		nfsd_max_blksize = bsize;
+		unlock_kernel();
+	}
+	return sprintf(buf, "%d\n", nfsd_max_blksize);
+}
+
 #ifdef CONFIG_NFSD_V4
 extern time_t nfs4_leasetime(void);
 
@@ -483,7 +649,10 @@
 		[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_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
+		[NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
 #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/nfsproc.c b/fs/nfsd/nfsproc.c
index 06cd0db..9ee1dab 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -146,20 +146,20 @@
 	 * status, 17 words for fattr, and 1 word for the byte count.
 	 */
 
-	if (NFSSVC_MAXBLKSIZE < argp->count) {
+	if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
 		printk(KERN_NOTICE
 			"oversized read request from %u.%u.%u.%u:%d (%d bytes)\n",
 				NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
 				ntohs(rqstp->rq_addr.sin_port),
 				argp->count);
-		argp->count = NFSSVC_MAXBLKSIZE;
+		argp->count = NFSSVC_MAXBLKSIZE_V2;
 	}
 	svc_reserve(rqstp, (19<<2) + argp->count + 4);
 
 	resp->count = argp->count;
 	nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
 				  argp->offset,
-			   	  argp->vec, argp->vlen,
+			   	  rqstp->rq_vec, argp->vlen,
 				  &resp->count);
 
 	if (nfserr) return nfserr;
@@ -185,7 +185,7 @@
 
 	nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
 				   argp->offset,
-				   argp->vec, argp->vlen,
+				   rqstp->rq_vec, argp->vlen,
 				   argp->len,
 				   &stable);
 	return nfsd_return_attrs(nfserr, resp);
@@ -225,7 +225,7 @@
 	nfserr = nfserr_exist;
 	if (isdotent(argp->name, argp->len))
 		goto done;
-	fh_lock(dirfhp);
+	fh_lock_nested(dirfhp, I_MUTEX_PARENT);
 	dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);
 	if (IS_ERR(dchild)) {
 		nfserr = nfserrno(PTR_ERR(dchild));
@@ -553,7 +553,7 @@
   PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
   PROC(lookup,	 diropargs,	diropres,	fhandle,	RC_NOCACHE, ST+FH+AT),
   PROC(readlink, readlinkargs,	readlinkres,	none,		RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
-  PROC(read,	 readargs,	readres,	fhandle,	RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4),
+  PROC(read,	 readargs,	readres,	fhandle,	RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4),
   PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
   PROC(write,	 writeargs,	attrstat,	fhandle,	RC_REPLBUFF, ST+AT),
   PROC(create,	 createargs,	diropres,	fhandle,	RC_REPLBUFF, ST+FH+AT),
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ec1decf..6fa6340 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -57,12 +57,6 @@
 static unsigned long		nfsd_last_call;
 static DEFINE_SPINLOCK(nfsd_call_lock);
 
-struct nfsd_list {
-	struct list_head 	list;
-	struct task_struct	*task;
-};
-static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
-
 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 static struct svc_stat	nfsd_acl_svcstats;
 static struct svc_version *	nfsd_acl_version[] = {
@@ -117,6 +111,32 @@
 
 };
 
+int nfsd_vers(int vers, enum vers_op change)
+{
+	if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
+		return -1;
+	switch(change) {
+	case NFSD_SET:
+		nfsd_versions[vers] = nfsd_version[vers];
+		break;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+		if (vers < NFSD_ACL_NRVERS)
+			nfsd_acl_version[vers] = nfsd_acl_version[vers];
+#endif
+	case NFSD_CLEAR:
+		nfsd_versions[vers] = NULL;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+		if (vers < NFSD_ACL_NRVERS)
+			nfsd_acl_version[vers] = NULL;
+#endif
+		break;
+	case NFSD_TEST:
+		return nfsd_versions[vers] != NULL;
+	case NFSD_AVAIL:
+		return nfsd_version[vers] != NULL;
+	}
+	return 0;
+}
 /*
  * Maximum number of nfsd processes
  */
@@ -130,16 +150,192 @@
 		return nfsd_serv->sv_nrthreads;
 }
 
+static int killsig;	/* signal that was used to kill last nfsd */
+static void nfsd_last_thread(struct svc_serv *serv)
+{
+	/* When last nfsd thread exits we need to do some clean-up */
+	struct svc_sock *svsk;
+	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+		lockd_down();
+	nfsd_serv = NULL;
+	nfsd_racache_shutdown();
+	nfs4_state_shutdown();
+
+	printk(KERN_WARNING "nfsd: last server has exited\n");
+	if (killsig != SIG_NOCLEAN) {
+		printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
+		nfsd_export_flush();
+	}
+}
+
+void nfsd_reset_versions(void)
+{
+	int found_one = 0;
+	int i;
+
+	for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+		if (nfsd_program.pg_vers[i])
+			found_one = 1;
+	}
+
+	if (!found_one) {
+		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+			nfsd_program.pg_vers[i] = nfsd_version[i];
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+		for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
+			nfsd_acl_program.pg_vers[i] =
+				nfsd_acl_version[i];
+#endif
+	}
+}
+
+int nfsd_create_serv(void)
+{
+	int err = 0;
+	lock_kernel();
+	if (nfsd_serv) {
+		svc_get(nfsd_serv);
+		unlock_kernel();
+		return 0;
+	}
+	if (nfsd_max_blksize == 0) {
+		/* choose a suitable default */
+		struct sysinfo i;
+		si_meminfo(&i);
+		/* Aim for 1/4096 of memory per thread
+		 * This gives 1MB on 4Gig machines
+		 * But only uses 32K on 128M machines.
+		 * Bottom out at 8K on 32M and smaller.
+		 * Of course, this is only a default.
+		 */
+		nfsd_max_blksize = NFSSVC_MAXBLKSIZE;
+		i.totalram <<= PAGE_SHIFT - 12;
+		while (nfsd_max_blksize > i.totalram &&
+		       nfsd_max_blksize >= 8*1024*2)
+			nfsd_max_blksize /= 2;
+	}
+
+	atomic_set(&nfsd_busy, 0);
+	nfsd_serv = svc_create_pooled(&nfsd_program,
+				      NFSD_BUFSIZE - NFSSVC_MAXBLKSIZE + nfsd_max_blksize,
+				      nfsd_last_thread,
+				      nfsd, SIG_NOCLEAN, THIS_MODULE);
+	if (nfsd_serv == NULL)
+		err = -ENOMEM;
+	unlock_kernel();
+	do_gettimeofday(&nfssvc_boot);		/* record boot time */
+	return err;
+}
+
+static int nfsd_init_socks(int port)
+{
+	int error;
+	if (!list_empty(&nfsd_serv->sv_permsocks))
+		return 0;
+
+	error = lockd_up(IPPROTO_UDP);
+	if (error >= 0) {
+		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+		if (error < 0)
+			lockd_down();
+	}
+	if (error < 0)
+		return error;
+
+#ifdef CONFIG_NFSD_TCP
+	error = lockd_up(IPPROTO_TCP);
+	if (error >= 0) {
+		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+		if (error < 0)
+			lockd_down();
+	}
+	if (error < 0)
+		return error;
+#endif
+	return 0;
+}
+
+int nfsd_nrpools(void)
+{
+	if (nfsd_serv == NULL)
+		return 0;
+	else
+		return nfsd_serv->sv_nrpools;
+}
+
+int nfsd_get_nrthreads(int n, int *nthreads)
+{
+	int i = 0;
+
+	if (nfsd_serv != NULL) {
+		for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++)
+			nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads;
+	}
+
+	return 0;
+}
+
+int nfsd_set_nrthreads(int n, int *nthreads)
+{
+	int i = 0;
+	int tot = 0;
+	int err = 0;
+
+	if (nfsd_serv == NULL || n <= 0)
+		return 0;
+
+	if (n > nfsd_serv->sv_nrpools)
+		n = nfsd_serv->sv_nrpools;
+
+	/* enforce a global maximum number of threads */
+	tot = 0;
+	for (i = 0; i < n; i++) {
+		if (nthreads[i] > NFSD_MAXSERVS)
+			nthreads[i] = NFSD_MAXSERVS;
+		tot += nthreads[i];
+	}
+	if (tot > NFSD_MAXSERVS) {
+		/* total too large: scale down requested numbers */
+		for (i = 0; i < n && tot > 0; i++) {
+		    	int new = nthreads[i] * NFSD_MAXSERVS / tot;
+			tot -= (nthreads[i] - new);
+			nthreads[i] = new;
+		}
+		for (i = 0; i < n && tot > 0; i++) {
+			nthreads[i]--;
+			tot--;
+		}
+	}
+
+	/*
+	 * There must always be a thread in pool 0; the admin
+	 * can't shut down NFS completely using pool_threads.
+	 */
+	if (nthreads[0] == 0)
+		nthreads[0] = 1;
+
+	/* apply the new numbers */
+	lock_kernel();
+	svc_get(nfsd_serv);
+	for (i = 0; i < n; i++) {
+		err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i],
+				    	  nthreads[i]);
+		if (err)
+			break;
+	}
+	svc_destroy(nfsd_serv);
+	unlock_kernel();
+
+	return err;
+}
+
 int
 nfsd_svc(unsigned short port, int nrservs)
 {
 	int	error;
-	int	none_left, found_one, i;
-	struct list_head *victim;
 	
 	lock_kernel();
-	dprintk("nfsd: creating service: vers 0x%x\n",
-		nfsd_versbits);
+	dprintk("nfsd: creating service\n");
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
@@ -153,91 +349,20 @@
 	error = nfs4_state_start();
 	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;
-		}
+	nfsd_reset_versions();
 
-		if (!found_one) {
-			for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
-				nfsd_program.pg_vers[i] = nfsd_version[i];
-		}
+	error = nfsd_create_serv();
 
+	if (error)
+		goto out;
+	error = nfsd_init_socks(port);
+	if (error)
+		goto failure;
 
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
-		found_one = 0;
-
-		for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
-			if (NFSCTL_VERISSET(nfsd_versbits, i)) {
-				nfsd_acl_program.pg_vers[i] =
-					nfsd_acl_version[i];
-				found_one = 1;
-			} else
-				nfsd_acl_program.pg_vers[i] = NULL;
-		}
-
-		if (!found_one) {
-			for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
-				nfsd_acl_program.pg_vers[i] =
-					nfsd_acl_version[i];
-		}
-#endif
-
-		atomic_set(&nfsd_busy, 0);
-		error = -ENOMEM;
-		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
-		if (nfsd_serv == NULL)
-			goto out;
-		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-		if (error < 0)
-			goto failure;
-
-#ifdef CONFIG_NFSD_TCP
-		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-		if (error < 0)
-			goto failure;
-#endif
-		do_gettimeofday(&nfssvc_boot);		/* record boot time */
-	} else
-		nfsd_serv->sv_nrthreads++;
-	nrservs -= (nfsd_serv->sv_nrthreads-1);
-	while (nrservs > 0) {
-		nrservs--;
-		__module_get(THIS_MODULE);
-		error = svc_create_thread(nfsd, nfsd_serv);
-		if (error < 0) {
-			module_put(THIS_MODULE);
-			break;
-		}
-	}
-	victim = nfsd_list.next;
-	while (nrservs < 0 && victim != &nfsd_list) {
-		struct nfsd_list *nl =
-			list_entry(victim,struct nfsd_list, list);
-		victim = victim->next;
-		send_sig(SIG_NOCLEAN, nl->task, 1);
-		nrservs++;
-	}
+	error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
  failure:
-	none_left = (nfsd_serv->sv_nrthreads == 1);
 	svc_destroy(nfsd_serv);		/* Release server */
-	if (none_left) {
-		nfsd_serv = NULL;
-		nfsd_racache_shutdown();
-		nfs4_state_shutdown();
-	}
  out:
 	unlock_kernel();
 	return error;
@@ -270,10 +395,8 @@
 static void
 nfsd(struct svc_rqst *rqstp)
 {
-	struct svc_serv	*serv = rqstp->rq_server;
 	struct fs_struct *fsp;
 	int		err;
-	struct nfsd_list me;
 	sigset_t shutdown_mask, allowed_mask;
 
 	/* Lock module and set up kernel thread */
@@ -297,10 +420,7 @@
 
 	nfsdstats.th_cnt++;
 
-	lockd_up();				/* start lockd */
-
-	me.task = current;
-	list_add(&me.list, &nfsd_list);
+	rqstp->rq_task = current;
 
 	unlock_kernel();
 
@@ -322,8 +442,7 @@
 		 * Find a socket with data available and call its
 		 * recvfrom routine.
 		 */
-		while ((err = svc_recv(serv, rqstp,
-				       60*60*HZ)) == -EAGAIN)
+		while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
 			;
 		if (err < 0)
 			break;
@@ -336,7 +455,7 @@
 		/* Process request with signals blocked.  */
 		sigprocmask(SIG_SETMASK, &allowed_mask, NULL);
 
-		svc_process(serv, rqstp);
+		svc_process(rqstp);
 
 		/* Unlock export hash tables */
 		exp_readunlock();
@@ -353,29 +472,13 @@
 			if (sigismember(&current->pending.signal, signo) &&
 			    !sigismember(&current->blocked, signo))
 				break;
-		err = signo;
+		killsig = signo;
 	}
-	/* Clear signals before calling lockd_down() and svc_exit_thread() */
+	/* Clear signals before calling svc_exit_thread() */
 	flush_signals(current);
 
 	lock_kernel();
 
-	/* Release lockd */
-	lockd_down();
-
-	/* Check if this is last thread */
-	if (serv->sv_nrthreads==1) {
-		
-		printk(KERN_WARNING "nfsd: last server has exited\n");
-		if (err != SIG_NOCLEAN) {
-			printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
-			nfsd_export_flush();
-		}
-		nfsd_serv = NULL;
-	        nfsd_racache_shutdown();	/* release read-ahead cache */
-		nfs4_state_shutdown();
-	}
-	list_del(&me.list);
 	nfsdstats.th_cnt --;
 
 out:
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index e3a0797..1135c0d 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nfsd/xdr.c
+ * linux/fs/nfsd/nfsxdr.c
  *
  * XDR support for nfsd
  *
@@ -254,19 +254,18 @@
 	len = args->count     = ntohl(*p++);
 	p++; /* totalcount - unused */
 
-	if (len > NFSSVC_MAXBLKSIZE)
-		len = NFSSVC_MAXBLKSIZE;
+	if (len > NFSSVC_MAXBLKSIZE_V2)
+		len = NFSSVC_MAXBLKSIZE_V2;
 
 	/* set up somewhere to store response.
 	 * We take pages, put them on reslist and include in iovec
 	 */
 	v=0;
 	while (len > 0) {
-		pn=rqstp->rq_resused;
-		svc_take_page(rqstp);
-		args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
-		args->vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
-		len -= args->vec[v].iov_len;
+		pn = rqstp->rq_resused++;
+		rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
+		rqstp->rq_vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
+		len -= rqstp->rq_vec[v].iov_len;
 		v++;
 	}
 	args->vlen = v;
@@ -286,21 +285,21 @@
 	args->offset = ntohl(*p++);	/* offset */
 	p++;				/* totalcount */
 	len = args->len = ntohl(*p++);
-	args->vec[0].iov_base = (void*)p;
-	args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
+	rqstp->rq_vec[0].iov_base = (void*)p;
+	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
 				(((void*)p) - rqstp->rq_arg.head[0].iov_base);
-	if (len > NFSSVC_MAXBLKSIZE)
-		len = NFSSVC_MAXBLKSIZE;
+	if (len > NFSSVC_MAXBLKSIZE_V2)
+		len = NFSSVC_MAXBLKSIZE_V2;
 	v = 0;
-	while (len > args->vec[v].iov_len) {
-		len -= args->vec[v].iov_len;
+	while (len > rqstp->rq_vec[v].iov_len) {
+		len -= rqstp->rq_vec[v].iov_len;
 		v++;
-		args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
-		args->vec[v].iov_len = PAGE_SIZE;
+		rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
+		rqstp->rq_vec[v].iov_len = PAGE_SIZE;
 	}
-	args->vec[v].iov_len = len;
+	rqstp->rq_vec[v].iov_len = len;
 	args->vlen = v+1;
-	return args->vec[0].iov_len > 0;
+	return rqstp->rq_vec[0].iov_len > 0;
 }
 
 int
@@ -333,8 +332,7 @@
 {
 	if (!(p = decode_fh(p, &args->fh)))
 		return 0;
-	svc_take_page(rqstp);
-	args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+	args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
 	return xdr_argsize_check(rqstp, p);
 }
@@ -375,8 +373,7 @@
 	if (args->count > PAGE_SIZE)
 		args->count = PAGE_SIZE;
 
-	svc_take_page(rqstp);
-	args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+	args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
 	return xdr_argsize_check(rqstp, p);
 }
@@ -416,7 +413,6 @@
 	rqstp->rq_res.page_len = resp->len;
 	if (resp->len & 3) {
 		/* need to pad the tail */
-		rqstp->rq_restailpage = 0;
 		rqstp->rq_res.tail[0].iov_base = p;
 		*p = 0;
 		rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
@@ -436,7 +432,6 @@
 	rqstp->rq_res.page_len = resp->count;
 	if (resp->count & 3) {
 		/* need to pad the tail */
-		rqstp->rq_restailpage = 0;
 		rqstp->rq_res.tail[0].iov_base = p;
 		*p = 0;
 		rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3);
@@ -463,7 +458,7 @@
 {
 	struct kstatfs	*stat = &resp->stats;
 
-	*p++ = htonl(NFSSVC_MAXBLKSIZE);	/* max transfer size */
+	*p++ = htonl(NFSSVC_MAXBLKSIZE_V2);	/* max transfer size */
 	*p++ = htonl(stat->f_bsize);
 	*p++ = htonl(stat->f_blocks);
 	*p++ = htonl(stat->f_bfree);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c9e3b5a..1141bd2 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -54,6 +54,7 @@
 #include <linux/nfsd_idmap.h>
 #include <linux/security.h>
 #endif /* CONFIG_NFSD_V4 */
+#include <linux/jhash.h>
 
 #include <asm/uaccess.h>
 
@@ -81,10 +82,19 @@
 	dev_t			p_dev;
 	int			p_set;
 	struct file_ra_state	p_ra;
+	unsigned int		p_hindex;
 };
 
+struct raparm_hbucket {
+	struct raparms		*pb_head;
+	spinlock_t		pb_lock;
+} ____cacheline_aligned_in_smp;
+
 static struct raparms *		raparml;
-static struct raparms *		raparm_cache;
+#define RAPARM_HASH_BITS	4
+#define RAPARM_HASH_SIZE	(1<<RAPARM_HASH_BITS)
+#define RAPARM_HASH_MASK	(RAPARM_HASH_SIZE-1)
+static struct raparm_hbucket	raparm_hash[RAPARM_HASH_SIZE];
 
 /* 
  * Called from nfsd_lookup and encode_dirent. Check if we have crossed 
@@ -437,13 +447,11 @@
 	} else if (error < 0)
 		goto out_nfserr;
 
-	if (pacl) {
-		error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
-		if (error < 0)
-			goto out_nfserr;
-	}
+	error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
+	if (error < 0)
+		goto out_nfserr;
 
-	if (dpacl) {
+	if (S_ISDIR(inode->i_mode)) {
 		error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
 		if (error < 0)
 			goto out_nfserr;
@@ -743,16 +751,20 @@
  * Obtain the readahead parameters for the file
  * specified by (dev, ino).
  */
-static DEFINE_SPINLOCK(ra_lock);
 
 static inline struct raparms *
 nfsd_get_raparms(dev_t dev, ino_t ino)
 {
 	struct raparms	*ra, **rap, **frap = NULL;
 	int depth = 0;
+	unsigned int hash;
+	struct raparm_hbucket *rab;
 
-	spin_lock(&ra_lock);
-	for (rap = &raparm_cache; (ra = *rap); rap = &ra->p_next) {
+	hash = jhash_2words(dev, ino, 0xfeedbeef) & RAPARM_HASH_MASK;
+	rab = &raparm_hash[hash];
+
+	spin_lock(&rab->pb_lock);
+	for (rap = &rab->pb_head; (ra = *rap); rap = &ra->p_next) {
 		if (ra->p_ino == ino && ra->p_dev == dev)
 			goto found;
 		depth++;
@@ -761,7 +773,7 @@
 	}
 	depth = nfsdstats.ra_size*11/10;
 	if (!frap) {	
-		spin_unlock(&ra_lock);
+		spin_unlock(&rab->pb_lock);
 		return NULL;
 	}
 	rap = frap;
@@ -769,15 +781,16 @@
 	ra->p_dev = dev;
 	ra->p_ino = ino;
 	ra->p_set = 0;
+	ra->p_hindex = hash;
 found:
-	if (rap != &raparm_cache) {
+	if (rap != &rab->pb_head) {
 		*rap = ra->p_next;
-		ra->p_next   = raparm_cache;
-		raparm_cache = ra;
+		ra->p_next   = rab->pb_head;
+		rab->pb_head = ra;
 	}
 	ra->p_count++;
 	nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
-	spin_unlock(&ra_lock);
+	spin_unlock(&rab->pb_lock);
 	return ra;
 }
 
@@ -791,22 +804,26 @@
 {
 	unsigned long count = desc->count;
 	struct svc_rqst *rqstp = desc->arg.data;
+	struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
 
 	if (size > count)
 		size = count;
 
 	if (rqstp->rq_res.page_len == 0) {
 		get_page(page);
-		rqstp->rq_respages[rqstp->rq_resused++] = page;
+		put_page(*pp);
+		*pp = page;
+		rqstp->rq_resused++;
 		rqstp->rq_res.page_base = offset;
 		rqstp->rq_res.page_len = size;
-	} else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) {
+	} else if (page != pp[-1]) {
 		get_page(page);
-		rqstp->rq_respages[rqstp->rq_resused++] = page;
+		put_page(*pp);
+		*pp = page;
+		rqstp->rq_resused++;
 		rqstp->rq_res.page_len += size;
-	} else {
+	} else
 		rqstp->rq_res.page_len += size;
-	}
 
 	desc->count = count - size;
 	desc->written += size;
@@ -837,7 +854,7 @@
 		file->f_ra = ra->p_ra;
 
 	if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
-		svc_pushback_unused_pages(rqstp);
+		rqstp->rq_resused = 1;
 		err = file->f_op->sendfile(file, &offset, *count,
 						 nfsd_read_actor, rqstp);
 	} else {
@@ -849,11 +866,12 @@
 
 	/* Write back readahead params */
 	if (ra) {
-		spin_lock(&ra_lock);
+		struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
+		spin_lock(&rab->pb_lock);
 		ra->p_ra = file->f_ra;
 		ra->p_set = 1;
 		ra->p_count--;
-		spin_unlock(&ra_lock);
+		spin_unlock(&rab->pb_lock);
 	}
 
 	if (err >= 0) {
@@ -1114,7 +1132,7 @@
 	 */
 	if (!resfhp->fh_dentry) {
 		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
-		fh_lock(fhp);
+		fh_lock_nested(fhp, I_MUTEX_PARENT);
 		dchild = lookup_one_len(fname, dentry, flen);
 		err = PTR_ERR(dchild);
 		if (IS_ERR(dchild))
@@ -1240,7 +1258,7 @@
 	err = nfserr_notdir;
 	if(!dirp->i_op || !dirp->i_op->lookup)
 		goto out;
-	fh_lock(fhp);
+	fh_lock_nested(fhp, I_MUTEX_PARENT);
 
 	/*
 	 * Compose the response file handle.
@@ -1494,7 +1512,7 @@
 	if (isdotent(name, len))
 		goto out;
 
-	fh_lock(ffhp);
+	fh_lock_nested(ffhp, I_MUTEX_PARENT);
 	ddir = ffhp->fh_dentry;
 	dirp = ddir->d_inode;
 
@@ -1644,7 +1662,7 @@
 	if (err)
 		goto out;
 
-	fh_lock(fhp);
+	fh_lock_nested(fhp, I_MUTEX_PARENT);
 	dentry = fhp->fh_dentry;
 	dirp = dentry->d_inode;
 
@@ -1829,11 +1847,11 @@
 void
 nfsd_racache_shutdown(void)
 {
-	if (!raparm_cache)
+	if (!raparml)
 		return;
 	dprintk("nfsd: freeing readahead buffers.\n");
 	kfree(raparml);
-	raparm_cache = raparml = NULL;
+	raparml = NULL;
 }
 /*
  * Initialize readahead param cache
@@ -1842,19 +1860,31 @@
 nfsd_racache_init(int cache_size)
 {
 	int	i;
+	int	j = 0;
+	int	nperbucket;
 
-	if (raparm_cache)
+
+	if (raparml)
 		return 0;
+	if (cache_size < 2*RAPARM_HASH_SIZE)
+		cache_size = 2*RAPARM_HASH_SIZE;
 	raparml = kmalloc(sizeof(struct raparms) * cache_size, GFP_KERNEL);
 
 	if (raparml != NULL) {
 		dprintk("nfsd: allocating %d readahead buffers.\n",
 			cache_size);
+		for (i = 0 ; i < RAPARM_HASH_SIZE ; i++) {
+			raparm_hash[i].pb_head = NULL;
+			spin_lock_init(&raparm_hash[i].pb_lock);
+		}
+		nperbucket = cache_size >> RAPARM_HASH_BITS;
 		memset(raparml, 0, sizeof(struct raparms) * cache_size);
 		for (i = 0; i < cache_size - 1; i++) {
-			raparml[i].p_next = raparml + i + 1;
+			if (i % nperbucket == 0)
+				raparm_hash[j++].pb_head = raparml + i;
+			if (i % nperbucket < nperbucket-1)
+				raparml[i].p_next = raparml + i + 1;
 		}
-		raparm_cache = raparml;
 	} else {
 		printk(KERN_WARNING
 		       "nfsd: Could not allocate memory read-ahead cache.\n");
diff --git a/fs/nls/nls_ascii.c b/fs/nls/nls_ascii.c
index b83381c..6993fae 100644
--- a/fs/nls/nls_ascii.c
+++ b/fs/nls/nls_ascii.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_ascii.c
+ * linux/fs/nls/nls_ascii.c
  *
  * Charset ascii translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 9de6b49..7dfdab9 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_base.c
+ * linux/fs/nls/nls_base.c
  *
  * Native language support--charsets and unicode translations.
  * By Gordon Chaffee 1996, 1997
@@ -163,8 +163,6 @@
 {
 	struct nls_table ** tmp = &tables;
 
-	if (!nls)
-		return -EINVAL;
 	if (nls->next)
 		return -EBUSY;
 
diff --git a/fs/nls/nls_cp1250.c b/fs/nls/nls_cp1250.c
index 32e78cf..570aa69 100644
--- a/fs/nls/nls_cp1250.c
+++ b/fs/nls/nls_cp1250.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp1250.c
+ * linux/fs/nls/nls_cp1250.c
  *
  * Charset cp1250 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp1251.c b/fs/nls/nls_cp1251.c
index cb41c8a..f114afa 100644
--- a/fs/nls/nls_cp1251.c
+++ b/fs/nls/nls_cp1251.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp1251.c
+ * linux/fs/nls/nls_cp1251.c
  *
  * Charset cp1251 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp1255.c b/fs/nls/nls_cp1255.c
index efdeefe..e57f2cb 100644
--- a/fs/nls/nls_cp1255.c
+++ b/fs/nls/nls_cp1255.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp1255.c
+ * linux/fs/nls/nls_cp1255.c
  *
  * Charset cp1255 translation tables.
  * The Unicode to charset table has only exact mappings.
diff --git a/fs/nls/nls_cp437.c b/fs/nls/nls_cp437.c
index 5c4a1cd..d41930c 100644
--- a/fs/nls/nls_cp437.c
+++ b/fs/nls/nls_cp437.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp437.c
+ * linux/fs/nls/nls_cp437.c
  *
  * Charset cp437 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp737.c b/fs/nls/nls_cp737.c
index e8b3ca8..d21f879 100644
--- a/fs/nls/nls_cp737.c
+++ b/fs/nls/nls_cp737.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp737.c
+ * linux/fs/nls/nls_cp737.c
  *
  * Charset cp737 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp775.c b/fs/nls/nls_cp775.c
index bdb290e..c97714c 100644
--- a/fs/nls/nls_cp775.c
+++ b/fs/nls/nls_cp775.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp775.c
+ * linux/fs/nls/nls_cp775.c
  *
  * Charset cp775 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp850.c b/fs/nls/nls_cp850.c
index 25deaa4..843b7d9 100644
--- a/fs/nls/nls_cp850.c
+++ b/fs/nls/nls_cp850.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp850.c
+ * linux/fs/nls/nls_cp850.c
  *
  * Charset cp850 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp852.c b/fs/nls/nls_cp852.c
index b822a7b..83cfd84 100644
--- a/fs/nls/nls_cp852.c
+++ b/fs/nls/nls_cp852.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp852.c
+ * linux/fs/nls/nls_cp852.c
  *
  * Charset cp852 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp855.c b/fs/nls/nls_cp855.c
index e8641b7..9190b7b 100644
--- a/fs/nls/nls_cp855.c
+++ b/fs/nls/nls_cp855.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp855.c
+ * linux/fs/nls/nls_cp855.c
  *
  * Charset cp855 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp857.c b/fs/nls/nls_cp857.c
index 7ba589e..ef3d36d 100644
--- a/fs/nls/nls_cp857.c
+++ b/fs/nls/nls_cp857.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp857.c
+ * linux/fs/nls/nls_cp857.c
  *
  * Charset cp857 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp860.c b/fs/nls/nls_cp860.c
index 3b9e49c..7e2fb66 100644
--- a/fs/nls/nls_cp860.c
+++ b/fs/nls/nls_cp860.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp860.c
+ * linux/fs/nls/nls_cp860.c
  *
  * Charset cp860 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp861.c b/fs/nls/nls_cp861.c
index 959ff64..66d8d80 100644
--- a/fs/nls/nls_cp861.c
+++ b/fs/nls/nls_cp861.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp861.c
+ * linux/fs/nls/nls_cp861.c
  *
  * Charset cp861 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp862.c b/fs/nls/nls_cp862.c
index b96928f..360ba38 100644
--- a/fs/nls/nls_cp862.c
+++ b/fs/nls/nls_cp862.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp862.c
+ * linux/fs/nls/nls_cp862.c
  *
  * Charset cp862 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp863.c b/fs/nls/nls_cp863.c
index baa6e0e..656a931 100644
--- a/fs/nls/nls_cp863.c
+++ b/fs/nls/nls_cp863.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp863.c
+ * linux/fs/nls/nls_cp863.c
  *
  * Charset cp863 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp864.c b/fs/nls/nls_cp864.c
index f4dabb0..01ca730 100644
--- a/fs/nls/nls_cp864.c
+++ b/fs/nls/nls_cp864.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp864.c
+ * linux/fs/nls/nls_cp864.c
  *
  * Charset cp864 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp865.c b/fs/nls/nls_cp865.c
index 4caeafa..5ba6ee1 100644
--- a/fs/nls/nls_cp865.c
+++ b/fs/nls/nls_cp865.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp865.c
+ * linux/fs/nls/nls_cp865.c
  *
  * Charset cp865 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp866.c b/fs/nls/nls_cp866.c
index f2b4a9a..c5f8222 100644
--- a/fs/nls/nls_cp866.c
+++ b/fs/nls/nls_cp866.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp866.c
+ * linux/fs/nls/nls_cp866.c
  *
  * Charset cp866 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp869.c b/fs/nls/nls_cp869.c
index 12b436f..8d40151 100644
--- a/fs/nls/nls_cp869.c
+++ b/fs/nls/nls_cp869.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp869.c
+ * linux/fs/nls/nls_cp869.c
  *
  * Charset cp869 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp874.c b/fs/nls/nls_cp874.c
index b5766a0..df04205 100644
--- a/fs/nls/nls_cp874.c
+++ b/fs/nls/nls_cp874.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp874.c
+ * linux/fs/nls/nls_cp874.c
  *
  * Charset cp874 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_cp932.c b/fs/nls/nls_cp932.c
index 2c1a17c..2a9ccf3 100644
--- a/fs/nls/nls_cp932.c
+++ b/fs/nls/nls_cp932.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp932.c
+ * linux/fs/nls/nls_cp932.c
  *
  * Charset cp932 translation tables.
  * This translation table was generated automatically, the
diff --git a/fs/nls/nls_cp936.c b/fs/nls/nls_cp936.c
index ef4cef4..046fde8 100644
--- a/fs/nls/nls_cp936.c
+++ b/fs/nls/nls_cp936.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp936.c
+ * linux/fs/nls/nls_cp936.c
  *
  * Charset cp936 translation tables.
  * This translation table was generated automatically, the
diff --git a/fs/nls/nls_cp949.c b/fs/nls/nls_cp949.c
index 4351ae2..92ae193 100644
--- a/fs/nls/nls_cp949.c
+++ b/fs/nls/nls_cp949.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp949.c
+ * linux/fs/nls/nls_cp949.c
  *
  * Charset cp949 translation tables.
  * This translation table was generated automatically, the
diff --git a/fs/nls/nls_cp950.c b/fs/nls/nls_cp950.c
index 8167a28..5665945 100644
--- a/fs/nls/nls_cp950.c
+++ b/fs/nls/nls_cp950.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp950.c
+ * linux/fs/nls/nls_cp950.c
  *
  * Charset cp950 translation tables.
  * This translation table was generated automatically, the
diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c
index 06640c3..7329351 100644
--- a/fs/nls/nls_euc-jp.c
+++ b/fs/nls/nls_euc-jp.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_euc-jp.c
+ * linux/fs/nls/nls_euc-jp.c
  *
  * Added `OSF/JVC Recommended Code Set Conversion Specification
  * between Japanese EUC and Shift-JIS' support: <hirofumi@mail.parknet.co.jp>
diff --git a/fs/nls/nls_iso8859-1.c b/fs/nls/nls_iso8859-1.c
index 70a2c19..2483c3c 100644
--- a/fs/nls/nls_iso8859-1.c
+++ b/fs/nls/nls_iso8859-1.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-1.c
+ * linux/fs/nls/nls_iso8859-1.c
  *
  * Charset iso8859-1 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_iso8859-13.c b/fs/nls/nls_iso8859-13.c
index 4547035..7b8721d 100644
--- a/fs/nls/nls_iso8859-13.c
+++ b/fs/nls/nls_iso8859-13.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-13.c
+ * linux/fs/nls/nls_iso8859-13.c
  *
  * Charset iso8859-13 translation tables.
  * The Unicode to charset table has only exact mappings.
diff --git a/fs/nls/nls_iso8859-14.c b/fs/nls/nls_iso8859-14.c
index 13628d0..2e895e6 100644
--- a/fs/nls/nls_iso8859-14.c
+++ b/fs/nls/nls_iso8859-14.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-14.c
+ * linux/fs/nls/nls_iso8859-14.c
  *
  * Charset iso8859-14 translation tables.
  *
diff --git a/fs/nls/nls_iso8859-15.c b/fs/nls/nls_iso8859-15.c
index 88b924b..5c91592 100644
--- a/fs/nls/nls_iso8859-15.c
+++ b/fs/nls/nls_iso8859-15.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-15.c
+ * linux/fs/nls/nls_iso8859-15.c
  *
  * Charset iso8859-15 translation tables.
  * The Unicode to charset table has only exact mappings.
diff --git a/fs/nls/nls_iso8859-2.c b/fs/nls/nls_iso8859-2.c
index 372528a..892d38f 100644
--- a/fs/nls/nls_iso8859-2.c
+++ b/fs/nls/nls_iso8859-2.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-2.c
+ * linux/fs/nls/nls_iso8859-2.c
  *
  * Charset iso8859-2 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_iso8859-3.c b/fs/nls/nls_iso8859-3.c
index 81b45a2..49317bc 100644
--- a/fs/nls/nls_iso8859-3.c
+++ b/fs/nls/nls_iso8859-3.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-3.c
+ * linux/fs/nls/nls_iso8859-3.c
  *
  * Charset iso8859-3 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_iso8859-4.c b/fs/nls/nls_iso8859-4.c
index 101b87f..9f3b936 100644
--- a/fs/nls/nls_iso8859-4.c
+++ b/fs/nls/nls_iso8859-4.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-4.c
+ * linux/fs/nls/nls_iso8859-4.c
  *
  * Charset iso8859-4 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_iso8859-5.c b/fs/nls/nls_iso8859-5.c
index 83b0084..001a2bb 100644
--- a/fs/nls/nls_iso8859-5.c
+++ b/fs/nls/nls_iso8859-5.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-5.c
+ * linux/fs/nls/nls_iso8859-5.c
  *
  * Charset iso8859-5 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_iso8859-6.c b/fs/nls/nls_iso8859-6.c
index 0c519d6..8cec03d 100644
--- a/fs/nls/nls_iso8859-6.c
+++ b/fs/nls/nls_iso8859-6.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-6.c
+ * linux/fs/nls/nls_iso8859-6.c
  *
  * Charset iso8859-6 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_iso8859-7.c b/fs/nls/nls_iso8859-7.c
index bd08546..1be707d 100644
--- a/fs/nls/nls_iso8859-7.c
+++ b/fs/nls/nls_iso8859-7.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-7.c
+ * linux/fs/nls/nls_iso8859-7.c
  *
  * Charset iso8859-7 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_iso8859-9.c b/fs/nls/nls_iso8859-9.c
index 988eff7..8c0146f 100644
--- a/fs/nls/nls_iso8859-9.c
+++ b/fs/nls/nls_iso8859-9.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-9.c
+ * linux/fs/nls/nls_iso8859-9.c
  *
  * Charset iso8859-9 translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_koi8-r.c b/fs/nls/nls_koi8-r.c
index 0ad22c2..fefbe08 100644
--- a/fs/nls/nls_koi8-r.c
+++ b/fs/nls/nls_koi8-r.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_koi8-r.c
+ * linux/fs/nls/nls_koi8-r.c
  *
  * Charset koi8-r translation tables.
  * Generated automatically from the Unicode and charset
diff --git a/fs/nls/nls_koi8-ru.c b/fs/nls/nls_koi8-ru.c
index 5db83ef..e7bc1d7 100644
--- a/fs/nls/nls_koi8-ru.c
+++ b/fs/nls/nls_koi8-ru.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_koi8-ru.c
+ * linux/fs/nls/nls_koi8-ru.c
  *
  * Charset koi8-ru translation based on charset koi8-u.
  * The Unicode to charset table has only exact mappings.
diff --git a/fs/nls/nls_koi8-u.c b/fs/nls/nls_koi8-u.c
index 9d30fd6..0150702 100644
--- a/fs/nls/nls_koi8-u.c
+++ b/fs/nls/nls_koi8-u.c
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_koi8-u.c
+ * linux/fs/nls/nls_koi8-u.c
  *
  * Charset koi8-u translation tables.
  * The Unicode to charset table has only exact mappings.
diff --git a/fs/proc/array.c b/fs/proc/array.c
index c0e5549..25e917f 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -162,7 +162,7 @@
 	int g;
 	struct fdtable *fdt = NULL;
 
-	read_lock(&tasklist_lock);
+	rcu_read_lock();
 	buffer += sprintf(buffer,
 		"State:\t%s\n"
 		"SleepAVG:\t%lu%%\n"
@@ -174,14 +174,13 @@
 		"Gid:\t%d\t%d\t%d\t%d\n",
 		get_task_state(p),
 		(p->sleep_avg/1024)*100/(1020000000/1024),
-	       	p->tgid,
-		p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0,
-		pid_alive(p) && p->ptrace ? p->parent->pid : 0,
+	       	p->tgid, p->pid,
+	       	pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
+		pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
 		p->uid, p->euid, p->suid, p->fsuid,
 		p->gid, p->egid, p->sgid, p->fsgid);
-	read_unlock(&tasklist_lock);
+
 	task_lock(p);
-	rcu_read_lock();
 	if (p->files)
 		fdt = files_fdtable(p->files);
 	buffer += sprintf(buffer,
@@ -244,6 +243,7 @@
 
 static inline char * task_sig(struct task_struct *p, char *buffer)
 {
+	unsigned long flags;
 	sigset_t pending, shpending, blocked, ignored, caught;
 	int num_threads = 0;
 	unsigned long qsize = 0;
@@ -255,10 +255,8 @@
 	sigemptyset(&ignored);
 	sigemptyset(&caught);
 
-	/* Gather all the data with the appropriate locks held */
-	read_lock(&tasklist_lock);
-	if (p->sighand) {
-		spin_lock_irq(&p->sighand->siglock);
+	rcu_read_lock();
+	if (lock_task_sighand(p, &flags)) {
 		pending = p->pending.signal;
 		shpending = p->signal->shared_pending.signal;
 		blocked = p->blocked;
@@ -266,9 +264,9 @@
 		num_threads = atomic_read(&p->signal->count);
 		qsize = atomic_read(&p->user->sigpending);
 		qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
-		spin_unlock_irq(&p->sighand->siglock);
+		unlock_task_sighand(p, &flags);
 	}
-	read_unlock(&tasklist_lock);
+	rcu_read_unlock();
 
 	buffer += sprintf(buffer, "Threads:\t%d\n", num_threads);
 	buffer += sprintf(buffer, "SigQ:\t%lu/%lu\n", qsize, qlim);
@@ -322,7 +320,7 @@
 	sigset_t sigign, sigcatch;
 	char state;
 	int res;
- 	pid_t ppid, pgid = -1, sid = -1;
+ 	pid_t ppid = 0, pgid = -1, sid = -1;
 	int num_threads = 0;
 	struct mm_struct *mm;
 	unsigned long long start_time;
@@ -330,8 +328,8 @@
 	unsigned long  min_flt = 0,  maj_flt = 0;
 	cputime_t cutime, cstime, utime, stime;
 	unsigned long rsslim = 0;
-	struct task_struct *t;
 	char tcomm[sizeof(task->comm)];
+	unsigned long flags;
 
 	state = *get_task_state(task);
 	vsize = eip = esp = 0;
@@ -349,15 +347,33 @@
 	cutime = cstime = utime = stime = cputime_zero;
 
 	mutex_lock(&tty_mutex);
-	read_lock(&tasklist_lock);
-	if (task->sighand) {
-		spin_lock_irq(&task->sighand->siglock);
-		num_threads = atomic_read(&task->signal->count);
+	rcu_read_lock();
+	if (lock_task_sighand(task, &flags)) {
+		struct signal_struct *sig = task->signal;
+		struct tty_struct *tty = sig->tty;
+
+		if (tty) {
+			/*
+			 * sig->tty is not stable, but tty_mutex
+			 * protects us from release_dev(tty)
+			 */
+			barrier();
+			tty_pgrp = tty->pgrp;
+			tty_nr = new_encode_dev(tty_devnum(tty));
+		}
+
+		num_threads = atomic_read(&sig->count);
 		collect_sigign_sigcatch(task, &sigign, &sigcatch);
 
+		cmin_flt = sig->cmin_flt;
+		cmaj_flt = sig->cmaj_flt;
+		cutime = sig->cutime;
+		cstime = sig->cstime;
+		rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
+
 		/* add up live thread stats at the group level */
 		if (whole) {
-			t = task;
+			struct task_struct *t = task;
 			do {
 				min_flt += t->min_flt;
 				maj_flt += t->maj_flt;
@@ -365,31 +381,20 @@
 				stime = cputime_add(stime, t->stime);
 				t = next_thread(t);
 			} while (t != task);
+
+			min_flt += sig->min_flt;
+			maj_flt += sig->maj_flt;
+			utime = cputime_add(utime, sig->utime);
+			stime = cputime_add(stime, sig->stime);
 		}
 
-		spin_unlock_irq(&task->sighand->siglock);
-	}
-	if (task->signal) {
-		if (task->signal->tty) {
-			tty_pgrp = task->signal->tty->pgrp;
-			tty_nr = new_encode_dev(tty_devnum(task->signal->tty));
-		}
+		sid = sig->session;
 		pgid = process_group(task);
-		sid = task->signal->session;
-		cmin_flt = task->signal->cmin_flt;
-		cmaj_flt = task->signal->cmaj_flt;
-		cutime = task->signal->cutime;
-		cstime = task->signal->cstime;
-		rsslim = task->signal->rlim[RLIMIT_RSS].rlim_cur;
-		if (whole) {
-			min_flt += task->signal->min_flt;
-			maj_flt += task->signal->maj_flt;
-			utime = cputime_add(utime, task->signal->utime);
-			stime = cputime_add(stime, task->signal->stime);
-		}
+		ppid = rcu_dereference(task->real_parent)->tgid;
+
+		unlock_task_sighand(task, &flags);
 	}
-	ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
-	read_unlock(&tasklist_lock);
+	rcu_read_unlock();
 	mutex_unlock(&tty_mutex);
 
 	if (!whole || num_threads<2)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 89c20d9..82da55b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -71,6 +71,7 @@
 #include <linux/cpuset.h>
 #include <linux/audit.h>
 #include <linux/poll.h>
+#include <linux/nsproxy.h>
 #include "internal.h"
 
 /* NOTE:
@@ -83,262 +84,44 @@
  *	in /proc for a task before it execs a suid executable.
  */
 
-/*
- * For hysterical raisins we keep the same inumbers as in the old procfs.
- * Feel free to change the macro below - just keep the range distinct from
- * inumbers of the rest of procfs (currently those are in 0x0000--0xffff).
- * As soon as we'll get a separate superblock we will be able to forget
- * about magical ranges too.
- */
-
-#define fake_ino(pid,ino) (((pid)<<16)|(ino))
-
-enum pid_directory_inos {
-	PROC_TGID_INO = 2,
-	PROC_TGID_TASK,
-	PROC_TGID_STATUS,
-	PROC_TGID_MEM,
-#ifdef CONFIG_SECCOMP
-	PROC_TGID_SECCOMP,
-#endif
-	PROC_TGID_CWD,
-	PROC_TGID_ROOT,
-	PROC_TGID_EXE,
-	PROC_TGID_FD,
-	PROC_TGID_ENVIRON,
-	PROC_TGID_AUXV,
-	PROC_TGID_CMDLINE,
-	PROC_TGID_STAT,
-	PROC_TGID_STATM,
-	PROC_TGID_MAPS,
-	PROC_TGID_NUMA_MAPS,
-	PROC_TGID_MOUNTS,
-	PROC_TGID_MOUNTSTATS,
-	PROC_TGID_WCHAN,
-#ifdef CONFIG_MMU
-	PROC_TGID_SMAPS,
-#endif
-#ifdef CONFIG_SCHEDSTATS
-	PROC_TGID_SCHEDSTAT,
-#endif
-#ifdef CONFIG_CPUSETS
-	PROC_TGID_CPUSET,
-#endif
-#ifdef CONFIG_SECURITY
-	PROC_TGID_ATTR,
-	PROC_TGID_ATTR_CURRENT,
-	PROC_TGID_ATTR_PREV,
-	PROC_TGID_ATTR_EXEC,
-	PROC_TGID_ATTR_FSCREATE,
-	PROC_TGID_ATTR_KEYCREATE,
-	PROC_TGID_ATTR_SOCKCREATE,
-#endif
-#ifdef CONFIG_AUDITSYSCALL
-	PROC_TGID_LOGINUID,
-#endif
-	PROC_TGID_OOM_SCORE,
-	PROC_TGID_OOM_ADJUST,
-	PROC_TID_INO,
-	PROC_TID_STATUS,
-	PROC_TID_MEM,
-#ifdef CONFIG_SECCOMP
-	PROC_TID_SECCOMP,
-#endif
-	PROC_TID_CWD,
-	PROC_TID_ROOT,
-	PROC_TID_EXE,
-	PROC_TID_FD,
-	PROC_TID_ENVIRON,
-	PROC_TID_AUXV,
-	PROC_TID_CMDLINE,
-	PROC_TID_STAT,
-	PROC_TID_STATM,
-	PROC_TID_MAPS,
-	PROC_TID_NUMA_MAPS,
-	PROC_TID_MOUNTS,
-	PROC_TID_MOUNTSTATS,
-	PROC_TID_WCHAN,
-#ifdef CONFIG_MMU
-	PROC_TID_SMAPS,
-#endif
-#ifdef CONFIG_SCHEDSTATS
-	PROC_TID_SCHEDSTAT,
-#endif
-#ifdef CONFIG_CPUSETS
-	PROC_TID_CPUSET,
-#endif
-#ifdef CONFIG_SECURITY
-	PROC_TID_ATTR,
-	PROC_TID_ATTR_CURRENT,
-	PROC_TID_ATTR_PREV,
-	PROC_TID_ATTR_EXEC,
-	PROC_TID_ATTR_FSCREATE,
-	PROC_TID_ATTR_KEYCREATE,
-	PROC_TID_ATTR_SOCKCREATE,
-#endif
-#ifdef CONFIG_AUDITSYSCALL
-	PROC_TID_LOGINUID,
-#endif
-	PROC_TID_OOM_SCORE,
-	PROC_TID_OOM_ADJUST,
-
-	/* Add new entries before this */
-	PROC_TID_FD_DIR = 0x8000,	/* 0x8000-0xffff */
-};
 
 /* Worst case buffer size needed for holding an integer. */
 #define PROC_NUMBUF 10
 
 struct pid_entry {
-	int type;
 	int len;
 	char *name;
 	mode_t mode;
+	struct inode_operations *iop;
+	struct file_operations *fop;
+	union proc_op op;
 };
 
-#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
-
-static struct pid_entry tgid_base_stuff[] = {
-	E(PROC_TGID_TASK,      "task",    S_IFDIR|S_IRUGO|S_IXUGO),
-	E(PROC_TGID_FD,        "fd",      S_IFDIR|S_IRUSR|S_IXUSR),
-	E(PROC_TGID_ENVIRON,   "environ", S_IFREG|S_IRUSR),
-	E(PROC_TGID_AUXV,      "auxv",	  S_IFREG|S_IRUSR),
-	E(PROC_TGID_STATUS,    "status",  S_IFREG|S_IRUGO),
-	E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
-	E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
-	E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
-#ifdef CONFIG_NUMA
-	E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
-#endif
-	E(PROC_TGID_MEM,       "mem",     S_IFREG|S_IRUSR|S_IWUSR),
-#ifdef CONFIG_SECCOMP
-	E(PROC_TGID_SECCOMP,   "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
-#endif
-	E(PROC_TGID_CWD,       "cwd",     S_IFLNK|S_IRWXUGO),
-	E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
-	E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
-	E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
-	E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
-#ifdef CONFIG_MMU
-	E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SECURITY
-	E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
-#endif
-#ifdef CONFIG_KALLSYMS
-	E(PROC_TGID_WCHAN,     "wchan",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SCHEDSTATS
-	E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_CPUSETS
-	E(PROC_TGID_CPUSET,    "cpuset",  S_IFREG|S_IRUGO),
-#endif
-	E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
-	E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
-#ifdef CONFIG_AUDITSYSCALL
-	E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
-#endif
-	{0,0,NULL,0}
-};
-static struct pid_entry tid_base_stuff[] = {
-	E(PROC_TID_FD,         "fd",      S_IFDIR|S_IRUSR|S_IXUSR),
-	E(PROC_TID_ENVIRON,    "environ", S_IFREG|S_IRUSR),
-	E(PROC_TID_AUXV,       "auxv",	  S_IFREG|S_IRUSR),
-	E(PROC_TID_STATUS,     "status",  S_IFREG|S_IRUGO),
-	E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
-	E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
-	E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
-#ifdef CONFIG_NUMA
-	E(PROC_TID_NUMA_MAPS,  "numa_maps",    S_IFREG|S_IRUGO),
-#endif
-	E(PROC_TID_MEM,        "mem",     S_IFREG|S_IRUSR|S_IWUSR),
-#ifdef CONFIG_SECCOMP
-	E(PROC_TID_SECCOMP,    "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
-#endif
-	E(PROC_TID_CWD,        "cwd",     S_IFLNK|S_IRWXUGO),
-	E(PROC_TID_ROOT,       "root",    S_IFLNK|S_IRWXUGO),
-	E(PROC_TID_EXE,        "exe",     S_IFLNK|S_IRWXUGO),
-	E(PROC_TID_MOUNTS,     "mounts",  S_IFREG|S_IRUGO),
-#ifdef CONFIG_MMU
-	E(PROC_TID_SMAPS,      "smaps",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SECURITY
-	E(PROC_TID_ATTR,       "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
-#endif
-#ifdef CONFIG_KALLSYMS
-	E(PROC_TID_WCHAN,      "wchan",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SCHEDSTATS
-	E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_CPUSETS
-	E(PROC_TID_CPUSET,     "cpuset",  S_IFREG|S_IRUGO),
-#endif
-	E(PROC_TID_OOM_SCORE,  "oom_score",S_IFREG|S_IRUGO),
-	E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
-#ifdef CONFIG_AUDITSYSCALL
-	E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
-#endif
-	{0,0,NULL,0}
-};
-
-#ifdef CONFIG_SECURITY
-static struct pid_entry tgid_attr_stuff[] = {
-	E(PROC_TGID_ATTR_CURRENT,  "current",  S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TGID_ATTR_PREV,     "prev",     S_IFREG|S_IRUGO),
-	E(PROC_TGID_ATTR_EXEC,     "exec",     S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
-	{0,0,NULL,0}
-};
-static struct pid_entry tid_attr_stuff[] = {
-	E(PROC_TID_ATTR_CURRENT,   "current",  S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TID_ATTR_PREV,      "prev",     S_IFREG|S_IRUGO),
-	E(PROC_TID_ATTR_EXEC,      "exec",     S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TID_ATTR_FSCREATE,  "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
-	E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
-	{0,0,NULL,0}
-};
-#endif
-
-#undef E
-
-static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
-{
-	struct task_struct *task = get_proc_task(inode);
-	struct files_struct *files = NULL;
-	struct file *file;
-	int fd = proc_fd(inode);
-
-	if (task) {
-		files = get_files_struct(task);
-		put_task_struct(task);
-	}
-	if (files) {
-		/*
-		 * We are not taking a ref to the file structure, so we must
-		 * hold ->file_lock.
-		 */
-		spin_lock(&files->file_lock);
-		file = fcheck_files(files, fd);
-		if (file) {
-			*mnt = mntget(file->f_vfsmnt);
-			*dentry = dget(file->f_dentry);
-			spin_unlock(&files->file_lock);
-			put_files_struct(files);
-			return 0;
-		}
-		spin_unlock(&files->file_lock);
-		put_files_struct(files);
-	}
-	return -ENOENT;
+#define NOD(NAME, MODE, IOP, FOP, OP) {			\
+	.len  = sizeof(NAME) - 1,			\
+	.name = (NAME),					\
+	.mode = MODE,					\
+	.iop  = IOP,					\
+	.fop  = FOP,					\
+	.op   = OP,					\
 }
 
+#define DIR(NAME, MODE, OTYPE)							\
+	NOD(NAME, (S_IFDIR|(MODE)),						\
+		&proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations,	\
+		{} )
+#define LNK(NAME, OTYPE)					\
+	NOD(NAME, (S_IFLNK|S_IRWXUGO),				\
+		&proc_pid_link_inode_operations, NULL,		\
+		{ .proc_get_link = &proc_##OTYPE##_link } )
+#define REG(NAME, MODE, OTYPE)				\
+	NOD(NAME, (S_IFREG|(MODE)), NULL,		\
+		&proc_##OTYPE##_operations, {})
+#define INF(NAME, MODE, OTYPE)				\
+	NOD(NAME, (S_IFREG|(MODE)), 			\
+		NULL, &proc_info_file_operations,	\
+		{ .proc_read = &proc_##OTYPE } )
+
 static struct fs_struct *get_fs_struct(struct task_struct *task)
 {
 	struct fs_struct *fs;
@@ -587,7 +370,7 @@
 
 	if (task) {
 		task_lock(task);
-		namespace = task->namespace;
+		namespace = task->nsproxy->namespace;
 		if (namespace)
 			get_namespace(namespace);
 		task_unlock(task);
@@ -658,7 +441,7 @@
 
 		if (task) {
 			task_lock(task);
-			namespace = task->namespace;
+			namespace = task->nsproxy->namespace;
 			if (namespace)
 				get_namespace(namespace);
 			task_unlock(task);
@@ -1137,143 +920,6 @@
 	.setattr	= proc_setattr,
 };
 
-static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
-{
-	struct dentry *dentry = filp->f_dentry;
-	struct inode *inode = dentry->d_inode;
-	struct task_struct *p = get_proc_task(inode);
-	unsigned int fd, tid, ino;
-	int retval;
-	char buf[PROC_NUMBUF];
-	struct files_struct * files;
-	struct fdtable *fdt;
-
-	retval = -ENOENT;
-	if (!p)
-		goto out_no_task;
-	retval = 0;
-	tid = p->pid;
-
-	fd = filp->f_pos;
-	switch (fd) {
-		case 0:
-			if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
-				goto out;
-			filp->f_pos++;
-		case 1:
-			ino = parent_ino(dentry);
-			if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
-				goto out;
-			filp->f_pos++;
-		default:
-			files = get_files_struct(p);
-			if (!files)
-				goto out;
-			rcu_read_lock();
-			fdt = files_fdtable(files);
-			for (fd = filp->f_pos-2;
-			     fd < fdt->max_fds;
-			     fd++, filp->f_pos++) {
-				unsigned int i,j;
-
-				if (!fcheck_files(files, fd))
-					continue;
-				rcu_read_unlock();
-
-				j = PROC_NUMBUF;
-				i = fd;
-				do {
-					j--;
-					buf[j] = '0' + (i % 10);
-					i /= 10;
-				} while (i);
-
-				ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
-				if (filldir(dirent, buf+j, PROC_NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
-					rcu_read_lock();
-					break;
-				}
-				rcu_read_lock();
-			}
-			rcu_read_unlock();
-			put_files_struct(files);
-	}
-out:
-	put_task_struct(p);
-out_no_task:
-	return retval;
-}
-
-static int proc_pident_readdir(struct file *filp,
-		void *dirent, filldir_t filldir,
-		struct pid_entry *ents, unsigned int nents)
-{
-	int i;
-	int pid;
-	struct dentry *dentry = filp->f_dentry;
-	struct inode *inode = dentry->d_inode;
-	struct task_struct *task = get_proc_task(inode);
-	struct pid_entry *p;
-	ino_t ino;
-	int ret;
-
-	ret = -ENOENT;
-	if (!task)
-		goto out;
-
-	ret = 0;
-	pid = task->pid;
-	put_task_struct(task);
-	i = filp->f_pos;
-	switch (i) {
-	case 0:
-		ino = inode->i_ino;
-		if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
-			goto out;
-		i++;
-		filp->f_pos++;
-		/* fall through */
-	case 1:
-		ino = parent_ino(dentry);
-		if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
-			goto out;
-		i++;
-		filp->f_pos++;
-		/* fall through */
-	default:
-		i -= 2;
-		if (i >= nents) {
-			ret = 1;
-			goto out;
-		}
-		p = ents + i;
-		while (p->name) {
-			if (filldir(dirent, p->name, p->len, filp->f_pos,
-				    fake_ino(pid, p->type), p->mode >> 12) < 0)
-				goto out;
-			filp->f_pos++;
-			p++;
-		}
-	}
-
-	ret = 1;
-out:
-	return ret;
-}
-
-static int proc_tgid_base_readdir(struct file * filp,
-			     void * dirent, filldir_t filldir)
-{
-	return proc_pident_readdir(filp,dirent,filldir,
-				   tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
-}
-
-static int proc_tid_base_readdir(struct file * filp,
-			     void * dirent, filldir_t filldir)
-{
-	return proc_pident_readdir(filp,dirent,filldir,
-				   tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
-}
 
 /* building an inode */
 
@@ -1293,13 +939,13 @@
 }
 
 
-static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
+static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task)
 {
 	struct inode * inode;
 	struct proc_inode *ei;
 
 	/* We need a new inode */
-	
+
 	inode = new_inode(sb);
 	if (!inode)
 		goto out;
@@ -1307,13 +953,12 @@
 	/* Common stuff */
 	ei = PROC_I(inode);
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-	inode->i_ino = fake_ino(task->pid, ino);
 	inode->i_op = &proc_def_inode_operations;
 
 	/*
 	 * grab the reference to task.
 	 */
-	ei->pid = get_pid(task->pids[PIDTYPE_PID].pid);
+	ei->pid = get_task_pid(task, PIDTYPE_PID);
 	if (!ei->pid)
 		goto out_unlock;
 
@@ -1333,6 +978,27 @@
 	return NULL;
 }
 
+static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+	struct inode *inode = dentry->d_inode;
+	struct task_struct *task;
+	generic_fillattr(inode, stat);
+
+	rcu_read_lock();
+	stat->uid = 0;
+	stat->gid = 0;
+	task = pid_task(proc_pid(inode), PIDTYPE_PID);
+	if (task) {
+		if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
+		    task_dumpable(task)) {
+			stat->uid = task->euid;
+			stat->gid = task->egid;
+		}
+	}
+	rcu_read_unlock();
+	return 0;
+}
+
 /* dentry stuff */
 
 /*
@@ -1372,25 +1038,130 @@
 	return 0;
 }
 
-static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+static int pid_delete_dentry(struct dentry * dentry)
 {
-	struct inode *inode = dentry->d_inode;
-	struct task_struct *task;
-	generic_fillattr(inode, stat);
+	/* Is the task we represent dead?
+	 * If so, then don't put the dentry on the lru list,
+	 * kill it immediately.
+	 */
+	return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
+}
 
-	rcu_read_lock();
-	stat->uid = 0;
-	stat->gid = 0;
-	task = pid_task(proc_pid(inode), PIDTYPE_PID);
-	if (task) {
-		if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
-		    task_dumpable(task)) {
-			stat->uid = task->euid;
-			stat->gid = task->egid;
+static struct dentry_operations pid_dentry_operations =
+{
+	.d_revalidate	= pid_revalidate,
+	.d_delete	= pid_delete_dentry,
+};
+
+/* Lookups */
+
+typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *);
+
+/*
+ * Fill a directory entry.
+ *
+ * If possible create the dcache entry and derive our inode number and
+ * file type from dcache entry.
+ *
+ * Since all of the proc inode numbers are dynamically generated, the inode
+ * numbers do not exist until the inode is cache.  This means creating the
+ * the dcache entry in readdir is necessary to keep the inode numbers
+ * reported by readdir in sync with the inode numbers reported
+ * by stat.
+ */
+static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+	char *name, int len,
+	instantiate_t instantiate, struct task_struct *task, void *ptr)
+{
+	struct dentry *child, *dir = filp->f_dentry;
+	struct inode *inode;
+	struct qstr qname;
+	ino_t ino = 0;
+	unsigned type = DT_UNKNOWN;
+
+	qname.name = name;
+	qname.len  = len;
+	qname.hash = full_name_hash(name, len);
+
+	child = d_lookup(dir, &qname);
+	if (!child) {
+		struct dentry *new;
+		new = d_alloc(dir, &qname);
+		if (new) {
+			child = instantiate(dir->d_inode, new, task, ptr);
+			if (child)
+				dput(new);
+			else
+				child = new;
 		}
 	}
-	rcu_read_unlock();
-	return 0;
+	if (!child || IS_ERR(child) || !child->d_inode)
+		goto end_instantiate;
+	inode = child->d_inode;
+	if (inode) {
+		ino = inode->i_ino;
+		type = inode->i_mode >> 12;
+	}
+	dput(child);
+end_instantiate:
+	if (!ino)
+		ino = find_inode_number(dir, &qname);
+	if (!ino)
+		ino = 1;
+	return filldir(dirent, name, len, filp->f_pos, ino, type);
+}
+
+static unsigned name_to_int(struct dentry *dentry)
+{
+	const char *name = dentry->d_name.name;
+	int len = dentry->d_name.len;
+	unsigned n = 0;
+
+	if (len > 1 && *name == '0')
+		goto out;
+	while (len-- > 0) {
+		unsigned c = *name++ - '0';
+		if (c > 9)
+			goto out;
+		if (n >= (~0U-9)/10)
+			goto out;
+		n *= 10;
+		n += c;
+	}
+	return n;
+out:
+	return ~0U;
+}
+
+static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+{
+	struct task_struct *task = get_proc_task(inode);
+	struct files_struct *files = NULL;
+	struct file *file;
+	int fd = proc_fd(inode);
+
+	if (task) {
+		files = get_files_struct(task);
+		put_task_struct(task);
+	}
+	if (files) {
+		/*
+		 * We are not taking a ref to the file structure, so we must
+		 * hold ->file_lock.
+		 */
+		spin_lock(&files->file_lock);
+		file = fcheck_files(files, fd);
+		if (file) {
+			*mnt = mntget(file->f_vfsmnt);
+			*dentry = dget(file->f_dentry);
+			spin_unlock(&files->file_lock);
+			put_files_struct(files);
+			return 0;
+		}
+		spin_unlock(&files->file_lock);
+		put_files_struct(files);
+	}
+	return -ENOENT;
 }
 
 static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
@@ -1428,75 +1199,30 @@
 	return 0;
 }
 
-static int pid_delete_dentry(struct dentry * dentry)
-{
-	/* Is the task we represent dead?
-	 * If so, then don't put the dentry on the lru list,
-	 * kill it immediately.
-	 */
-	return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
-}
-
 static struct dentry_operations tid_fd_dentry_operations =
 {
 	.d_revalidate	= tid_fd_revalidate,
 	.d_delete	= pid_delete_dentry,
 };
 
-static struct dentry_operations pid_dentry_operations =
+static struct dentry *proc_fd_instantiate(struct inode *dir,
+	struct dentry *dentry, struct task_struct *task, void *ptr)
 {
-	.d_revalidate	= pid_revalidate,
-	.d_delete	= pid_delete_dentry,
-};
+	unsigned fd = *(unsigned *)ptr;
+	struct file *file;
+	struct files_struct *files;
+ 	struct inode *inode;
+ 	struct proc_inode *ei;
+	struct dentry *error = ERR_PTR(-ENOENT);
 
-/* Lookups */
-
-static unsigned name_to_int(struct dentry *dentry)
-{
-	const char *name = dentry->d_name.name;
-	int len = dentry->d_name.len;
-	unsigned n = 0;
-
-	if (len > 1 && *name == '0')
-		goto out;
-	while (len-- > 0) {
-		unsigned c = *name++ - '0';
-		if (c > 9)
-			goto out;
-		if (n >= (~0U-9)/10)
-			goto out;
-		n *= 10;
-		n += c;
-	}
-	return n;
-out:
-	return ~0U;
-}
-
-/* SMP-safe */
-static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
-{
-	struct task_struct *task = get_proc_task(dir);
-	unsigned fd = name_to_int(dentry);
-	struct dentry *result = ERR_PTR(-ENOENT);
-	struct file * file;
-	struct files_struct * files;
-	struct inode *inode;
-	struct proc_inode *ei;
-
-	if (!task)
-		goto out_no_task;
-	if (fd == ~0U)
-		goto out;
-
-	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd);
+	inode = proc_pid_make_inode(dir->i_sb, task);
 	if (!inode)
 		goto out;
 	ei = PROC_I(inode);
 	ei->fd = fd;
 	files = get_files_struct(task);
 	if (!files)
-		goto out_unlock;
+		goto out_iput;
 	inode->i_mode = S_IFLNK;
 
 	/*
@@ -1506,13 +1232,14 @@
 	spin_lock(&files->file_lock);
 	file = fcheck_files(files, fd);
 	if (!file)
-		goto out_unlock2;
+		goto out_unlock;
 	if (file->f_mode & 1)
 		inode->i_mode |= S_IRUSR | S_IXUSR;
 	if (file->f_mode & 2)
 		inode->i_mode |= S_IWUSR | S_IXUSR;
 	spin_unlock(&files->file_lock);
 	put_files_struct(files);
+
 	inode->i_op = &proc_pid_link_inode_operations;
 	inode->i_size = 64;
 	ei->op.proc_get_link = proc_fd_link;
@@ -1520,34 +1247,106 @@
 	d_add(dentry, inode);
 	/* Close the race of the process dying before we return the dentry */
 	if (tid_fd_revalidate(dentry, NULL))
-		result = NULL;
-out:
-	put_task_struct(task);
-out_no_task:
-	return result;
+		error = NULL;
 
-out_unlock2:
+ out:
+	return error;
+out_unlock:
 	spin_unlock(&files->file_lock);
 	put_files_struct(files);
-out_unlock:
+out_iput:
 	iput(inode);
 	goto out;
 }
 
-static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir);
-static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd);
-static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
+static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+{
+	struct task_struct *task = get_proc_task(dir);
+	unsigned fd = name_to_int(dentry);
+	struct dentry *result = ERR_PTR(-ENOENT);
+
+	if (!task)
+		goto out_no_task;
+	if (fd == ~0U)
+		goto out;
+
+	result = proc_fd_instantiate(dir, dentry, task, &fd);
+out:
+	put_task_struct(task);
+out_no_task:
+	return result;
+}
+
+static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+	struct task_struct *task, int fd)
+{
+	char name[PROC_NUMBUF];
+	int len = snprintf(name, sizeof(name), "%d", fd);
+	return proc_fill_cache(filp, dirent, filldir, name, len,
+				proc_fd_instantiate, task, &fd);
+}
+
+static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
+{
+	struct dentry *dentry = filp->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	struct task_struct *p = get_proc_task(inode);
+	unsigned int fd, tid, ino;
+	int retval;
+	struct files_struct * files;
+	struct fdtable *fdt;
+
+	retval = -ENOENT;
+	if (!p)
+		goto out_no_task;
+	retval = 0;
+	tid = p->pid;
+
+	fd = filp->f_pos;
+	switch (fd) {
+		case 0:
+			if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
+				goto out;
+			filp->f_pos++;
+		case 1:
+			ino = parent_ino(dentry);
+			if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
+				goto out;
+			filp->f_pos++;
+		default:
+			files = get_files_struct(p);
+			if (!files)
+				goto out;
+			rcu_read_lock();
+			fdt = files_fdtable(files);
+			for (fd = filp->f_pos-2;
+			     fd < fdt->max_fds;
+			     fd++, filp->f_pos++) {
+
+				if (!fcheck_files(files, fd))
+					continue;
+				rcu_read_unlock();
+
+				if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
+					rcu_read_lock();
+					break;
+				}
+				rcu_read_lock();
+			}
+			rcu_read_unlock();
+			put_files_struct(files);
+	}
+out:
+	put_task_struct(p);
+out_no_task:
+	return retval;
+}
 
 static struct file_operations proc_fd_operations = {
 	.read		= generic_read_dir,
 	.readdir	= proc_readfd,
 };
 
-static struct file_operations proc_task_operations = {
-	.read		= generic_read_dir,
-	.readdir	= proc_task_readdir,
-};
-
 /*
  * proc directories can do almost nothing..
  */
@@ -1556,11 +1355,137 @@
 	.setattr	= proc_setattr,
 };
 
-static struct inode_operations proc_task_inode_operations = {
-	.lookup		= proc_task_lookup,
-	.getattr	= proc_task_getattr,
-	.setattr	= proc_setattr,
-};
+static struct dentry *proc_pident_instantiate(struct inode *dir,
+	struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+	struct pid_entry *p = ptr;
+	struct inode *inode;
+	struct proc_inode *ei;
+	struct dentry *error = ERR_PTR(-EINVAL);
+
+	inode = proc_pid_make_inode(dir->i_sb, task);
+	if (!inode)
+		goto out;
+
+	ei = PROC_I(inode);
+	inode->i_mode = p->mode;
+	if (S_ISDIR(inode->i_mode))
+		inode->i_nlink = 2;	/* Use getattr to fix if necessary */
+	if (p->iop)
+		inode->i_op = p->iop;
+	if (p->fop)
+		inode->i_fop = p->fop;
+	ei->op = p->op;
+	dentry->d_op = &pid_dentry_operations;
+	d_add(dentry, inode);
+	/* Close the race of the process dying before we return the dentry */
+	if (pid_revalidate(dentry, NULL))
+		error = NULL;
+out:
+	return error;
+}
+
+static struct dentry *proc_pident_lookup(struct inode *dir, 
+					 struct dentry *dentry,
+					 struct pid_entry *ents,
+					 unsigned int nents)
+{
+	struct inode *inode;
+	struct dentry *error;
+	struct task_struct *task = get_proc_task(dir);
+	struct pid_entry *p, *last;
+
+	error = ERR_PTR(-ENOENT);
+	inode = NULL;
+
+	if (!task)
+		goto out_no_task;
+
+	/*
+	 * Yes, it does not scale. And it should not. Don't add
+	 * new entries into /proc/<tgid>/ without very good reasons.
+	 */
+	last = &ents[nents - 1];
+	for (p = ents; p <= last; p++) {
+		if (p->len != dentry->d_name.len)
+			continue;
+		if (!memcmp(dentry->d_name.name, p->name, p->len))
+			break;
+	}
+	if (p > last)
+		goto out;
+
+	error = proc_pident_instantiate(dir, dentry, task, p);
+out:
+	put_task_struct(task);
+out_no_task:
+	return error;
+}
+
+static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+	struct task_struct *task, struct pid_entry *p)
+{
+	return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
+				proc_pident_instantiate, task, p);
+}
+
+static int proc_pident_readdir(struct file *filp,
+		void *dirent, filldir_t filldir,
+		struct pid_entry *ents, unsigned int nents)
+{
+	int i;
+	int pid;
+	struct dentry *dentry = filp->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	struct task_struct *task = get_proc_task(inode);
+	struct pid_entry *p, *last;
+	ino_t ino;
+	int ret;
+
+	ret = -ENOENT;
+	if (!task)
+		goto out_no_task;
+
+	ret = 0;
+	pid = task->pid;
+	i = filp->f_pos;
+	switch (i) {
+	case 0:
+		ino = inode->i_ino;
+		if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+			goto out;
+		i++;
+		filp->f_pos++;
+		/* fall through */
+	case 1:
+		ino = parent_ino(dentry);
+		if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
+			goto out;
+		i++;
+		filp->f_pos++;
+		/* fall through */
+	default:
+		i -= 2;
+		if (i >= nents) {
+			ret = 1;
+			goto out;
+		}
+		p = ents + i;
+		last = &ents[nents - 1];
+		while (p <= last) {
+			if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0)
+				goto out;
+			filp->f_pos++;
+			p++;
+		}
+	}
+
+	ret = 1;
+out:
+	put_task_struct(task);
+out_no_task:
+	return ret;
+}
 
 #ifdef CONFIG_SECURITY
 static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
@@ -1581,8 +1506,8 @@
 	if (!(page = __get_free_page(GFP_KERNEL)))
 		goto out;
 
-	length = security_getprocattr(task, 
-				      (char*)file->f_dentry->d_name.name, 
+	length = security_getprocattr(task,
+				      (char*)file->f_dentry->d_name.name,
 				      (void*)page, count);
 	if (length >= 0)
 		length = simple_read_from_buffer(buf, count, ppos, (char *)page, length);
@@ -1595,17 +1520,17 @@
 
 static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
 				   size_t count, loff_t *ppos)
-{ 
+{
 	struct inode * inode = file->f_dentry->d_inode;
-	char *page; 
-	ssize_t length; 
+	char *page;
+	ssize_t length;
 	struct task_struct *task = get_proc_task(inode);
 
 	length = -ESRCH;
 	if (!task)
 		goto out_no_task;
-	if (count > PAGE_SIZE) 
-		count = PAGE_SIZE; 
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
 
 	/* No partial writes. */
 	length = -EINVAL;
@@ -1613,16 +1538,16 @@
 		goto out;
 
 	length = -ENOMEM;
-	page = (char*)__get_free_page(GFP_USER); 
-	if (!page) 
+	page = (char*)__get_free_page(GFP_USER);
+	if (!page)
 		goto out;
 
-	length = -EFAULT; 
-	if (copy_from_user(page, buf, count)) 
+	length = -EFAULT;
+	if (copy_from_user(page, buf, count))
 		goto out_free;
 
-	length = security_setprocattr(task, 
-				      (char*)file->f_dentry->d_name.name, 
+	length = security_setprocattr(task,
+				      (char*)file->f_dentry->d_name.name,
 				      (void*)page, count);
 out_free:
 	free_page((unsigned long) page);
@@ -1630,306 +1555,47 @@
 	put_task_struct(task);
 out_no_task:
 	return length;
-} 
+}
 
 static struct file_operations proc_pid_attr_operations = {
 	.read		= proc_pid_attr_read,
 	.write		= proc_pid_attr_write,
 };
 
-static struct file_operations proc_tid_attr_operations;
-static struct inode_operations proc_tid_attr_inode_operations;
-static struct file_operations proc_tgid_attr_operations;
-static struct inode_operations proc_tgid_attr_inode_operations;
-#endif
-
-/* SMP-safe */
-static struct dentry *proc_pident_lookup(struct inode *dir, 
-					 struct dentry *dentry,
-					 struct pid_entry *ents)
-{
-	struct inode *inode;
-	struct dentry *error;
-	struct task_struct *task = get_proc_task(dir);
-	struct pid_entry *p;
-	struct proc_inode *ei;
-
-	error = ERR_PTR(-ENOENT);
-	inode = NULL;
-
-	if (!task)
-		goto out_no_task;
-
-	for (p = ents; p->name; p++) {
-		if (p->len != dentry->d_name.len)
-			continue;
-		if (!memcmp(dentry->d_name.name, p->name, p->len))
-			break;
-	}
-	if (!p->name)
-		goto out;
-
-	error = ERR_PTR(-EINVAL);
-	inode = proc_pid_make_inode(dir->i_sb, task, p->type);
-	if (!inode)
-		goto out;
-
-	ei = PROC_I(inode);
-	inode->i_mode = p->mode;
-	/*
-	 * Yes, it does not scale. And it should not. Don't add
-	 * new entries into /proc/<tgid>/ without very good reasons.
-	 */
-	switch(p->type) {
-		case PROC_TGID_TASK:
-			inode->i_nlink = 2;
-			inode->i_op = &proc_task_inode_operations;
-			inode->i_fop = &proc_task_operations;
-			break;
-		case PROC_TID_FD:
-		case PROC_TGID_FD:
-			inode->i_nlink = 2;
-			inode->i_op = &proc_fd_inode_operations;
-			inode->i_fop = &proc_fd_operations;
-			break;
-		case PROC_TID_EXE:
-		case PROC_TGID_EXE:
-			inode->i_op = &proc_pid_link_inode_operations;
-			ei->op.proc_get_link = proc_exe_link;
-			break;
-		case PROC_TID_CWD:
-		case PROC_TGID_CWD:
-			inode->i_op = &proc_pid_link_inode_operations;
-			ei->op.proc_get_link = proc_cwd_link;
-			break;
-		case PROC_TID_ROOT:
-		case PROC_TGID_ROOT:
-			inode->i_op = &proc_pid_link_inode_operations;
-			ei->op.proc_get_link = proc_root_link;
-			break;
-		case PROC_TID_ENVIRON:
-		case PROC_TGID_ENVIRON:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_pid_environ;
-			break;
-		case PROC_TID_AUXV:
-		case PROC_TGID_AUXV:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_pid_auxv;
-			break;
-		case PROC_TID_STATUS:
-		case PROC_TGID_STATUS:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_pid_status;
-			break;
-		case PROC_TID_STAT:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_tid_stat;
-			break;
-		case PROC_TGID_STAT:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_tgid_stat;
-			break;
-		case PROC_TID_CMDLINE:
-		case PROC_TGID_CMDLINE:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_pid_cmdline;
-			break;
-		case PROC_TID_STATM:
-		case PROC_TGID_STATM:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_pid_statm;
-			break;
-		case PROC_TID_MAPS:
-		case PROC_TGID_MAPS:
-			inode->i_fop = &proc_maps_operations;
-			break;
-#ifdef CONFIG_NUMA
-		case PROC_TID_NUMA_MAPS:
-		case PROC_TGID_NUMA_MAPS:
-			inode->i_fop = &proc_numa_maps_operations;
-			break;
-#endif
-		case PROC_TID_MEM:
-		case PROC_TGID_MEM:
-			inode->i_fop = &proc_mem_operations;
-			break;
-#ifdef CONFIG_SECCOMP
-		case PROC_TID_SECCOMP:
-		case PROC_TGID_SECCOMP:
-			inode->i_fop = &proc_seccomp_operations;
-			break;
-#endif /* CONFIG_SECCOMP */
-		case PROC_TID_MOUNTS:
-		case PROC_TGID_MOUNTS:
-			inode->i_fop = &proc_mounts_operations;
-			break;
-#ifdef CONFIG_MMU
-		case PROC_TID_SMAPS:
-		case PROC_TGID_SMAPS:
-			inode->i_fop = &proc_smaps_operations;
-			break;
-#endif
-		case PROC_TID_MOUNTSTATS:
-		case PROC_TGID_MOUNTSTATS:
-			inode->i_fop = &proc_mountstats_operations;
-			break;
-#ifdef CONFIG_SECURITY
-		case PROC_TID_ATTR:
-			inode->i_nlink = 2;
-			inode->i_op = &proc_tid_attr_inode_operations;
-			inode->i_fop = &proc_tid_attr_operations;
-			break;
-		case PROC_TGID_ATTR:
-			inode->i_nlink = 2;
-			inode->i_op = &proc_tgid_attr_inode_operations;
-			inode->i_fop = &proc_tgid_attr_operations;
-			break;
-		case PROC_TID_ATTR_CURRENT:
-		case PROC_TGID_ATTR_CURRENT:
-		case PROC_TID_ATTR_PREV:
-		case PROC_TGID_ATTR_PREV:
-		case PROC_TID_ATTR_EXEC:
-		case PROC_TGID_ATTR_EXEC:
-		case PROC_TID_ATTR_FSCREATE:
-		case PROC_TGID_ATTR_FSCREATE:
-		case PROC_TID_ATTR_KEYCREATE:
-		case PROC_TGID_ATTR_KEYCREATE:
-		case PROC_TID_ATTR_SOCKCREATE:
-		case PROC_TGID_ATTR_SOCKCREATE:
-			inode->i_fop = &proc_pid_attr_operations;
-			break;
-#endif
-#ifdef CONFIG_KALLSYMS
-		case PROC_TID_WCHAN:
-		case PROC_TGID_WCHAN:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_pid_wchan;
-			break;
-#endif
-#ifdef CONFIG_SCHEDSTATS
-		case PROC_TID_SCHEDSTAT:
-		case PROC_TGID_SCHEDSTAT:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_pid_schedstat;
-			break;
-#endif
-#ifdef CONFIG_CPUSETS
-		case PROC_TID_CPUSET:
-		case PROC_TGID_CPUSET:
-			inode->i_fop = &proc_cpuset_operations;
-			break;
-#endif
-		case PROC_TID_OOM_SCORE:
-		case PROC_TGID_OOM_SCORE:
-			inode->i_fop = &proc_info_file_operations;
-			ei->op.proc_read = proc_oom_score;
-			break;
-		case PROC_TID_OOM_ADJUST:
-		case PROC_TGID_OOM_ADJUST:
-			inode->i_fop = &proc_oom_adjust_operations;
-			break;
-#ifdef CONFIG_AUDITSYSCALL
-		case PROC_TID_LOGINUID:
-		case PROC_TGID_LOGINUID:
-			inode->i_fop = &proc_loginuid_operations;
-			break;
-#endif
-		default:
-			printk("procfs: impossible type (%d)",p->type);
-			iput(inode);
-			error = ERR_PTR(-EINVAL);
-			goto out;
-	}
-	dentry->d_op = &pid_dentry_operations;
-	d_add(dentry, inode);
-	/* Close the race of the process dying before we return the dentry */
-	if (pid_revalidate(dentry, NULL))
-		error = NULL;
-out:
-	put_task_struct(task);
-out_no_task:
-	return error;
-}
-
-static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
-	return proc_pident_lookup(dir, dentry, tgid_base_stuff);
-}
-
-static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
-	return proc_pident_lookup(dir, dentry, tid_base_stuff);
-}
-
-static struct file_operations proc_tgid_base_operations = {
-	.read		= generic_read_dir,
-	.readdir	= proc_tgid_base_readdir,
+static struct pid_entry attr_dir_stuff[] = {
+	REG("current",    S_IRUGO|S_IWUGO, pid_attr),
+	REG("prev",       S_IRUGO,	   pid_attr),
+	REG("exec",       S_IRUGO|S_IWUGO, pid_attr),
+	REG("fscreate",   S_IRUGO|S_IWUGO, pid_attr),
+	REG("keycreate",  S_IRUGO|S_IWUGO, pid_attr),
+	REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr),
 };
 
-static struct file_operations proc_tid_base_operations = {
-	.read		= generic_read_dir,
-	.readdir	= proc_tid_base_readdir,
-};
-
-static struct inode_operations proc_tgid_base_inode_operations = {
-	.lookup		= proc_tgid_base_lookup,
-	.getattr	= pid_getattr,
-	.setattr	= proc_setattr,
-};
-
-static struct inode_operations proc_tid_base_inode_operations = {
-	.lookup		= proc_tid_base_lookup,
-	.getattr	= pid_getattr,
-	.setattr	= proc_setattr,
-};
-
-#ifdef CONFIG_SECURITY
-static int proc_tgid_attr_readdir(struct file * filp,
+static int proc_attr_dir_readdir(struct file * filp,
 			     void * dirent, filldir_t filldir)
 {
 	return proc_pident_readdir(filp,dirent,filldir,
-				   tgid_attr_stuff,ARRAY_SIZE(tgid_attr_stuff));
+				   attr_dir_stuff,ARRAY_SIZE(attr_dir_stuff));
 }
 
-static int proc_tid_attr_readdir(struct file * filp,
-			     void * dirent, filldir_t filldir)
-{
-	return proc_pident_readdir(filp,dirent,filldir,
-				   tid_attr_stuff,ARRAY_SIZE(tid_attr_stuff));
-}
-
-static struct file_operations proc_tgid_attr_operations = {
+static struct file_operations proc_attr_dir_operations = {
 	.read		= generic_read_dir,
-	.readdir	= proc_tgid_attr_readdir,
+	.readdir	= proc_attr_dir_readdir,
 };
 
-static struct file_operations proc_tid_attr_operations = {
-	.read		= generic_read_dir,
-	.readdir	= proc_tid_attr_readdir,
-};
-
-static struct dentry *proc_tgid_attr_lookup(struct inode *dir,
+static struct dentry *proc_attr_dir_lookup(struct inode *dir,
 				struct dentry *dentry, struct nameidata *nd)
 {
-	return proc_pident_lookup(dir, dentry, tgid_attr_stuff);
+	return proc_pident_lookup(dir, dentry,
+				  attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
 }
 
-static struct dentry *proc_tid_attr_lookup(struct inode *dir,
-				struct dentry *dentry, struct nameidata *nd)
-{
-	return proc_pident_lookup(dir, dentry, tid_attr_stuff);
-}
-
-static struct inode_operations proc_tgid_attr_inode_operations = {
-	.lookup		= proc_tgid_attr_lookup,
+static struct inode_operations proc_attr_dir_inode_operations = {
+	.lookup		= proc_attr_dir_lookup,
 	.getattr	= pid_getattr,
 	.setattr	= proc_setattr,
 };
 
-static struct inode_operations proc_tid_attr_inode_operations = {
-	.lookup		= proc_tid_attr_lookup,
-	.getattr	= pid_getattr,
-	.setattr	= proc_setattr,
-};
 #endif
 
 /*
@@ -1948,13 +1614,205 @@
 	char tmp[PROC_NUMBUF];
 	sprintf(tmp, "%d", current->tgid);
 	return ERR_PTR(vfs_follow_link(nd,tmp));
-}	
+}
 
 static struct inode_operations proc_self_inode_operations = {
 	.readlink	= proc_self_readlink,
 	.follow_link	= proc_self_follow_link,
 };
 
+/*
+ * proc base
+ *
+ * These are the directory entries in the root directory of /proc
+ * that properly belong to the /proc filesystem, as they describe
+ * describe something that is process related.
+ */
+static struct pid_entry proc_base_stuff[] = {
+	NOD("self", S_IFLNK|S_IRWXUGO,
+		&proc_self_inode_operations, NULL, {}),
+};
+
+/*
+ *	Exceptional case: normally we are not allowed to unhash a busy
+ * directory. In this case, however, we can do it - no aliasing problems
+ * due to the way we treat inodes.
+ */
+static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+	struct inode *inode = dentry->d_inode;
+	struct task_struct *task = get_proc_task(inode);
+	if (task) {
+		put_task_struct(task);
+		return 1;
+	}
+	d_drop(dentry);
+	return 0;
+}
+
+static struct dentry_operations proc_base_dentry_operations =
+{
+	.d_revalidate	= proc_base_revalidate,
+	.d_delete	= pid_delete_dentry,
+};
+
+static struct dentry *proc_base_instantiate(struct inode *dir,
+	struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+	struct pid_entry *p = ptr;
+	struct inode *inode;
+	struct proc_inode *ei;
+	struct dentry *error = ERR_PTR(-EINVAL);
+
+	/* Allocate the inode */
+	error = ERR_PTR(-ENOMEM);
+	inode = new_inode(dir->i_sb);
+	if (!inode)
+		goto out;
+
+	/* Initialize the inode */
+	ei = PROC_I(inode);
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+
+	/*
+	 * grab the reference to the task.
+	 */
+	ei->pid = get_task_pid(task, PIDTYPE_PID);
+	if (!ei->pid)
+		goto out_iput;
+
+	inode->i_uid = 0;
+	inode->i_gid = 0;
+	inode->i_mode = p->mode;
+	if (S_ISDIR(inode->i_mode))
+		inode->i_nlink = 2;
+	if (S_ISLNK(inode->i_mode))
+		inode->i_size = 64;
+	if (p->iop)
+		inode->i_op = p->iop;
+	if (p->fop)
+		inode->i_fop = p->fop;
+	ei->op = p->op;
+	dentry->d_op = &proc_base_dentry_operations;
+	d_add(dentry, inode);
+	error = NULL;
+out:
+	return error;
+out_iput:
+	iput(inode);
+	goto out;
+}
+
+static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
+{
+	struct dentry *error;
+	struct task_struct *task = get_proc_task(dir);
+	struct pid_entry *p, *last;
+
+	error = ERR_PTR(-ENOENT);
+
+	if (!task)
+		goto out_no_task;
+
+	/* Lookup the directory entry */
+	last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1];
+	for (p = proc_base_stuff; p <= last; p++) {
+		if (p->len != dentry->d_name.len)
+			continue;
+		if (!memcmp(dentry->d_name.name, p->name, p->len))
+			break;
+	}
+	if (p > last)
+		goto out;
+
+	error = proc_base_instantiate(dir, dentry, task, p);
+
+out:
+	put_task_struct(task);
+out_no_task:
+	return error;
+}
+
+static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+	struct task_struct *task, struct pid_entry *p)
+{
+	return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
+				proc_base_instantiate, task, p);
+}
+
+/*
+ * Thread groups
+ */
+static struct file_operations proc_task_operations;
+static struct inode_operations proc_task_inode_operations;
+
+static struct pid_entry tgid_base_stuff[] = {
+	DIR("task",       S_IRUGO|S_IXUGO, task),
+	DIR("fd",         S_IRUSR|S_IXUSR, fd),
+	INF("environ",    S_IRUSR, pid_environ),
+	INF("auxv",       S_IRUSR, pid_auxv),
+	INF("status",     S_IRUGO, pid_status),
+	INF("cmdline",    S_IRUGO, pid_cmdline),
+	INF("stat",       S_IRUGO, tgid_stat),
+	INF("statm",      S_IRUGO, pid_statm),
+	REG("maps",       S_IRUGO, maps),
+#ifdef CONFIG_NUMA
+	REG("numa_maps",  S_IRUGO, numa_maps),
+#endif
+	REG("mem",        S_IRUSR|S_IWUSR, mem),
+#ifdef CONFIG_SECCOMP
+	REG("seccomp",    S_IRUSR|S_IWUSR, seccomp),
+#endif
+	LNK("cwd",        cwd),
+	LNK("root",       root),
+	LNK("exe",        exe),
+	REG("mounts",     S_IRUGO, mounts),
+	REG("mountstats", S_IRUSR, mountstats),
+#ifdef CONFIG_MMU
+	REG("smaps",      S_IRUGO, smaps),
+#endif
+#ifdef CONFIG_SECURITY
+	DIR("attr",       S_IRUGO|S_IXUGO, attr_dir),
+#endif
+#ifdef CONFIG_KALLSYMS
+	INF("wchan",      S_IRUGO, pid_wchan),
+#endif
+#ifdef CONFIG_SCHEDSTATS
+	INF("schedstat",  S_IRUGO, pid_schedstat),
+#endif
+#ifdef CONFIG_CPUSETS
+	REG("cpuset",     S_IRUGO, cpuset),
+#endif
+	INF("oom_score",  S_IRUGO, oom_score),
+	REG("oom_adj",    S_IRUGO|S_IWUSR, oom_adjust),
+#ifdef CONFIG_AUDITSYSCALL
+	REG("loginuid",   S_IWUSR|S_IRUGO, loginuid),
+#endif
+};
+
+static int proc_tgid_base_readdir(struct file * filp,
+			     void * dirent, filldir_t filldir)
+{
+	return proc_pident_readdir(filp,dirent,filldir,
+				   tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
+}
+
+static struct file_operations proc_tgid_base_operations = {
+	.read		= generic_read_dir,
+	.readdir	= proc_tgid_base_readdir,
+};
+
+static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+	return proc_pident_lookup(dir, dentry,
+				  tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
+}
+
+static struct inode_operations proc_tgid_base_inode_operations = {
+	.lookup		= proc_tgid_base_lookup,
+	.getattr	= pid_getattr,
+	.setattr	= proc_setattr,
+};
+
 /**
  * proc_flush_task -  Remove dcache entries for @task from the /proc dcache.
  *
@@ -2022,30 +1880,45 @@
 	return;
 }
 
-/* SMP-safe */
+struct dentry *proc_pid_instantiate(struct inode *dir,
+	struct dentry * dentry, struct task_struct *task, void *ptr)
+{
+	struct dentry *error = ERR_PTR(-ENOENT);
+	struct inode *inode;
+
+	inode = proc_pid_make_inode(dir->i_sb, task);
+	if (!inode)
+		goto out;
+
+	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+	inode->i_op = &proc_tgid_base_inode_operations;
+	inode->i_fop = &proc_tgid_base_operations;
+	inode->i_flags|=S_IMMUTABLE;
+	inode->i_nlink = 4;
+#ifdef CONFIG_SECURITY
+	inode->i_nlink += 1;
+#endif
+
+	dentry->d_op = &pid_dentry_operations;
+
+	d_add(dentry, inode);
+	/* Close the race of the process dying before we return the dentry */
+	if (pid_revalidate(dentry, NULL))
+		error = NULL;
+out:
+	return error;
+}
+
 struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
 	struct dentry *result = ERR_PTR(-ENOENT);
 	struct task_struct *task;
-	struct inode *inode;
-	struct proc_inode *ei;
 	unsigned tgid;
 
-	if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
-		inode = new_inode(dir->i_sb);
-		if (!inode)
-			return ERR_PTR(-ENOMEM);
-		ei = PROC_I(inode);
-		inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-		inode->i_ino = fake_ino(0, PROC_TGID_INO);
-		ei->pde = NULL;
-		inode->i_mode = S_IFLNK|S_IRWXUGO;
-		inode->i_uid = inode->i_gid = 0;
-		inode->i_size = 64;
-		inode->i_op = &proc_self_inode_operations;
-		d_add(dentry, inode);
-		return NULL;
-	}
+	result = proc_base_lookup(dir, dentry);
+	if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
+		goto out;
+
 	tgid = name_to_int(dentry);
 	if (tgid == ~0U)
 		goto out;
@@ -2058,18 +1931,178 @@
 	if (!task)
 		goto out;
 
-	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
-	if (!inode)
-		goto out_put_task;
+	result = proc_pid_instantiate(dir, dentry, task, NULL);
+	put_task_struct(task);
+out:
+	return result;
+}
 
-	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
-	inode->i_op = &proc_tgid_base_inode_operations;
-	inode->i_fop = &proc_tgid_base_operations;
-	inode->i_flags|=S_IMMUTABLE;
+/*
+ * Find the first task with tgid >= tgid
+ *
+ */
+static struct task_struct *next_tgid(unsigned int tgid)
+{
+	struct task_struct *task;
+	struct pid *pid;
+
+	rcu_read_lock();
+retry:
+	task = NULL;
+	pid = find_ge_pid(tgid);
+	if (pid) {
+		tgid = pid->nr + 1;
+		task = pid_task(pid, PIDTYPE_PID);
+		/* What we to know is if the pid we have find is the
+		 * pid of a thread_group_leader.  Testing for task
+		 * being a thread_group_leader is the obvious thing
+		 * todo but there is a window when it fails, due to
+		 * the pid transfer logic in de_thread.
+		 *
+		 * So we perform the straight forward test of seeing
+		 * if the pid we have found is the pid of a thread
+		 * group leader, and don't worry if the task we have
+		 * found doesn't happen to be a thread group leader.
+		 * As we don't care in the case of readdir.
+		 */
+		if (!task || !has_group_leader_pid(task))
+			goto retry;
+		get_task_struct(task);
+	}
+	rcu_read_unlock();
+	return task;
+}
+
+#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
+
+static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+	struct task_struct *task, int tgid)
+{
+	char name[PROC_NUMBUF];
+	int len = snprintf(name, sizeof(name), "%d", tgid);
+	return proc_fill_cache(filp, dirent, filldir, name, len,
+				proc_pid_instantiate, task, NULL);
+}
+
+/* for the /proc/ directory itself, after non-process stuff has been done */
+int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+{
+	unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
+	struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode);
+	struct task_struct *task;
+	int tgid;
+
+	if (!reaper)
+		goto out_no_task;
+
+	for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
+		struct pid_entry *p = &proc_base_stuff[nr];
+		if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
+			goto out;
+	}
+
+	tgid = filp->f_pos - TGID_OFFSET;
+	for (task = next_tgid(tgid);
+	     task;
+	     put_task_struct(task), task = next_tgid(tgid + 1)) {
+		tgid = task->pid;
+		filp->f_pos = tgid + TGID_OFFSET;
+		if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
+			put_task_struct(task);
+			goto out;
+		}
+	}
+	filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET;
+out:
+	put_task_struct(reaper);
+out_no_task:
+	return 0;
+}
+
+/*
+ * Tasks
+ */
+static struct pid_entry tid_base_stuff[] = {
+	DIR("fd",        S_IRUSR|S_IXUSR, fd),
+	INF("environ",   S_IRUSR, pid_environ),
+	INF("auxv",      S_IRUSR, pid_auxv),
+	INF("status",    S_IRUGO, pid_status),
+	INF("cmdline",   S_IRUGO, pid_cmdline),
+	INF("stat",      S_IRUGO, tid_stat),
+	INF("statm",     S_IRUGO, pid_statm),
+	REG("maps",      S_IRUGO, maps),
+#ifdef CONFIG_NUMA
+	REG("numa_maps", S_IRUGO, numa_maps),
+#endif
+	REG("mem",       S_IRUSR|S_IWUSR, mem),
+#ifdef CONFIG_SECCOMP
+	REG("seccomp",   S_IRUSR|S_IWUSR, seccomp),
+#endif
+	LNK("cwd",       cwd),
+	LNK("root",      root),
+	LNK("exe",       exe),
+	REG("mounts",    S_IRUGO, mounts),
+#ifdef CONFIG_MMU
+	REG("smaps",     S_IRUGO, smaps),
+#endif
 #ifdef CONFIG_SECURITY
-	inode->i_nlink = 5;
-#else
-	inode->i_nlink = 4;
+	DIR("attr",      S_IRUGO|S_IXUGO, attr_dir),
+#endif
+#ifdef CONFIG_KALLSYMS
+	INF("wchan",     S_IRUGO, pid_wchan),
+#endif
+#ifdef CONFIG_SCHEDSTATS
+	INF("schedstat", S_IRUGO, pid_schedstat),
+#endif
+#ifdef CONFIG_CPUSETS
+	REG("cpuset",    S_IRUGO, cpuset),
+#endif
+	INF("oom_score", S_IRUGO, oom_score),
+	REG("oom_adj",   S_IRUGO|S_IWUSR, oom_adjust),
+#ifdef CONFIG_AUDITSYSCALL
+	REG("loginuid",  S_IWUSR|S_IRUGO, loginuid),
+#endif
+};
+
+static int proc_tid_base_readdir(struct file * filp,
+			     void * dirent, filldir_t filldir)
+{
+	return proc_pident_readdir(filp,dirent,filldir,
+				   tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
+}
+
+static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+	return proc_pident_lookup(dir, dentry,
+				  tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
+}
+
+static struct file_operations proc_tid_base_operations = {
+	.read		= generic_read_dir,
+	.readdir	= proc_tid_base_readdir,
+};
+
+static struct inode_operations proc_tid_base_inode_operations = {
+	.lookup		= proc_tid_base_lookup,
+	.getattr	= pid_getattr,
+	.setattr	= proc_setattr,
+};
+
+static struct dentry *proc_task_instantiate(struct inode *dir,
+	struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+	struct dentry *error = ERR_PTR(-ENOENT);
+	struct inode *inode;
+	inode = proc_pid_make_inode(dir->i_sb, task);
+
+	if (!inode)
+		goto out;
+	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+	inode->i_op = &proc_tid_base_inode_operations;
+	inode->i_fop = &proc_tid_base_operations;
+	inode->i_flags|=S_IMMUTABLE;
+	inode->i_nlink = 3;
+#ifdef CONFIG_SECURITY
+	inode->i_nlink += 1;
 #endif
 
 	dentry->d_op = &pid_dentry_operations;
@@ -2077,21 +2110,16 @@
 	d_add(dentry, inode);
 	/* Close the race of the process dying before we return the dentry */
 	if (pid_revalidate(dentry, NULL))
-		result = NULL;
-
-out_put_task:
-	put_task_struct(task);
+		error = NULL;
 out:
-	return result;
+	return error;
 }
 
-/* SMP-safe */
 static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
 	struct dentry *result = ERR_PTR(-ENOENT);
 	struct task_struct *task;
 	struct task_struct *leader = get_proc_task(dir);
-	struct inode *inode;
 	unsigned tid;
 
 	if (!leader)
@@ -2111,28 +2139,7 @@
 	if (leader->tgid != task->tgid)
 		goto out_drop_task;
 
-	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
-
-
-	if (!inode)
-		goto out_drop_task;
-	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
-	inode->i_op = &proc_tid_base_inode_operations;
-	inode->i_fop = &proc_tid_base_operations;
-	inode->i_flags|=S_IMMUTABLE;
-#ifdef CONFIG_SECURITY
-	inode->i_nlink = 4;
-#else
-	inode->i_nlink = 3;
-#endif
-
-	dentry->d_op = &pid_dentry_operations;
-
-	d_add(dentry, inode);
-	/* Close the race of the process dying before we return the dentry */
-	if (pid_revalidate(dentry, NULL))
-		result = NULL;
-
+	result = proc_task_instantiate(dir, dentry, task, NULL);
 out_drop_task:
 	put_task_struct(task);
 out:
@@ -2142,114 +2149,6 @@
 }
 
 /*
- * Find the first tgid to return to user space.
- *
- * Usually this is just whatever follows &init_task, but if the users
- * buffer was too small to hold the full list or there was a seek into
- * the middle of the directory we have more work to do.
- *
- * In the case of a short read we start with find_task_by_pid.
- *
- * In the case of a seek we start with &init_task and walk nr
- * threads past it.
- */
-static struct task_struct *first_tgid(int tgid, unsigned int nr)
-{
-	struct task_struct *pos;
-	rcu_read_lock();
-	if (tgid && nr) {
-		pos = find_task_by_pid(tgid);
-		if (pos && thread_group_leader(pos))
-			goto found;
-	}
-	/* If nr exceeds the number of processes get out quickly */
-	pos = NULL;
-	if (nr && nr >= nr_processes())
-		goto done;
-
-	/* If we haven't found our starting place yet start with
-	 * the init_task and walk nr tasks forward.
-	 */
-	for (pos = next_task(&init_task); nr > 0; --nr) {
-		pos = next_task(pos);
-		if (pos == &init_task) {
-			pos = NULL;
-			goto done;
-		}
-	}
-found:
-	get_task_struct(pos);
-done:
-	rcu_read_unlock();
-	return pos;
-}
-
-/*
- * Find the next task in the task list.
- * Return NULL if we loop or there is any error.
- *
- * The reference to the input task_struct is released.
- */
-static struct task_struct *next_tgid(struct task_struct *start)
-{
-	struct task_struct *pos;
-	rcu_read_lock();
-	pos = start;
-	if (pid_alive(start))
-		pos = next_task(start);
-	if (pid_alive(pos) && (pos != &init_task)) {
-		get_task_struct(pos);
-		goto done;
-	}
-	pos = NULL;
-done:
-	rcu_read_unlock();
-	put_task_struct(start);
-	return pos;
-}
-
-/* for the /proc/ directory itself, after non-process stuff has been done */
-int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
-{
-	char buf[PROC_NUMBUF];
-	unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
-	struct task_struct *task;
-	int tgid;
-
-	if (!nr) {
-		ino_t ino = fake_ino(0,PROC_TGID_INO);
-		if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0)
-			return 0;
-		filp->f_pos++;
-		nr++;
-	}
-	nr -= 1;
-
-	/* f_version caches the tgid value that the last readdir call couldn't
-	 * return. lseek aka telldir automagically resets f_version to 0.
-	 */
-	tgid = filp->f_version;
-	filp->f_version = 0;
-	for (task = first_tgid(tgid, nr);
-	     task;
-	     task = next_tgid(task), filp->f_pos++) {
-		int len;
-		ino_t ino;
-		tgid = task->pid;
-		len = snprintf(buf, sizeof(buf), "%d", tgid);
-		ino = fake_ino(tgid, PROC_TGID_INO);
-		if (filldir(dirent, buf, len, filp->f_pos, ino, DT_DIR) < 0) {
-			/* returning this tgid failed, save it as the first
-			 * pid for the next readir call */
-			filp->f_version = tgid;
-			put_task_struct(task);
-			break;
-		}
-	}
-	return 0;
-}
-
-/*
  * Find the first tid of a thread group to return to user space.
  *
  * Usually this is just the thread group leader, but if the users
@@ -2318,10 +2217,18 @@
 	return pos;
 }
 
+static int proc_task_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+	struct task_struct *task, int tid)
+{
+	char name[PROC_NUMBUF];
+	int len = snprintf(name, sizeof(name), "%d", tid);
+	return proc_fill_cache(filp, dirent, filldir, name, len,
+				proc_task_instantiate, task, NULL);
+}
+
 /* for the /proc/TGID/task/ directories */
 static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-	char buf[PROC_NUMBUF];
 	struct dentry *dentry = filp->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	struct task_struct *leader = get_proc_task(inode);
@@ -2358,11 +2265,8 @@
 	for (task = first_tid(leader, tid, pos - 2);
 	     task;
 	     task = next_tid(task), pos++) {
-		int len;
 		tid = task->pid;
-		len = snprintf(buf, sizeof(buf), "%d", tid);
-		ino = fake_ino(tid, PROC_TID_INO);
-		if (filldir(dirent, buf, len, pos, ino, DT_DIR < 0)) {
+		if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
 			/* returning this tgid failed, save it as the first
 			 * pid for the next readir call */
 			filp->f_version = tid;
@@ -2392,3 +2296,14 @@
 
 	return 0;
 }
+
+static struct inode_operations proc_task_inode_operations = {
+	.lookup		= proc_task_lookup,
+	.getattr	= proc_task_getattr,
+	.setattr	= proc_setattr,
+};
+
+static struct file_operations proc_task_operations = {
+	.read		= generic_read_dir,
+	.readdir	= proc_task_readdir,
+};
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 66bc425..8d88e58 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -45,6 +45,7 @@
 #include <linux/sysrq.h>
 #include <linux/vmalloc.h>
 #include <linux/crash_dump.h>
+#include <linux/pspace.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -91,7 +92,7 @@
 		LOAD_INT(a), LOAD_FRAC(a),
 		LOAD_INT(b), LOAD_FRAC(b),
 		LOAD_INT(c), LOAD_FRAC(c),
-		nr_running(), nr_threads, last_pid);
+		nr_running(), nr_threads, init_pspace.last_pid);
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 8901c65..ffe66c3 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/smp_lock.h>
+#include <linux/mount.h>
 
 #include "internal.h"
 
@@ -28,6 +29,17 @@
 static int proc_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
+	if (proc_mnt) {
+		/* Seed the root directory with a pid so it doesn't need
+		 * to be special in base.c.  I would do this earlier but
+		 * the only task alive when /proc is mounted the first time
+		 * is the init_task and it doesn't have any pids.
+		 */
+		struct proc_inode *ei;
+		ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode);
+		if (!ei->pid)
+			ei->pid = find_get_pid(1);
+	}
 	return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
 }
 
diff --git a/fs/readdir.c b/fs/readdir.c
index b610932..bff3ee5 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -69,20 +69,24 @@
 };
 
 static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
-		      ino_t ino, unsigned int d_type)
+		      u64 ino, unsigned int d_type)
 {
 	struct readdir_callback * buf = (struct readdir_callback *) __buf;
 	struct old_linux_dirent __user * dirent;
+	unsigned long d_ino;
 
 	if (buf->result)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	buf->result++;
 	dirent = buf->dirent;
 	if (!access_ok(VERIFY_WRITE, dirent,
 			(unsigned long)(dirent->d_name + namlen + 1) -
 				(unsigned long)dirent))
 		goto efault;
-	if (	__put_user(ino, &dirent->d_ino) ||
+	if (	__put_user(d_ino, &dirent->d_ino) ||
 		__put_user(offset, &dirent->d_offset) ||
 		__put_user(namlen, &dirent->d_namlen) ||
 		__copy_to_user(dirent->d_name, name, namlen) ||
@@ -138,22 +142,26 @@
 };
 
 static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
-		   ino_t ino, unsigned int d_type)
+		   u64 ino, unsigned int d_type)
 {
 	struct linux_dirent __user * dirent;
 	struct getdents_callback * buf = (struct getdents_callback *) __buf;
+	unsigned long d_ino;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
 
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count)
 		return -EINVAL;
+	d_ino = ino;
+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+		return -EOVERFLOW;
 	dirent = buf->previous;
 	if (dirent) {
 		if (__put_user(offset, &dirent->d_off))
 			goto efault;
 	}
 	dirent = buf->current_dir;
-	if (__put_user(ino, &dirent->d_ino))
+	if (__put_user(d_ino, &dirent->d_ino))
 		goto efault;
 	if (__put_user(reclen, &dirent->d_reclen))
 		goto efault;
@@ -222,7 +230,7 @@
 };
 
 static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
-		     ino_t ino, unsigned int d_type)
+		     u64 ino, unsigned int d_type)
 {
 	struct linux_dirent64 __user *dirent;
 	struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 41f2436..c093642 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -38,8 +38,7 @@
 	int err;
 	int jbegin_failure = 0;
 
-	if (!S_ISREG(inode->i_mode))
-		BUG();
+	BUG_ON(!S_ISREG(inode->i_mode));
 
 	/* fast out for when nothing needs to be done */
 	if ((atomic_read(&inode->i_count) > 1 ||
@@ -125,8 +124,7 @@
 	int n_err;
 	int barrier_done;
 
-	if (!S_ISREG(p_s_inode->i_mode))
-		BUG();
+	BUG_ON(!S_ISREG(p_s_inode->i_mode));
 	n_err = sync_mapping_buffers(p_s_inode->i_mapping);
 	reiserfs_write_lock(p_s_inode->i_sb);
 	barrier_done = reiserfs_commit_for_inode(p_s_inode);
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 7e5a2f5..9c69bca 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1780,7 +1780,7 @@
 		err = -EDQUOT;
 		goto out_end_trans;
 	}
-	if (!dir || !dir->i_nlink) {
+	if (!dir->i_nlink) {
 		err = -EPERM;
 		goto out_bad_inode;
 	}
diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
index 7a88adb..b9b423b 100644
--- a/fs/reiserfs/item_ops.c
+++ b/fs/reiserfs/item_ops.c
@@ -75,8 +75,7 @@
 static int sd_check_left(struct virtual_item *vi, int free,
 			 int start_skip, int end_skip)
 {
-	if (start_skip || end_skip)
-		BUG();
+	BUG_ON(start_skip || end_skip);
 	return -1;
 }
 
@@ -87,8 +86,7 @@
 
 static int sd_part_size(struct virtual_item *vi, int first, int count)
 {
-	if (count)
-		BUG();
+	BUG_ON(count);
 	return 0;
 }
 
@@ -476,8 +474,7 @@
 
 	vi->vi_index = TYPE_DIRENTRY;
 
-	if (!(vi->vi_ih) || !vi->vi_item)
-		BUG();
+	BUG_ON(!(vi->vi_ih) || !vi->vi_item);
 
 	dir_u->flags = 0;
 	if (le_ih_k_offset(vi->vi_ih) == DOT_OFFSET)
@@ -575,8 +572,7 @@
 		free -= dir_u->entry_sizes[i];
 		entries++;
 	}
-	if (entries == dir_u->entry_count)
-		BUG();
+	BUG_ON(entries == dir_u->entry_count);
 
 	/* "." and ".." can not be separated from each other */
 	if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index e6b5ccf..ad8cbc4 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -718,8 +718,7 @@
 			spinlock_t * lock, void (fn) (struct buffer_chunk *))
 {
 	int ret = 0;
-	if (chunk->nr >= CHUNK_SIZE)
-		BUG();
+	BUG_ON(chunk->nr >= CHUNK_SIZE);
 	chunk->bh[chunk->nr++] = bh;
 	if (chunk->nr >= CHUNK_SIZE) {
 		ret = 1;
@@ -788,8 +787,7 @@
 		/* buffer must be locked for __add_jh, should be able to have
 		 * two adds at the same time
 		 */
-		if (bh->b_private)
-			BUG();
+		BUG_ON(bh->b_private);
 		jh->bh = bh;
 		bh->b_private = jh;
 	}
@@ -2967,8 +2965,7 @@
 	int retval;
 
 	reiserfs_check_lock_depth(p_s_sb, "journal_begin");
-	if (nblocks > journal->j_trans_max)
-		BUG();
+	BUG_ON(nblocks > journal->j_trans_max);
 
 	PROC_INFO_INC(p_s_sb, journal.journal_being);
 	/* set here for journal_join */
@@ -3084,9 +3081,8 @@
 	if (reiserfs_transaction_running(s)) {
 		th = current->journal_info;
 		th->t_refcount++;
-		if (th->t_refcount < 2) {
-			BUG();
-		}
+		BUG_ON(th->t_refcount < 2);
+		
 		return th;
 	}
 	th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS);
@@ -3126,9 +3122,7 @@
 	 ** pointer
 	 */
 	th->t_handle_save = cur_th;
-	if (cur_th && cur_th->t_refcount > 1) {
-		BUG();
-	}
+	BUG_ON(cur_th && cur_th->t_refcount > 1);
 	return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_JOIN);
 }
 
@@ -3141,9 +3135,7 @@
 	 ** pointer
 	 */
 	th->t_handle_save = cur_th;
-	if (cur_th && cur_th->t_refcount > 1) {
-		BUG();
-	}
+	BUG_ON(cur_th && cur_th->t_refcount > 1);
 	return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_ABORT);
 }
 
@@ -3178,8 +3170,7 @@
 		current->journal_info = th;
 	}
 	ret = do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_REG);
-	if (current->journal_info != th)
-		BUG();
+	BUG_ON(current->journal_info != th);
 
 	/* I guess this boils down to being the reciprocal of clm-2100 above.
 	 * If do_journal_begin_r fails, we need to put it back, since journal_end
@@ -3324,8 +3315,7 @@
 		/* we aren't allowed to close a nested transaction on a different
 		 ** filesystem from the one in the task struct
 		 */
-		if (cur_th->t_super != th->t_super)
-			BUG();
+		BUG_ON(cur_th->t_super != th->t_super);
 
 		if (th != cur_th) {
 			memcpy(current->journal_info, th, sizeof(*th));
@@ -3444,9 +3434,7 @@
 
 	BUG_ON(!th->t_trans_id);
 	/* you can sync while nested, very, very bad */
-	if (th->t_refcount > 1) {
-		BUG();
-	}
+	BUG_ON(th->t_refcount > 1);
 	if (journal->j_len == 0) {
 		reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb),
 					     1);
@@ -3556,9 +3544,8 @@
 	 ** will be dealt with by next transaction that actually writes something, but should be taken
 	 ** care of in this trans
 	 */
-	if (journal->j_len == 0) {
-		BUG();
-	}
+	BUG_ON(journal->j_len == 0);
+
 	/* if wcount > 0, and we are called to with flush or commit_now,
 	 ** we wait on j_join_wait.  We will wake up when the last writer has
 	 ** finished the transaction, and started it on its way to the disk.
@@ -3592,9 +3579,8 @@
 					unlock_journal(p_s_sb);
 				}
 			}
-			if (journal->j_trans_id == trans_id) {
-				BUG();
-			}
+			BUG_ON(journal->j_trans_id == trans_id);
+			
 			if (commit_now
 			    && journal_list_still_alive(p_s_sb, trans_id)
 			    && wait_on_commit) {
@@ -4074,9 +4060,7 @@
 	set_commit_trans_len(commit, journal->j_len);
 
 	/* special check in case all buffers in the journal were marked for not logging */
-	if (journal->j_len == 0) {
-		BUG();
-	}
+	BUG_ON(journal->j_len == 0);
 
 	/* we're about to dirty all the log blocks, mark the description block
 	 * dirty now too.  Don't mark the commit block dirty until all the
@@ -4173,8 +4157,7 @@
 				      journal, jl, &jl->j_tail_bh_list);
 		lock_kernel();
 	}
-	if (!list_empty(&jl->j_tail_bh_list))
-		BUG();
+	BUG_ON(!list_empty(&jl->j_tail_bh_list));
 	up(&jl->j_commit_lock);
 
 	/* honor the flush wishes from the caller, simple commits can
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 16e9cff..abde1ed 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -67,8 +67,7 @@
 {
 	struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
 
-	if (de->de_entry_num >= ih_entry_count(de->de_ih))
-		BUG();
+	BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih));
 
 	de->de_entrylen = entry_length(de->de_bh, de->de_ih, de->de_entry_num);
 	de->de_namelen = de->de_entrylen - (de_with_sd(deh) ? SD_SIZE : 0);
@@ -80,8 +79,7 @@
 // what entry points to
 static inline void set_de_object_key(struct reiserfs_dir_entry *de)
 {
-	if (de->de_entry_num >= ih_entry_count(de->de_ih))
-		BUG();
+	BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih));
 	de->de_dir_id = deh_dir_id(&(de->de_deh[de->de_entry_num]));
 	de->de_objectid = deh_objectid(&(de->de_deh[de->de_entry_num]));
 }
@@ -90,8 +88,7 @@
 {
 	struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
 
-	if (de->de_entry_num >= ih_entry_count(de->de_ih))
-		BUG();
+	BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih));
 
 	/* store key of the found entry */
 	de->de_entry_key.version = KEY_FORMAT_3_5;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 8b9b131..5240abe 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1476,9 +1476,7 @@
 	int n_block_size = p_s_sb->s_blocksize;
 	int cut_bytes;
 	BUG_ON(!th->t_trans_id);
-
-	if (n_new_file_size != p_s_inode->i_size)
-		BUG();
+	BUG_ON(n_new_file_size != p_s_inode->i_size);
 
 	/* the page being sent in could be NULL if there was an i/o error
 	 ** reading in the last block.  The user will hit problems trying to
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d935fb9..7bdb0ed 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -773,7 +773,7 @@
 
 static int
 reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
-			      loff_t offset, ino_t ino, unsigned int d_type)
+			      loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct dentry *xadir = (struct dentry *)buf;
 
@@ -851,7 +851,7 @@
 /* XXX: If there is a better way to do this, I'd love to hear about it */
 static int
 reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
-			     loff_t offset, ino_t ino, unsigned int d_type)
+			     loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
 	struct dentry *xafile, *xadir = chown_buf->xadir;
@@ -1036,7 +1036,7 @@
 
 static int
 reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
-			  loff_t offset, ino_t ino, unsigned int d_type)
+			  loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
 	int len = 0;
diff --git a/fs/stat.c b/fs/stat.c
index 60a31d5..bca07eb 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -140,6 +140,8 @@
 	memset(&tmp, 0, sizeof(struct __old_kernel_stat));
 	tmp.st_dev = old_encode_dev(stat->dev);
 	tmp.st_ino = stat->ino;
+	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+		return -EOVERFLOW;
 	tmp.st_mode = stat->mode;
 	tmp.st_nlink = stat->nlink;
 	if (tmp.st_nlink != stat->nlink)
@@ -210,6 +212,8 @@
 	tmp.st_dev = new_encode_dev(stat->dev);
 #endif
 	tmp.st_ino = stat->ino;
+	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+		return -EOVERFLOW;
 	tmp.st_mode = stat->mode;
 	tmp.st_nlink = stat->nlink;
 	if (tmp.st_nlink != stat->nlink)
@@ -347,6 +351,8 @@
 	tmp.st_rdev = huge_encode_dev(stat->rdev);
 #endif
 	tmp.st_ino = stat->ino;
+	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+		return -EOVERFLOW;
 #ifdef STAT64_HAS_BROKEN_ST_INO
 	tmp.__st_ino = stat->ino;
 #endif
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index cf37866..146f1de 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -157,8 +157,8 @@
 		if ((retval = fill_read_buffer(file->f_dentry,buffer)))
 			goto out;
 	}
-	pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
-		 __FUNCTION__,count,*ppos,buffer->page);
+	pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
+		 __FUNCTION__, count, *ppos, buffer->page);
 	retval = flush_read_buffer(buffer,buf,count,ppos);
 out:
 	up(&buffer->sem);
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 36fbecc..c75f683 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -53,8 +53,7 @@
 	va_end(ap);
 	spin_unlock_irqrestore(&xfs_err_lock,flags);
 
-	if (level == CE_PANIC)
-		BUG();
+	BUG_ON(level == CE_PANIC);
 }
 
 void
@@ -72,8 +71,7 @@
 		strcat(message, "\n");
 	spin_unlock_irqrestore(&xfs_err_lock,flags);
 	printk("%s%s", err_level[level], message);
-	if (level == CE_PANIC)
-		BUG();
+	BUG_ON(level == CE_PANIC);
 }
 
 void
diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
index bc6e6a9..2cabbd4 100644
--- a/include/asm-alpha/unistd.h
+++ b/include/asm-alpha/unistd.h
@@ -580,75 +580,6 @@
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <linux/syscalls.h>
-#include <asm/ptrace.h>
-
-static inline long open(const char * name, int mode, int flags)
-{
-	return sys_open(name, mode, flags);
-}
-
-static inline long dup(int fd)
-{
-	return sys_dup(fd);
-}
-
-static inline long close(int fd)
-{
-	return sys_close(fd);
-}
-
-static inline off_t lseek(int fd, off_t off, int whence)
-{
-	return sys_lseek(fd, off, whence);
-}
-
-static inline void _exit(int value)
-{
-	sys_exit(value);
-}
-
-#define exit(x) _exit(x)
-
-static inline long write(int fd, const char * buf, size_t nr)
-{
-	return sys_write(fd, buf, nr);
-}
-
-static inline long read(int fd, char * buf, size_t nr)
-{
-	return sys_read(fd, buf, nr);
-}
-
-extern int execve(char *, char **, char **);
-
-static inline long setsid(void)
-{
-	return sys_setsid();
-}
-
-static inline pid_t waitpid(int pid, int * wait_stat, int flags)
-{
-	return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-asmlinkage int sys_execve(char *ufilename, char **argv, char **envp,
-			unsigned long a3, unsigned long a4, unsigned long a5,
-			struct pt_regs regs);
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize,
-				void *restorer);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /* "Conditional" syscalls.  What we want is
 
 	__attribute__((weak,alias("sys_ni_syscall")))
diff --git a/include/asm-arm/arch-clps711x/entry-macro.S b/include/asm-arm/arch-clps711x/entry-macro.S
index 21f6ee4..de4481d 100644
--- a/include/asm-arm/arch-clps711x/entry-macro.S
+++ b/include/asm-arm/arch-clps711x/entry-macro.S
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-CLPS711x/entry-macro.S
+ * include/asm-arm/arch-clps711x/entry-macro.S
  *
  * Low-level IRQ helper macros for CLPS711X-based platforms
  *
diff --git a/include/asm-arm/arch-ebsa285/entry-macro.S b/include/asm-arm/arch-ebsa285/entry-macro.S
index cf10ac9..ce812d4 100644
--- a/include/asm-arm/arch-ebsa285/entry-macro.S
+++ b/include/asm-arm/arch-ebsa285/entry-macro.S
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-footbridge/entry-macro.S
+ * include/asm-arm/arch-ebsa285/entry-macro.S
  *
  * Low-level IRQ helper macros for footbridge-based platforms
  *
diff --git a/include/asm-arm/arch-h720x/system.h b/include/asm-arm/arch-h720x/system.h
index 09eda84..8dc1460 100644
--- a/include/asm-arm/arch-h720x/system.h
+++ b/include/asm-arm/arch-h720x/system.h
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-h720x/system.h
+ * linux/include/asm-arm/arch-h720x/system.h
  *
  * Copyright (C) 2001-2002 Jungjun Kim, Hynix Semiconductor Inc.
  *
diff --git a/include/asm-arm/arch-ixp4xx/system.h b/include/asm-arm/arch-ixp4xx/system.h
index 73589aa..8e1db42 100644
--- a/include/asm-arm/arch-ixp4xx/system.h
+++ b/include/asm-arm/arch-ixp4xx/system.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-ixp4x//system.h 
+ * include/asm-arm/arch-ixp4xx/system.h
  *
  * Copyright (C) 2002 Intel Corporation.
  *
diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
index b5f3a71..fefb276 100644
--- a/include/asm-arm/arch-omap/dmtimer.h
+++ b/include/asm-arm/arch-omap/dmtimer.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arm/arch-omap/dmtimer.h
+ * linux/include/asm-arm/arch-omap/dmtimer.h
  *
  * OMAP Dual-Mode Timers
  *
diff --git a/include/asm-arm/arch-omap/mcbsp.h b/include/asm-arm/arch-omap/mcbsp.h
index ed0dde4..c7a0cc1 100644
--- a/include/asm-arm/arch-omap/mcbsp.h
+++ b/include/asm-arm/arch-omap/mcbsp.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-omap/gpio.h
+ * linux/include/asm-arm/arch-omap/mcbsp.h
  *
  * Defines for Multi-Channel Buffered Serial Port
  *
diff --git a/include/asm-arm/arch-omap/pm.h b/include/asm-arm/arch-omap/pm.h
index e46623c..1458805 100644
--- a/include/asm-arm/arch-omap/pm.h
+++ b/include/asm-arm/arch-omap/pm.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm/arch-omap/pm.h
+ * linux/include/asm-arm/arch-omap/pm.h
  *
  * Header file for OMAP Power Management Routines
  *
diff --git a/include/asm-arm/arch-pnx4008/clock.h b/include/asm-arm/arch-pnx4008/clock.h
index 91ae003..ce155e1 100644
--- a/include/asm-arm/arch-pnx4008/clock.h
+++ b/include/asm-arm/arch-pnx4008/clock.h
@@ -32,6 +32,7 @@
 #define KEYCLKCTRL_REG		(PWRMAN_VA_BASE + 0xb0)
 #define TSCLKCTRL_REG		(PWRMAN_VA_BASE + 0xb4)
 #define PWMCLKCTRL_REG		(PWRMAN_VA_BASE + 0xb8)
+#define TIMCLKCTRL_REG		(PWRMAN_VA_BASE + 0xbc)
 #define SPICTRL_REG		(PWRMAN_VA_BASE + 0xc4)
 #define FLASHCLKCTRL_REG	(PWRMAN_VA_BASE + 0xc8)
 #define UART3CLK_REG		(PWRMAN_VA_BASE + 0xd0)
diff --git a/include/asm-arm/arch-pnx4008/platform.h b/include/asm-arm/arch-pnx4008/platform.h
index 485a365..2613c7c 100644
--- a/include/asm-arm/arch-pnx4008/platform.h
+++ b/include/asm-arm/arch-pnx4008/platform.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-pnx4008/platfrom.h
+ * include/asm-arm/arch-pnx4008/platform.h
  *
  * PNX4008 Base addresses - header file
  *
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index aba9b30..81c3928 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -12,12 +12,14 @@
  *  published by the Free Software Foundation.
  */
 
+#include <linux/fb.h>
+
 /*
  * This structure describes the machine which we are running on.
  * It is set in linux/arch/arm/mach-pxa/machine_name.c and used in the probe routine
  * of linux/drivers/video/pxafb.c
  */
-struct pxafb_mach_info {
+struct pxafb_mode_info {
 	u_long		pixclock;
 
 	u_short		xres;
@@ -34,6 +36,14 @@
 	u_char		sync;
 
 	u_int		cmap_greyscale:1,
+			unused:31;
+};
+
+struct pxafb_mach_info {
+	struct pxafb_mode_info *modes;
+	unsigned int num_modes;
+
+	u_int		fixed_modes:1,
 			cmap_inverse:1,
 			cmap_static:1,
 			unused:29;
@@ -62,7 +72,7 @@
 	u_int		lccr3;
 
 	void (*pxafb_backlight_power)(int);
-	void (*pxafb_lcd_power)(int);
+	void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 
 };
 void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
diff --git a/include/asm-arm/arch-pxa/spitz.h b/include/asm-arm/arch-pxa/spitz.h
index 62e1fe4..4953dd32 100644
--- a/include/asm-arm/arch-pxa/spitz.h
+++ b/include/asm-arm/arch-pxa/spitz.h
@@ -15,6 +15,8 @@
 #define __ASM_ARCH_SPITZ_H  1
 #endif
 
+#include <linux/fb.h>
+
 /* Spitz/Akita GPIOs */
 
 #define SPITZ_GPIO_KEY_INT         (0) /* Key Interrupt */
@@ -155,4 +157,4 @@
 extern struct platform_device spitzssp_device;
 extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
 
-extern void spitz_lcd_power(int on);
+extern void spitz_lcd_power(int on, struct fb_var_screeninfo *var);
diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
index 7116179..9089421 100644
--- a/include/asm-arm/arch-s3c2410/fb.h
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/fb.h
+/* linux/include/asm-arm/arch-s3c2410/fb.h
  *
  * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
  *
diff --git a/include/asm-arm/arch-s3c2410/regs-adc.h b/include/asm-arm/arch-s3c2410/regs-adc.h
index c7b90b3..3196a28 100644
--- a/include/asm-arm/arch-s3c2410/regs-adc.h
+++ b/include/asm-arm/arch-s3c2410/regs-adc.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-adc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-adc.h
  *
  * Copyright (c) 2004 Shannon Holland <holland@loser.net>
  *
diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h
index b2f4690..e39656b 100644
--- a/include/asm-arm/arch-s3c2410/regs-clock.h
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-clock.h
+/* linux/include/asm-arm/arch-s3c2410/regs-clock.h
  *
  * Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@simtec.co.uk>
  *		      http://armlinux.simtec.co.uk/
diff --git a/include/asm-arm/arch-s3c2410/regs-dsc.h b/include/asm-arm/arch-s3c2410/regs-dsc.h
index a0a1248..c074851 100644
--- a/include/asm-arm/arch-s3c2410/regs-dsc.h
+++ b/include/asm-arm/arch-s3c2410/regs-dsc.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/hardware/s3c2410/regs-dsc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-dsc.h
  *
  * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index 93c4943..b2893e3 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/hardware/s3c2410/regs-gpio.h
+/* linux/include/asm-arm/arch-s3c2410/regs-gpio.h
  *
  * Copyright (c) 2003,2004 Simtec Electronics <linux@simtec.co.uk>
  *		           http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-gpioj.h b/include/asm-arm/arch-s3c2410/regs-gpioj.h
index 91cefa2..02131a5 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpioj.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpioj.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/hardware/s3c2410/regs-gpioj.h
+/* linux/include/asm-arm/arch-s3c2410/regs-gpioj.h
  *
  * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/arch-s3c2410/regs-iis.h
index 72cd250..eaf7791 100644
--- a/include/asm-arm/arch-s3c2410/regs-iis.h
+++ b/include/asm-arm/arch-s3c2410/regs-iis.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-iis.h
+/* linux/include/asm-arm/arch-s3c2410/regs-iis.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-irq.h b/include/asm-arm/arch-s3c2410/regs-irq.h
index 29fb8ef..498184c 100644
--- a/include/asm-arm/arch-s3c2410/regs-irq.h
+++ b/include/asm-arm/arch-s3c2410/regs-irq.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-irq.h
+/* linux/include/asm-arm/arch-s3c2410/regs-irq.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-lcd.h b/include/asm-arm/arch-s3c2410/regs-lcd.h
index 6d7881c..b7faeb0 100644
--- a/include/asm-arm/arch-s3c2410/regs-lcd.h
+++ b/include/asm-arm/arch-s3c2410/regs-lcd.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-lcd.h
+/* linux/include/asm-arm/arch-s3c2410/regs-lcd.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-rtc.h b/include/asm-arm/arch-s3c2410/regs-rtc.h
index cd88fd6..93b03c4 100644
--- a/include/asm-arm/arch-s3c2410/regs-rtc.h
+++ b/include/asm-arm/arch-s3c2410/regs-rtc.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-rtc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-rtc.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-sdi.h b/include/asm-arm/arch-s3c2410/regs-sdi.h
index 06e716e..bb9d30b 100644
--- a/include/asm-arm/arch-s3c2410/regs-sdi.h
+++ b/include/asm-arm/arch-s3c2410/regs-sdi.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-sdi.h
+/* linux/include/asm-arm/arch-s3c2410/regs-sdi.h
  *
  * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-timer.h b/include/asm-arm/arch-s3c2410/regs-timer.h
index 731918e..6f8fe43 100644
--- a/include/asm-arm/arch-s3c2410/regs-timer.h
+++ b/include/asm-arm/arch-s3c2410/regs-timer.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-timer.h
+/* linux/include/asm-arm/arch-s3c2410/regs-timer.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *		      http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/asm-arm/arch-s3c2410/regs-udc.h b/include/asm-arm/arch-s3c2410/regs-udc.h
index 3aa31a2..487861d 100644
--- a/include/asm-arm/arch-s3c2410/regs-udc.h
+++ b/include/asm-arm/arch-s3c2410/regs-udc.h
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-udc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-udc.h
  *
  * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
  *
diff --git a/include/asm-arm/arch-s3c2410/spi-gpio.h b/include/asm-arm/arch-s3c2410/spi-gpio.h
index 258c00b..c1e4db7 100644
--- a/include/asm-arm/arch-s3c2410/spi-gpio.h
+++ b/include/asm-arm/arch-s3c2410/spi-gpio.h
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/arch-s3c2410/spi.h
+/* linux/include/asm-arm/arch-s3c2410/spi-gpio.h
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/include/asm-arm/arch-sa1100/neponset.h b/include/asm-arm/arch-sa1100/neponset.h
index 8051fd7..09ec9e2 100644
--- a/include/asm-arm/arch-sa1100/neponset.h
+++ b/include/asm-arm/arch-sa1100/neponset.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-sa1100/assabet.h
+ * linux/include/asm-arm/arch-sa1100/neponset.h
  *
  * Created 2000/06/05 by Nicolas Pitre <nico@cam.org>
  *
diff --git a/include/asm-arm/arch-sa1100/uncompress.h b/include/asm-arm/arch-sa1100/uncompress.h
index 2601a77..17e64d2 100644
--- a/include/asm-arm/arch-sa1100/uncompress.h
+++ b/include/asm-arm/arch-sa1100/uncompress.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-brutus/uncompress.h
+ * linux/include/asm-arm/arch-sa1100/uncompress.h
  *
  * (C) 1999 Nicolas Pitre <nico@cam.org>
  *
diff --git a/include/asm-arm/arch-shark/vmalloc.h b/include/asm-arm/arch-shark/vmalloc.h
index 10db5d1..fac37c6 100644
--- a/include/asm-arm/arch-shark/vmalloc.h
+++ b/include/asm-arm/arch-shark/vmalloc.h
@@ -1,4 +1,4 @@
 /*
- * linux/include/asm-arm/arch-rpc/vmalloc.h
+ * linux/include/asm-arm/arch-shark/vmalloc.h
  */
 #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff --git a/include/asm-arm/hardware/debug-8250.S b/include/asm-arm/hardware/debug-8250.S
index 4594fea..07c97fb 100644
--- a/include/asm-arm/hardware/debug-8250.S
+++ b/include/asm-arm/hardware/debug-8250.S
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/hardware/debug-8250.h
+ * linux/include/asm-arm/hardware/debug-8250.S
  *
  *  Copyright (C) 1994-1999 Russell King
  *
diff --git a/include/asm-arm/hardware/debug-pl01x.S b/include/asm-arm/hardware/debug-pl01x.S
index db0d0f7..23c541a 100644
--- a/include/asm-arm/hardware/debug-pl01x.S
+++ b/include/asm-arm/hardware/debug-pl01x.S
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/arch-integrator/debug-macro.S
+/* linux/include/asm-arm/hardware/debug-pl01x.S
  *
  * Debugging macro include header
  *
diff --git a/include/asm-arm/hardware/entry-macro-iomd.S b/include/asm-arm/hardware/entry-macro-iomd.S
index 30c7b92..fbed08f 100644
--- a/include/asm-arm/hardware/entry-macro-iomd.S
+++ b/include/asm-arm/hardware/entry-macro-iomd.S
@@ -1,5 +1,5 @@
 /*
- * arch/arm/commond/entry-macro-iomd.S
+ * include/asm-arm/hardware/entry-macro-iomd.S
  *
  * Low-level IRQ helper macros for IOC/IOMD based platforms
  *
diff --git a/include/asm-arm/hardware/sa1111.h b/include/asm-arm/hardware/sa1111.h
index 319aea0..6aa0a5b 100644
--- a/include/asm-arm/hardware/sa1111.h
+++ b/include/asm-arm/hardware/sa1111.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/hardware/SA-1111.h
+ * linux/include/asm-arm/hardware/sa1111.h
  *
  * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
  *
diff --git a/include/asm-arm/timeofday.h b/include/asm-arm/timeofday.h
deleted file mode 100644
index 27254bd..0000000
--- a/include/asm-arm/timeofday.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _ASM_ARM_TIMEOFDAY_H
-#define _ASM_ARM_TIMEOFDAY_H
-#include <asm-generic/timeofday.h>
-#endif
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 2ab4078..14a87ee 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -549,30 +549,6 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-extern long execve(const char *file, char **argv, char **envp);
-
-struct pt_regs;
-asmlinkage int sys_execve(char *filenamei, char **argv, char **envp,
-			struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-			struct pt_regs *regs);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-arm26/assembler.h b/include/asm-arm26/assembler.h
index 83f9aec..bb507a9 100644
--- a/include/asm-arm26/assembler.h
+++ b/include/asm-arm26/assembler.h
@@ -1,5 +1,5 @@
 /*
- * linux/asm/assembler.h
+ * linux/include/asm-arm26/assembler.h
  *
  * This file contains arm architecture specific defines
  * for the different processors.
diff --git a/include/asm-arm26/namei.h b/include/asm-arm26/namei.h
index a402d3b..3f5d340 100644
--- a/include/asm-arm26/namei.h
+++ b/include/asm-arm26/namei.h
@@ -1,5 +1,5 @@
 /* 
- * linux/include/asm-arm/namei.h
+ * linux/include/asm-arm26/namei.h
  *
  * Routines to handle famous /usr/gnemul
  * Derived from the Sparc version of this file
diff --git a/include/asm-arm26/semaphore.h b/include/asm-arm26/semaphore.h
index ccf15e7..1fda543 100644
--- a/include/asm-arm26/semaphore.h
+++ b/include/asm-arm26/semaphore.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/semaphore.h
+ * linux/include/asm-arm26/semaphore.h
  */
 #ifndef __ASM_ARM_SEMAPHORE_H
 #define __ASM_ARM_SEMAPHORE_H
diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
index c6d2436..25a5eea 100644
--- a/include/asm-arm26/unistd.h
+++ b/include/asm-arm26/unistd.h
@@ -464,30 +464,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-extern long execve(const char *file, char **argv, char **envp);
-
-struct pt_regs;
-asmlinkage int sys_execve(char *filenamei, char **argv, char **envp,
-			struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-			struct pt_regs *regs);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-avr32/unistd.h b/include/asm-avr32/unistd.h
index 1f528f9..a50e500 100644
--- a/include/asm-avr32/unistd.h
+++ b/include/asm-avr32/unistd.h
@@ -281,30 +281,10 @@
 #define __NR_tee		263
 #define __NR_vmsplice		264
 
+#ifdef __KERNEL__
 #define NR_syscalls		265
 
 
-/*
- * AVR32 calling convention for system calls:
- *   - System call number in r8
- *   - Parameters in r12 and downwards to r9 as well as r6 and r5.
- *   - Return value in r12
- */
-
-/*
- * user-visible error numbers are in the range -1 - -124: see
- * <asm-generic/errno.h>
- */
-
-#define __syscall_return(type, res) do {				\
-		if ((unsigned long)(res) >= (unsigned long)(-125)) {	\
-			errno = -(res);					\
-			res = -1;					\
-		}							\
-		return (type) (res);					\
-	} while (0)
-
-#ifdef __KERNEL__
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
@@ -319,62 +299,6 @@
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#endif
-
-#if defined(__KERNEL_SYSCALLS__) || defined(__CHECKER__)
-
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/signal.h>
-
-struct pt_regs;
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline int execve(const char *file, char **argv, char **envp)
-{
-	register long scno asm("r8") = __NR_execve;
-	register long sc1 asm("r12") = (long)file;
-	register long sc2 asm("r11") = (long)argv;
-	register long sc3 asm("r10") = (long)envp;
-	int res;
-
-	asm volatile("scall"
-		     : "=r"(sc1)
-		     : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
-		     : "lr", "memory");
-	res = sc1;
-	__syscall_return(int, res);
-}
-
-asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
-asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
-			       struct pt_regs *regs);
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long __user *filedes);
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, off_t offset);
-asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-			 unsigned long parent_tidptr,
-			 unsigned long child_tidptr, struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
-			  char __user *__user *uenvp, struct pt_regs *regs);
-
-#endif
 
 /*
  * "Conditional" syscalls
@@ -384,4 +308,6 @@
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
 
+#endif /* __KERNEL__ */
+
 #endif /* __ASM_AVR32_UNISTD_H */
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
index 7372efa..7c90fa9 100644
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -322,67 +322,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-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(
-			unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
-			long r13, long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
-			int* parent_tid, int* child_tid, long mof, long srp,
-			struct pt_regs *regs);
-asmlinkage int sys_fork(long r10, long r11, long r12, long r13,
-			long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
-			long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-/*
- * Since we define it "external", it collides with the built-in
- * definition, which has the "noreturn" attribute and will cause
- * complaints.  We don't want to use -fno-builtin, so just use a
- * different name when in the kernel.
- */
-#define _exit kernel_syscall_exit
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-#endif /* __KERNEL_SYSCALLS__ */
-
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-frv/namei.h b/include/asm-frv/namei.h
index 84ddd64..4ea5717 100644
--- a/include/asm-frv/namei.h
+++ b/include/asm-frv/namei.h
@@ -1,5 +1,5 @@
 /*
- * asm/namei.h
+ * include/asm-frv/namei.h
  *
  * Included from linux/fs/namei.c
  */
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index d104d1b..725e854 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -440,31 +440,6 @@
 	__syscall_return(type, __sc0);								 \
 }
 
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 #define __ARCH_WANT_IPC_PARSE_VERSION
 /* #define __ARCH_WANT_OLD_READDIR */
 #define __ARCH_WANT_OLD_STAT
diff --git a/include/asm-generic/mutex-dec.h b/include/asm-generic/mutex-dec.h
index 29c6ac3..0134151 100644
--- a/include/asm-generic/mutex-dec.h
+++ b/include/asm-generic/mutex-dec.h
@@ -1,5 +1,5 @@
 /*
- * asm-generic/mutex-dec.h
+ * include/asm-generic/mutex-dec.h
  *
  * Generic implementation of the mutex fastpath, based on atomic
  * decrement/increment.
diff --git a/include/asm-generic/mutex-null.h b/include/asm-generic/mutex-null.h
index 254a126..e1bbbc7 100644
--- a/include/asm-generic/mutex-null.h
+++ b/include/asm-generic/mutex-null.h
@@ -1,5 +1,5 @@
 /*
- * asm-generic/mutex-null.h
+ * include/asm-generic/mutex-null.h
  *
  * Generic implementation of the mutex fastpath, based on NOP :-)
  *
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h
index 32a2100..6a7e8c1 100644
--- a/include/asm-generic/mutex-xchg.h
+++ b/include/asm-generic/mutex-xchg.h
@@ -1,5 +1,5 @@
 /*
- * asm-generic/mutex-xchg.h
+ * include/asm-generic/mutex-xchg.h
  *
  * Generic implementation of the mutex fastpath, based on xchg().
  *
diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
index 4087037..d3238f1f 100644
--- a/include/asm-generic/rtc.h
+++ b/include/asm-generic/rtc.h
@@ -1,5 +1,5 @@
 /* 
- * inclue/asm-generic/rtc.h
+ * include/asm-generic/rtc.h
  *
  * Author: Tom Rini <trini@mvista.com>
  *
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 867d900..f490e43 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -1,4 +1,4 @@
-/* asm-generic/tlb.h
+/* include/asm-generic/tlb.h
  *
  *	Generic TLB shootdown code
  *
diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
index a2dd904..747788d 100644
--- a/include/asm-h8300/unistd.h
+++ b/include/asm-h8300/unistd.h
@@ -485,57 +485,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall0(int,sync)
-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)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
-	return waitpid(-1,wait_stat,0);
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *name, char **argv, char **envp,
-			int dummy, ...);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  */
diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h
index 2a9e4ee..592ffee 100644
--- a/include/asm-i386/bugs.h
+++ b/include/asm-i386/bugs.h
@@ -189,6 +189,6 @@
 	check_fpu();
 	check_hlt();
 	check_popad();
-	system_utsname.machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
+	init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
 	alternative_instructions(); 
 }
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index db4344d..3a05436 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -112,7 +112,7 @@
    For the moment, we have only optimizations for the Intel generations,
    but that could change... */
 
-#define ELF_PLATFORM  (system_utsname.machine)
+#define ELF_PLATFORM  (utsname()->machine)
 
 #define SET_PERSONALITY(ex, ibcs2) do { } while (0)
 
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index 87e5a35..88f02a0 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -17,8 +17,6 @@
 #include <asm/irq.h>
 #include <asm/sections.h>
 
-struct hw_interrupt_type;
-
 #define NMI_VECTOR		0x02
 
 /*
@@ -30,7 +28,6 @@
 
 extern u8 irq_vector[NR_IRQ_VECTORS];
 #define IO_APIC_VECTOR(irq)	(irq_vector[irq])
-#define AUTO_ASSIGN		-1
 
 extern void (*interrupt[NR_IRQS])(void);
 
diff --git a/include/asm-i386/hypertransport.h b/include/asm-i386/hypertransport.h
new file mode 100644
index 0000000..c16c6ff
--- /dev/null
+++ b/include/asm-i386/hypertransport.h
@@ -0,0 +1,42 @@
+#ifndef ASM_HYPERTRANSPORT_H
+#define ASM_HYPERTRANSPORT_H
+
+/*
+ * Constants for x86 Hypertransport Interrupts.
+ */
+
+#define HT_IRQ_LOW_BASE			0xf8000000
+
+#define HT_IRQ_LOW_VECTOR_SHIFT		16
+#define  HT_IRQ_LOW_VECTOR_MASK		0x00ff0000
+#define  HT_IRQ_LOW_VECTOR(v)		(((v) << HT_IRQ_LOW_VECTOR_SHIFT) & HT_IRQ_LOW_VECTOR_MASK)
+
+#define HT_IRQ_LOW_DEST_ID_SHIFT	8
+#define  HT_IRQ_LOW_DEST_ID_MASK	0x0000ff00
+#define  HT_IRQ_LOW_DEST_ID(v)		(((v) << HT_IRQ_LOW_DEST_ID_SHIFT) & HT_IRQ_LOW_DEST_ID_MASK)
+
+#define HT_IRQ_LOW_DM_PHYSICAL		0x0000000
+#define HT_IRQ_LOW_DM_LOGICAL		0x0000040
+
+#define HT_IRQ_LOW_RQEOI_EDGE		0x0000000
+#define HT_IRQ_LOW_RQEOI_LEVEL		0x0000020
+
+
+#define HT_IRQ_LOW_MT_FIXED		0x0000000
+#define HT_IRQ_LOW_MT_ARBITRATED	0x0000004
+#define HT_IRQ_LOW_MT_SMI		0x0000008
+#define HT_IRQ_LOW_MT_NMI		0x000000c
+#define HT_IRQ_LOW_MT_INIT		0x0000010
+#define HT_IRQ_LOW_MT_STARTUP		0x0000014
+#define HT_IRQ_LOW_MT_EXTINT		0x0000018
+#define HT_IRQ_LOW_MT_LINT1		0x000008c
+#define HT_IRQ_LOW_MT_LINT0		0x0000098
+
+#define HT_IRQ_LOW_IRQ_MASKED		0x0000001
+
+
+#define HT_IRQ_HIGH_DEST_ID_SHIFT	0
+#define  HT_IRQ_HIGH_DEST_ID_MASK	0x00ffffff
+#define  HT_IRQ_HIGH_DEST_ID(v)		((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
+
+#endif /* ASM_HYPERTRANSPORT_H */
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index 5d30927..276ea7e 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -12,46 +12,6 @@
 
 #ifdef CONFIG_X86_IO_APIC
 
-#ifdef CONFIG_PCI_MSI
-static inline int use_pci_vector(void)	{return 1;}
-static inline void disable_edge_ioapic_vector(unsigned int vector) { }
-static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
-static inline void end_edge_ioapic_vector (unsigned int vector) { }
-#define startup_level_ioapic	startup_level_ioapic_vector
-#define shutdown_level_ioapic	mask_IO_APIC_vector
-#define enable_level_ioapic	unmask_IO_APIC_vector
-#define disable_level_ioapic	mask_IO_APIC_vector
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
-#define end_level_ioapic	end_level_ioapic_vector
-#define set_ioapic_affinity	set_ioapic_affinity_vector
-
-#define startup_edge_ioapic 	startup_edge_ioapic_vector
-#define shutdown_edge_ioapic 	disable_edge_ioapic_vector
-#define enable_edge_ioapic 	unmask_IO_APIC_vector
-#define disable_edge_ioapic 	disable_edge_ioapic_vector
-#define ack_edge_ioapic 	ack_edge_ioapic_vector
-#define end_edge_ioapic 	end_edge_ioapic_vector
-#else
-static inline int use_pci_vector(void)	{return 0;}
-static inline void disable_edge_ioapic_irq(unsigned int irq) { }
-static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
-static inline void end_edge_ioapic_irq (unsigned int irq) { }
-#define startup_level_ioapic	startup_level_ioapic_irq
-#define shutdown_level_ioapic	mask_IO_APIC_irq
-#define enable_level_ioapic	unmask_IO_APIC_irq
-#define disable_level_ioapic	mask_IO_APIC_irq
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
-#define end_level_ioapic	end_level_ioapic_irq
-#define set_ioapic_affinity	set_ioapic_affinity_irq
-
-#define startup_edge_ioapic 	startup_edge_ioapic_irq
-#define shutdown_edge_ioapic 	disable_edge_ioapic_irq
-#define enable_edge_ioapic 	unmask_IO_APIC_irq
-#define disable_edge_ioapic 	disable_edge_ioapic_irq
-#define ack_edge_ioapic 	ack_edge_ioapic_irq
-#define end_edge_ioapic 	end_edge_ioapic_irq
-#endif
-
 #define IO_APIC_BASE(idx) \
 		((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
 		+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
@@ -219,6 +179,4 @@
 static inline void disable_ioapic_setup(void) { }
 #endif
 
-extern int assign_irq_vector(int irq);
-
 #endif
diff --git a/include/asm-i386/mach-default/irq_vectors_limits.h b/include/asm-i386/mach-default/irq_vectors_limits.h
index b330026..7f161e7 100644
--- a/include/asm-i386/mach-default/irq_vectors_limits.h
+++ b/include/asm-i386/mach-default/irq_vectors_limits.h
@@ -1,10 +1,6 @@
 #ifndef _ASM_IRQ_VECTORS_LIMITS_H
 #define _ASM_IRQ_VECTORS_LIMITS_H
 
-#ifdef CONFIG_PCI_MSI
-#define NR_IRQS FIRST_SYSTEM_VECTOR
-#define NR_IRQ_VECTORS NR_IRQS
-#else
 #ifdef CONFIG_X86_IO_APIC
 #define NR_IRQS 224
 # if (224 >= 32 * NR_CPUS)
@@ -16,6 +12,5 @@
 #define NR_IRQS 16
 #define NR_IRQ_VECTORS NR_IRQS
 #endif
-#endif
 
 #endif /* _ASM_IRQ_VECTORS_LIMITS_H */
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
index 254a0fe..ef0671e 100644
--- a/include/asm-i386/mach-summit/mach_apic.h
+++ b/include/asm-i386/mach-summit/mach_apic.h
@@ -88,7 +88,7 @@
 
 static inline int apicid_to_node(int logical_apicid)
 {
-	return apicid_2_node[logical_apicid];
+	return apicid_2_node[hard_smp_processor_id()];
 }
 
 /* Mapping from cpu number to logical apicid */
diff --git a/include/asm-i386/mca_dma.h b/include/asm-i386/mca_dma.h
index 4b3b526..fbb1f3b 100644
--- a/include/asm-i386/mca_dma.h
+++ b/include/asm-i386/mca_dma.h
@@ -181,7 +181,7 @@
  *	@mode: mode to set
  *
  *	The DMA controller supports several modes. The mode values you can
- *	set are :
+ *	set are-
  *
  *	%MCA_DMA_MODE_READ when reading from the DMA device.
  *
@@ -190,7 +190,6 @@
  *	%MCA_DMA_MODE_IO to do DMA to or from an I/O port.
  *
  *	%MCA_DMA_MODE_16 to do 16bit transfers.
- *
  */
 
 static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode)
diff --git a/include/asm-i386/msi.h b/include/asm-i386/msi.h
deleted file mode 100644
index b11c4b7..0000000
--- a/include/asm-i386/msi.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
- */
-
-#ifndef ASM_MSI_H
-#define ASM_MSI_H
-
-#include <asm/desc.h>
-#include <mach_apic.h>
-
-#define LAST_DEVICE_VECTOR	(FIRST_SYSTEM_VECTOR - 1)
-#define MSI_TARGET_CPU_SHIFT	12
-
-extern struct msi_ops msi_apic_ops;
-
-static inline int msi_arch_init(void)
-{
-	msi_register(&msi_apic_ops);
-	return 0;
-}
-
-#endif /* ASM_MSI_H */
diff --git a/include/asm-i386/msidef.h b/include/asm-i386/msidef.h
new file mode 100644
index 0000000..5b8acdd
--- /dev/null
+++ b/include/asm-i386/msidef.h
@@ -0,0 +1,47 @@
+#ifndef ASM_MSIDEF_H
+#define ASM_MSIDEF_H
+
+/*
+ * Constants for Intel APIC based MSI messages.
+ */
+
+/*
+ * Shifts for MSI data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT		0
+#define  MSI_DATA_VECTOR_MASK		0x000000ff
+#define	 MSI_DATA_VECTOR(v)		(((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK)
+
+#define MSI_DATA_DELIVERY_MODE_SHIFT	8
+#define  MSI_DATA_DELIVERY_FIXED	(0 << MSI_DATA_DELIVERY_MODE_SHIFT)
+#define  MSI_DATA_DELIVERY_LOWPRI	(1 << MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT		14
+#define	 MSI_DATA_LEVEL_DEASSERT	(0 << MSI_DATA_LEVEL_SHIFT)
+#define	 MSI_DATA_LEVEL_ASSERT		(1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT		15
+#define  MSI_DATA_TRIGGER_EDGE		(0 << MSI_DATA_TRIGGER_SHIFT)
+#define  MSI_DATA_TRIGGER_LEVEL		(1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for msi address
+ */
+
+#define MSI_ADDR_BASE_HI		0
+#define MSI_ADDR_BASE_LO		0xfee00000
+
+#define MSI_ADDR_DEST_MODE_SHIFT	2
+#define  MSI_ADDR_DEST_MODE_PHYSICAL	(0 << MSI_ADDR_DEST_MODE_SHIFT)
+#define	 MSI_ADDR_DEST_MODE_LOGICAL	(1 << MSI_ADDR_DEST_MODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT	3
+#define  MSI_ADDR_REDIRECTION_CPU	(0 << MSI_ADDR_REDIRECTION_SHIFT) /* dedicated cpu */
+#define  MSI_ADDR_REDIRECTION_LOWPRI	(1 << MSI_ADDR_REDIRECTION_SHIFT) /* lowest priority */
+
+#define MSI_ADDR_DEST_ID_SHIFT		12
+#define	 MSI_ADDR_DEST_ID_MASK		0x00ffff0
+#define  MSI_ADDR_DEST_ID(dest)		(((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK)
+
+#endif /* ASM_MSIDEF_H */
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
index a4a0e52..d505f50 100644
--- a/include/asm-i386/ptrace.h
+++ b/include/asm-i386/ptrace.h
@@ -47,7 +47,10 @@
 {
 	return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
 }
+
 #define instruction_pointer(regs) ((regs)->eip)
+#define regs_return_value(regs) ((regs)->eax)
+
 extern unsigned long profile_pc(struct pt_regs *regs);
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h
index 6adbd9b..978d095 100644
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -74,6 +74,7 @@
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index bd99870..3ca7ab9 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -451,45 +451,6 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount);
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(struct pt_regs regs);
-asmlinkage int sys_clone(struct pt_regs regs);
-asmlinkage int sys_fork(struct pt_regs regs);
-asmlinkage int sys_vfork(struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage long sys_iopl(unsigned long unused);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
index 15b545a..90cba96 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -20,6 +20,7 @@
 struct mm_struct;
 struct pci_bus;
 struct task_struct;
+struct pci_dev;
 
 typedef void ia64_mv_setup_t (char **);
 typedef void ia64_mv_cpu_init_t (void);
@@ -75,7 +76,9 @@
 typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *);
 typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *);
 typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *);
-typedef int ia64_mv_msi_init_t (void);
+
+typedef int ia64_mv_setup_msi_irq_t (unsigned int irq, struct pci_dev *pdev);
+typedef void ia64_mv_teardown_msi_irq_t (unsigned int irq);
 
 static inline void
 machvec_noop (void)
@@ -154,7 +157,8 @@
 #  define platform_readl_relaxed        ia64_mv.readl_relaxed
 #  define platform_readq_relaxed        ia64_mv.readq_relaxed
 #  define platform_migrate		ia64_mv.migrate
-#  define platform_msi_init		ia64_mv.msi_init
+#  define platform_setup_msi_irq	ia64_mv.setup_msi_irq
+#  define platform_teardown_msi_irq	ia64_mv.teardown_msi_irq
 # endif
 
 /* __attribute__((__aligned__(16))) is required to make size of the
@@ -204,7 +208,8 @@
 	ia64_mv_readl_relaxed_t *readl_relaxed;
 	ia64_mv_readq_relaxed_t *readq_relaxed;
 	ia64_mv_migrate_t *migrate;
-	ia64_mv_msi_init_t *msi_init;
+	ia64_mv_setup_msi_irq_t *setup_msi_irq;
+	ia64_mv_teardown_msi_irq_t *teardown_msi_irq;
 } __attribute__((__aligned__(16))); /* align attrib? see above comment */
 
 #define MACHVEC_INIT(name)			\
@@ -250,7 +255,8 @@
 	platform_readl_relaxed,			\
 	platform_readq_relaxed,			\
 	platform_migrate,			\
-	platform_msi_init,			\
+	platform_setup_msi_irq,			\
+	platform_teardown_msi_irq,		\
 }
 
 extern struct ia64_machine_vector ia64_mv;
@@ -404,8 +410,11 @@
 #ifndef platform_migrate
 # define platform_migrate machvec_noop_task
 #endif
-#ifndef platform_msi_init
-# define platform_msi_init	((ia64_mv_msi_init_t*)NULL)
+#ifndef platform_setup_msi_irq
+# define platform_setup_msi_irq		((ia64_mv_setup_msi_irq_t*)NULL)
+#endif
+#ifndef platform_teardown_msi_irq
+# define platform_teardown_msi_irq	((ia64_mv_teardown_msi_irq_t*)NULL)
 #endif
 
 #endif /* _ASM_IA64_MACHVEC_H */
diff --git a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
index cf724dc..c54b165 100644
--- a/include/asm-ia64/machvec_sn2.h
+++ b/include/asm-ia64/machvec_sn2.h
@@ -67,7 +67,8 @@
 extern ia64_mv_dma_mapping_error	sn_dma_mapping_error;
 extern ia64_mv_dma_supported		sn_dma_supported;
 extern ia64_mv_migrate_t		sn_migrate;
-extern ia64_mv_msi_init_t		sn_msi_init;
+extern ia64_mv_setup_msi_irq_t		sn_setup_msi_irq;
+extern ia64_mv_teardown_msi_irq_t	sn_teardown_msi_irq;
 
 
 /*
@@ -120,9 +121,11 @@
 #define platform_dma_supported		sn_dma_supported
 #define platform_migrate		sn_migrate
 #ifdef CONFIG_PCI_MSI
-#define platform_msi_init		sn_msi_init
+#define platform_setup_msi_irq		sn_setup_msi_irq
+#define platform_teardown_msi_irq	sn_teardown_msi_irq
 #else
-#define platform_msi_init		((ia64_mv_msi_init_t*)NULL)
+#define platform_setup_msi_irq		((ia64_mv_setup_msi_irq_t*)NULL)
+#define platform_teardown_msi_irq	((ia64_mv_teardown_msi_irq_t*)NULL)
 #endif
 
 #include <asm/sn/io.h>
diff --git a/include/asm-ia64/msi.h b/include/asm-ia64/msi.h
deleted file mode 100644
index bb92b0d..0000000
--- a/include/asm-ia64/msi.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
- */
-
-#ifndef ASM_MSI_H
-#define ASM_MSI_H
-
-#define NR_VECTORS		NR_IRQS
-#define FIRST_DEVICE_VECTOR 	IA64_FIRST_DEVICE_VECTOR
-#define LAST_DEVICE_VECTOR	IA64_LAST_DEVICE_VECTOR
-static inline void set_intr_gate (int nr, void *func) {}
-#define IO_APIC_VECTOR(irq)	(irq)
-#define ack_APIC_irq		ia64_eoi
-#define MSI_TARGET_CPU_SHIFT	4
-
-extern struct msi_ops msi_apic_ops;
-
-static inline int msi_arch_init(void)
-{
-	if (platform_msi_init)
-		return platform_msi_init();
-
-	/* default ops for most ia64 platforms */
-	msi_register(&msi_apic_ops);
-	return 0;
-}
-
-#endif /* ASM_MSI_H */
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index 1414316..f4ef87a 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -241,6 +241,9 @@
  * the canonical representation by adding to instruction pointer.
  */
 # define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
+
+#define regs_return_value(regs) ((regs)->r8)
+
 /* Conserve space in histogram by encoding slot bits in address
  * bits 2 and 3 rather than bits 0 and 1.
  */
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index 937c212..a6e3856 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -59,6 +59,7 @@
 #define SD_CPU_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 1,			\
 	.max_interval		= 4,			\
@@ -84,6 +85,7 @@
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 8*(min(num_online_cpus(), 32)), \
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index bb0eb72..53c5c0e 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -319,78 +319,6 @@
 
 extern long __ia64_syscall (long a0, long a1, long a2, long a3, long a4, long nr);
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <asm/ptrace.h>
-#include <linux/stringify.h>
-#include <linux/syscalls.h>
-
-static inline long
-open (const char * name, int mode, int flags)
-{
-	return sys_open(name, mode, flags);
-}
-
-static inline long
-dup (int fd)
-{
-	return sys_dup(fd);
-}
-
-static inline long
-close (int fd)
-{
-	return sys_close(fd);
-}
-
-static inline off_t
-lseek (int fd, off_t off, int whence)
-{
-	return sys_lseek(fd, off, whence);
-}
-
-static inline void
-_exit (int value)
-{
-	sys_exit(value);
-}
-
-#define exit(x) _exit(x)
-
-static inline long
-write (int fd, const char * buf, size_t nr)
-{
-	return sys_write(fd, buf, nr);
-}
-
-static inline long
-read (int fd, char * buf, size_t nr)
-{
-	return sys_read(fd, buf, nr);
-}
-
-
-static inline long
-setsid (void)
-{
-	return sys_setsid();
-}
-
-static inline pid_t
-waitpid (int pid, int * wait_stat, int flags)
-{
-	return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-
-extern int execve (const char *filename, char *const av[], char *const ep[]);
-extern pid_t clone (unsigned long flags, void *sp);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 asmlinkage unsigned long sys_mmap(
 				unsigned long addr, unsigned long len,
 				int prot, int flags,
diff --git a/include/asm-m32r/m32104ut/m32104ut_pld.h b/include/asm-m32r/m32104ut/m32104ut_pld.h
index 6ba4ddf..cbdbc58 100644
--- a/include/asm-m32r/m32104ut/m32104ut_pld.h
+++ b/include/asm-m32r/m32104ut/m32104ut_pld.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32104ut/m32104ut_pld.h
+ * include/asm-m32r/m32104ut/m32104ut_pld.h
  *
  * Definitions for Programable Logic Device(PLD) on M32104UT board.
  * Based on m32700ut_pld.h
diff --git a/include/asm-m32r/m32700ut/m32700ut_lan.h b/include/asm-m32r/m32700ut/m32700ut_lan.h
index c050b19..f1e47ae 100644
--- a/include/asm-m32r/m32700ut/m32700ut_lan.h
+++ b/include/asm-m32r/m32700ut/m32700ut_lan.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32700ut_lan.h
+ * include/asm-m32r/m32700ut/m32700ut_lan.h
  *
  * M32700UT-LAN board
  *
diff --git a/include/asm-m32r/m32700ut/m32700ut_lcd.h b/include/asm-m32r/m32700ut/m32700ut_lcd.h
index 4da4e82..e41c4aa 100644
--- a/include/asm-m32r/m32700ut/m32700ut_lcd.h
+++ b/include/asm-m32r/m32700ut/m32700ut_lcd.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32700ut_lcd.h
+ * include/asm-m32r/m32700ut/m32700ut_lcd.h
  *
  * M32700UT-LCD board
  *
diff --git a/include/asm-m32r/m32700ut/m32700ut_pld.h b/include/asm-m32r/m32700ut/m32700ut_pld.h
index f35f915..a48c22c 100644
--- a/include/asm-m32r/m32700ut/m32700ut_pld.h
+++ b/include/asm-m32r/m32700ut/m32700ut_pld.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32700ut/m32700ut_pld.h
+ * include/asm-m32r/m32700ut/m32700ut_pld.h
  *
  * Definitions for Programable Logic Device(PLD) on M32700UT board.
  *
diff --git a/include/asm-m32r/mappi2/mappi2_pld.h b/include/asm-m32r/mappi2/mappi2_pld.h
index 01dcdd1..56a2b12 100644
--- a/include/asm-m32r/mappi2/mappi2_pld.h
+++ b/include/asm-m32r/mappi2/mappi2_pld.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/mappi2/mappi2_pld.h
+ * include/asm-m32r/mappi2/mappi2_pld.h
  *
  * Definitions for Extended IO Logic on MAPPI2 board.
  *  based on m32700ut_pld.h by
diff --git a/include/asm-m32r/mappi3/mappi3_pld.h b/include/asm-m32r/mappi3/mappi3_pld.h
index 031369a..92f10de 100644
--- a/include/asm-m32r/mappi3/mappi3_pld.h
+++ b/include/asm-m32r/mappi3/mappi3_pld.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/mappi3/mappi3_pld.h
+ * include/asm-m32r/mappi3/mappi3_pld.h
  *
  * Definitions for Extended IO Logic on MAPPI3 board.
  *  based on m32700ut_pld.h
diff --git a/include/asm-m32r/opsput/opsput_lan.h b/include/asm-m32r/opsput/opsput_lan.h
index 6194829..f53e101 100644
--- a/include/asm-m32r/opsput/opsput_lan.h
+++ b/include/asm-m32r/opsput/opsput_lan.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/opsput_lan.h
+ * include/asm-m32r/opsput/opsput_lan.h
  *
  * OPSPUT-LAN board
  *
diff --git a/include/asm-m32r/opsput/opsput_lcd.h b/include/asm-m32r/opsput/opsput_lcd.h
index 44cfd7f..99f296e 100644
--- a/include/asm-m32r/opsput/opsput_lcd.h
+++ b/include/asm-m32r/opsput/opsput_lcd.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/opsput_lcd.h
+ * include/asm-m32r/opsput/opsput_lcd.h
  *
  * OPSPUT-LCD board
  *
diff --git a/include/asm-m32r/opsput/opsput_pld.h b/include/asm-m32r/opsput/opsput_pld.h
index 46296fe..a8d6452 100644
--- a/include/asm-m32r/opsput/opsput_pld.h
+++ b/include/asm-m32r/opsput/opsput_pld.h
@@ -1,5 +1,5 @@
 /*
- * include/asm/opsput/opsput_pld.h
+ * include/asm-m32r/opsput/opsput_pld.h
  *
  * Definitions for Programable Logic Device(PLD) on OPSPUT board.
  *
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index 5c6a9ac..95aa342 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -424,43 +424,6 @@
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static __inline__ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(struct pt_regs regs);
-asmlinkage int sys_clone(struct pt_regs regs);
-asmlinkage int sys_fork(struct pt_regs regs);
-asmlinkage int sys_vfork(struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				 const struct sigaction __user *act,
-				 struct sigaction __user *oact,
-				 size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-m68k/rtc.h b/include/asm-m68k/rtc.h
index 71406fc..5d3e038 100644
--- a/include/asm-m68k/rtc.h
+++ b/include/asm-m68k/rtc.h
@@ -1,4 +1,4 @@
-/* asm-m68k/rtc.h
+/* include/asm-m68k/rtc.h
  *
  * Copyright Richard Zidlicky
  * implementation details for genrtc/q40rtc driver
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index 751632b..3ab716f 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -409,12 +409,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h
index 9d3a1bf..91cba18 100644
--- a/include/asm-m68knommu/processor.h
+++ b/include/asm-m68knommu/processor.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-m68k/processor.h
+ * include/asm-m68knommu/processor.h
  *
  * Copyright (C) 1995 Hamish Macdonald
  */
diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
index 21fdc37..daafb5d 100644
--- a/include/asm-m68knommu/unistd.h
+++ b/include/asm-m68knommu/unistd.h
@@ -463,61 +463,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall0(int,sync)
-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)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
-	return waitpid(-1,wait_stat,0);
-}
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *name, char **argv, char **envp);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct pt_regs;
-int sys_request_irq(unsigned int,
-			irqreturn_t (*)(int, void *, struct pt_regs *),
-			unsigned long, const char *, void *);
-void sys_free_irq(unsigned int, void *);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index 78c35ec..1e5ccda 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -125,12 +125,6 @@
 #define  MACH_MOMENCO_OCELOT_3	4
 
 /*
- * Valid machtype for group ITE
- */
-#define MACH_GROUP_ITE		13	/* ITE Semi Eval Boards		*/
-#define  MACH_QED_4N_S01B	0	/* ITE8172 based eval board */
-
-/*
  * Valid machtype for group PHILIPS
  */
 #define MACH_GROUP_PHILIPS     14
@@ -139,12 +133,6 @@
 #define  MACH_PHILIPS_JBS	2	/* JBS */
 
 /*
- * Valid machtype for group Globespan
- */
-#define MACH_GROUP_GLOBESPAN   15	/* Globespan */
-#define  MACH_IVR		0	/* IVR eval board */
-
-/*
  * Valid machtype for group SIBYTE
  */
 #define MACH_GROUP_SIBYTE	16	/* Sibyte / Broadcom */
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index 36416fd..9ab59e2 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -46,8 +46,6 @@
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
 
-extern void (*__flush_icache_page)(struct vm_area_struct *vma,
-	struct page *page);
 static inline void flush_icache_page(struct vm_area_struct *vma,
 	struct page *page)
 {
diff --git a/include/asm-mips/galileo-boards/ev96100.h b/include/asm-mips/galileo-boards/ev96100.h
deleted file mode 100644
index 070dfd8..0000000
--- a/include/asm-mips/galileo-boards/ev96100.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *
- */
-#ifndef _MIPS_EV96100_H
-#define _MIPS_EV96100_H
-
-#include <asm/addrspace.h>
-
-/*
- *   GT64120 config space base address
- */
-#define GT64120_BASE	(KSEG1ADDR(0x14000000))
-#define MIPS_GT_BASE	GT64120_BASE
-
-/*
- *   PCI Bus allocation
- */
-#define GT_PCI_MEM_BASE    0x12000000UL
-#define GT_PCI_MEM_SIZE    0x02000000UL
-#define GT_PCI_IO_BASE     0x10000000UL
-#define GT_PCI_IO_SIZE     0x02000000UL
-#define GT_ISA_IO_BASE     PCI_IO_BASE
-
-/*
- *   Duart I/O ports.
- */
-#define EV96100_COM1_BASE_ADDR 	(0xBD000000 + 0x20)
-#define EV96100_COM2_BASE_ADDR	(0xBD000000 + 0x00)
-
-
-/*
- *   EV96100 interrupt controller register base.
- */
-#define EV96100_ICTRL_REGS_BASE	(KSEG1ADDR(0x1f000000))
-
-/*
- *   EV96100 UART register base.
- */
-#define EV96100_UART0_REGS_BASE	EV96100_COM1_BASE_ADDR
-#define EV96100_UART1_REGS_BASE	EV96100_COM2_BASE_ADDR
-#define EV96100_BASE_BAUD	( 3686400 / 16 )
-
-
-/*
- * Because of an error/peculiarity in the Galileo chip, we need to swap the
- * bytes when running bigendian.
- */
-#define __GT_READ(ofs)							\
-	(*(volatile u32 *)(GT64120_BASE+(ofs)))
-#define __GT_WRITE(ofs, data)						\
-	do { *(volatile u32 *)(GT64120_BASE+(ofs)) = (data); } while (0)
-#define GT_READ(ofs)		le32_to_cpu(__GT_READ(ofs))
-#define GT_WRITE(ofs, data)	__GT_WRITE(ofs, cpu_to_le32(data))
-
-#endif /* !(_MIPS_EV96100_H) */
diff --git a/include/asm-mips/galileo-boards/ev96100int.h b/include/asm-mips/galileo-boards/ev96100int.h
deleted file mode 100644
index c58b16d..0000000
--- a/include/asm-mips/galileo-boards/ev96100int.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- *
- */
-#ifndef _MIPS_EV96100INT_H
-#define _MIPS_EV96100INT_H
-
-#define EV96100INT_UART_0    6     /* IP 6 */
-#define EV96100INT_TIMER     7     /* IP 7 */
-
-extern void ev96100int_init(void);
-
-#endif /* !(_MIPS_EV96100_H) */
diff --git a/include/asm-mips/irqflags.h b/include/asm-mips/irqflags.h
index 43ca09a..46bf5de 100644
--- a/include/asm-mips/irqflags.h
+++ b/include/asm-mips/irqflags.h
@@ -213,12 +213,37 @@
  * Do the CPU's IRQ-state tracing from assembly code.
  */
 #ifdef CONFIG_TRACE_IRQFLAGS
+/* Reload some registers clobbered by trace_hardirqs_on */
+#ifdef CONFIG_64BIT
+# define TRACE_IRQS_RELOAD_REGS						\
+	LONG_L	$11, PT_R11(sp);					\
+	LONG_L	$10, PT_R10(sp);					\
+	LONG_L	$9, PT_R9(sp);						\
+	LONG_L	$8, PT_R8(sp);						\
+	LONG_L	$7, PT_R7(sp);						\
+	LONG_L	$6, PT_R6(sp);						\
+	LONG_L	$5, PT_R5(sp);						\
+	LONG_L	$4, PT_R4(sp);						\
+	LONG_L	$2, PT_R2(sp)
+#else
+# define TRACE_IRQS_RELOAD_REGS						\
+	LONG_L	$7, PT_R7(sp);						\
+	LONG_L	$6, PT_R6(sp);						\
+	LONG_L	$5, PT_R5(sp);						\
+	LONG_L	$4, PT_R4(sp);						\
+	LONG_L	$2, PT_R2(sp)
+#endif
 # define TRACE_IRQS_ON							\
+	CLI;	/* make sure trace_hardirqs_on() is called in kernel level */ \
 	jal	trace_hardirqs_on
+# define TRACE_IRQS_ON_RELOAD						\
+	TRACE_IRQS_ON;							\
+	TRACE_IRQS_RELOAD_REGS
 # define TRACE_IRQS_OFF							\
 	jal	trace_hardirqs_off
 #else
 # define TRACE_IRQS_ON
+# define TRACE_IRQS_ON_RELOAD
 # define TRACE_IRQS_OFF
 #endif
 
diff --git a/include/asm-mips/it8172/it8172.h b/include/asm-mips/it8172/it8172.h
deleted file mode 100644
index 8f23af0..0000000
--- a/include/asm-mips/it8172/it8172.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	IT8172 system controller defines.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __IT8172__H__
-#define __IT8172__H__
-
-#include <asm/addrspace.h>
-
-#define IT8172_BASE			0x18000000
-#define IT8172_PCI_IO_BASE		0x14000000
-#define IT8172_PCI_MEM_BASE		0x10000000
-
-// System registers offsets from IT8172_BASE
-#define IT_CMFPCR			0x0
-#define IT_DSRR				0x2
-#define IT_PCDCR			0x4
-#define IT_SPLLCR			0x6
-#define IT_CIDR				0x10
-#define IT_CRNR				0x12
-#define IT_CPUTR			0x14
-#define IT_CTCR				0x16
-#define IT_SDPR				0xF0
-
-// Power management register offset from IT8172_PCI_IO_BASE
-// Power Management Device Standby Register
-#define IT_PM_DSR		0x15800
-
-#define IT_PM_DSR_TMR0SB	0x0001
-#define IT_PM_DSR_TMR1SB	0x0002
-#define IT_PM_DSR_CIR0SB	0x0004
-#define IT_PM_DSR_CIR1SB	0x0008
-#define IT_PM_DSR_SCR0SB	0x0010
-#define IT_PM_DSR_SCR1SB	0x0020
-#define IT_PM_DSR_PPSB		0x0040
-#define IT_PM_DSR_I2CSB		0x0080
-#define IT_PM_DSR_UARTSB	0x0100
-#define IT_PM_DSR_IDESB		0x0200
-#define IT_PM_DSR_ACSB		0x0400
-#define IT_PM_DSR_M68KSB	0x0800
-
-// Power Management PCI Device Software Reset Register
-#define IT_PM_PCISR             0x15802
-
-#define IT_PM_PCISR_IDESR       0x0001
-#define IT_PM_PCISR_CDMASR      0x0002
-#define IT_PM_PCISR_USBSR       0x0004
-#define IT_PM_PCISR_DMASR       0x0008
-#define IT_PM_PCISR_ACSR        0x0010
-#define IT_PM_PCISR_MEMSR       0x0020
-#define IT_PM_PCISR_68KSR       0x0040
-
-
-// PCI Configuration address and data register offsets
-// from IT8172_BASE
-#define IT_CONFADDR			0x4000
-#define IT_BUSNUM_SHF                   16
-#define IT_DEVNUM_SHF                   11
-#define IT_FUNCNUM_SHF                  8
-#define IT_REGNUM_SHF                   2
-
-#define IT_CONFDATA			0x4004
-
-// PCI configuration header common register offsets
-#define IT_VID				0x00
-#define IT_DID				0x02
-#define IT_PCICMD			0x04
-#define IT_PCISTS			0x06
-#define IT_RID				0x08
-#define IT_CLASSC			0x09
-#define IT_HEADT			0x0E
-#define IT_SERIRQC			0x49
-
-// PCI to Internal/LPC Bus Bridge configuration header register offset
-#define IT_P2I_BCR				0x4C
-#define IT_P2I_D0IOSC				0x50
-#define IT_P2I_D1IOSC				0x54
-#define IT_P2I_D2IOSC				0x58
-#define IT_P2I_D3IOSC				0x5C
-#define IT_P2I_D4IOSC				0x60
-#define IT_P2I_D5IOSC				0x64
-#define IT_P2I_D6IOSC				0x68
-#define IT_P2I_D7IOSC				0x6C
-#define IT_P2I_D8IOSC				0x70
-#define IT_P2I_D9IOSC				0x74
-#define IT_P2I_D10IOSC				0x78
-#define IT_P2I_D11IOSC				0x7C
-
-// Memory controller register offsets from IT8172_BASE
-#define IT_MC_SDRMR					0x1000
-#define IT_MC_SDRTR					0x1004
-#define IT_MC_MCR					0x1008
-#define IT_MC_SDTYPE					0x100C
-#define IT_MC_WPBA					0x1010
-#define IT_MC_WPTA					0x1014
-#define IT_MC_HATR					0x1018
-#define IT_MC_PCICR					0x101C
-
-// Flash/ROM control register offsets from IT8172_BASE
-#define IT_FC_BRCR					0x2000
-#define IT_FC_FCR					0x2004
-#define IT_FC_DCR					0x2008
-
-// M68K interface bridge configuration header register offset
-#define IT_M68K_MBCSR					0x54
-#define IT_M68K_TMR					0x58
-#define IT_M68K_BCR					0x5C
-#define IT_M68K_BSR					0x5D
-#define IT_M68K_DTR					0x5F
-
-// Register offset from IT8172_PCI_IO_BASE
-// These registers are accessible through 8172 PCI IO window.
-
-// INTC
-#define IT_INTC_BASE				0x10000
-#define IT_INTC_LBDNIRR				0x10000
-#define IT_INTC_LBDNIMR				0x10002
-#define IT_INTC_LBDNITR				0x10004
-#define IT_INTC_LBDNIAR				0x10006
-#define IT_INTC_LPCNIRR				0x10010
-#define IT_INTC_LPCNIMR				0x10012
-#define IT_INTC_LPCNITR				0x10014
-#define IT_INTC_LPCNIAR				0x10016
-#define IT_INTC_PDNIRR				0x10020
-#define IT_INTC_PDNIMR				0x10022
-#define IT_INTC_PDNITR				0x10024
-#define IT_INTC_PDNIAR				0x10026
-#define IT_INTC_UMNIRR				0x10030
-#define IT_INTC_UMNITR				0x10034
-#define IT_INTC_UMNIAR				0x10036
-#define IT_INTC_TYPER				0x107FE
-
-// IT8172 PCI device number
-#define IT_C2P_DEVICE				0
-#define IT_AUDIO_DEVICE				1
-#define IT_DMAC_DEVICE				1
-#define IT_CDMAC_DEVICE				1
-#define IT_USB_DEVICE				1
-#define IT_P2I_DEVICE				1
-#define IT_IDE_DEVICE				1
-#define IT_M68K_DEVICE				1
-
-// IT8172 PCI function number
-#define IT_C2P_FUNCION				0
-#define IT_AUDIO_FUNCTION			0
-#define IT_DMAC_FUNCTION			1
-#define IT_CDMAC_FUNCTION			2
-#define IT_USB_FUNCTION				3
-#define IT_P2I_FUNCTION				4
-#define IT_IDE_FUNCTION				5
-#define IT_M68K_FUNCTION			6
-
-// IT8172 GPIO
-#define IT_GPADR				0x13800
-#define IT_GPBDR				0x13808
-#define IT_GPCDR				0x13810
-#define IT_GPACR				0x13802
-#define IT_GPBCR				0x1380A
-#define IT_GPCCR				0x13812
-#define IT_GPAICR				0x13804
-#define IT_GPBICR				0x1380C
-#define IT_GPCICR				0x13814
-#define IT_GPAISR				0x13806
-#define IT_GPBISR				0x1380E
-#define IT_GPCISR				0x13816
-#define IT_GCR					0x13818
-
-// IT8172 RTC
-#define IT_RTC_BASE				0x14800
-#define IT_RTC_CENTURY				0x14808
-
-#define IT_RTC_RIR0				0x00
-#define IT_RTC_RTR0				0x01
-#define IT_RTC_RIR1				0x02
-#define IT_RTC_RTR1				0x03
-#define IT_RTC_RIR2				0x04
-#define IT_RTC_RTR2				0x05
-#define IT_RTC_RCTR				0x08
-#define IT_RTC_RA				0x0A
-#define IT_RTC_RB				0x0B
-#define IT_RTC_RC				0x0C
-#define IT_RTC_RD				0x0D
-
-#define RTC_SEC_INDEX				0x00
-#define RTC_MIN_INDEX				0x02
-#define RTC_HOUR_INDEX				0x04
-#define RTC_DAY_INDEX				0x06
-#define RTC_DATE_INDEX				0x07
-#define RTC_MONTH_INDEX				0x08
-#define RTC_YEAR_INDEX				0x09
-
-// IT8172 internal device registers
-#define IT_TIMER_BASE				0x10800
-#define IT_CIR0_BASE				0x11000
-#define IT_UART_BASE				0x11800
-#define IT_SCR0_BASE				0x12000
-#define IT_SCR1_BASE				0x12800
-#define IT_PP_BASE				0x13000
-#define IT_I2C_BASE				0x14000
-#define IT_CIR1_BASE				0x15000
-
-// IT8172 Smart Card Reader offsets from IT_SCR*_BASE
-#define IT_SCR_SFR				0x08
-#define IT_SCR_SCDR				0x09
-
-// IT8172 IT_SCR_SFR bit definition & mask
-#define	IT_SCR_SFR_GATE_UART			0x40
-#define	IT_SCR_SFR_GATE_UART_BIT		6
-#define IT_SCR_SFR_GATE_UART_OFF		0
-#define	IT_SCR_SFR_GATE_UART_ON			1
-#define	IT_SCR_SFR_FET_CHARGE			0x30
-#define	IT_SCR_SFR_FET_CHARGE_BIT		4
-#define IT_SCR_SFR_FET_CHARGE_3_3_US		3
-#define IT_SCR_SFR_FET_CHARGE_13_US		2
-#define IT_SCR_SFR_FET_CHARGE_53_US		1
-#define IT_SCR_SFR_FET_CHARGE_213_US		0
-#define	IT_SCR_SFR_CARD_FREQ			0x0C
-#define	IT_SCR_SFR_CARD_FREQ_BIT		2
-#define IT_SCR_SFR_CARD_FREQ_STOP		3
-#define IT_SCR_SFR_CARD_FREQ_3_5_MHZ		0
-#define IT_SCR_SFR_CARD_FREQ_7_1_MHZ		2
-#define IT_SCR_SFR_CARD_FREQ_96_DIV_MHZ		1
-#define	IT_SCR_SFR_FET_ACTIVE			0x02
-#define	IT_SCR_SFR_FET_ACTIVE_BIT		1
-#define IT_SCR_SFR_FET_ACTIVE_INVERT		0
-#define IT_SCR_SFR_FET_ACTIVE_NONINVERT		1
-#define	IT_SCR_SFR_ENABLE			0x01
-#define	IT_SCR_SFR_ENABLE_BIT			0
-#define IT_SCR_SFR_ENABLE_OFF			0
-#define IT_SCR_SFR_ENABLE_ON			1
-
-// IT8172 IT_SCR_SCDR bit definition & mask
-#define	IT_SCR_SCDR_RESET_MODE			0x80
-#define	IT_SCR_SCDR_RESET_MODE_BIT		7
-#define	IT_SCR_SCDR_RESET_MODE_ASYNC		0
-#define IT_SCR_SCDR_RESET_MODE_SYNC		1
-#define	IT_SCR_SCDR_DIVISOR			0x7F
-#define	IT_SCR_SCDR_DIVISOR_BIT			0
-#define	IT_SCR_SCDR_DIVISOR_STOP_VAL_1		0x00
-#define	IT_SCR_SCDR_DIVISOR_STOP_VAL_2		0x01
-#define	IT_SCR_SCDR_DIVISOR_STOP_VAL_3		0x7F
-
-// IT8172 DMA
-#define IT_DMAC_BASE				0x16000
-#define IT_DMAC_BCAR0				0x00
-#define IT_DMAC_BCAR1				0x04
-#define IT_DMAC_BCAR2				0x08
-#define IT_DMAC_BCAR3				0x0C
-#define IT_DMAC_BCCR0				0x02
-#define IT_DMAC_BCCR1				0x06
-#define IT_DMAC_BCCR2				0x0a
-#define IT_DMAC_BCCR3				0x0e
-#define IT_DMAC_CR				0x10
-#define IT_DMAC_SR				0x12
-#define IT_DMAC_ESR				0x13
-#define IT_DMAC_RQR				0x14
-#define IT_DMAC_MR				0x16
-#define IT_DMAC_EMR				0x17
-#define IT_DMAC_MKR				0x18
-#define IT_DMAC_PAR0				0x20
-#define IT_DMAC_PAR1				0x22
-#define IT_DMAC_PAR2				0x24
-#define IT_DMAC_PAR3				0x26
-
-// IT8172 IDE
-#define IT_IDE_BASE				0x17800
-#define IT_IDE_STATUS				0x1F7
-
-// IT8172 Audio Controller
-#define IT_AC_BASE				0x17000
-#define	IT_AC_PCMOV				0x00
-#define IT_AC_FMOV				0x02
-#define	IT_AC_I2SV				0x04
-#define IT_AC_DRSS				0x06
-#define IT_AC_PCC				0x08
-#define IT_AC_PCDL				0x0A
-#define IT_AC_PCB1STA				0x0C
-#define IT_AC_PCB2STA				0x10
-#define IT_AC_CAPCC				0x14
-#define IT_AC_CAPCDL				0x16
-#define IT_AC_CAPB1STA				0x18
-#define IT_AC_CAPB2STA				0x1C
-#define IT_AC_CODECC				0x22
-#define IT_AC_I2SMC				0x24
-#define IT_AC_VS				0x26
-#define IT_AC_SRCS				0x28
-#define IT_AC_CIRCP				0x2A
-#define IT_AC_CIRDP				0x2C
-#define IT_AC_TM				0x4A
-#define IT_AC_PFDP				0x4C
-#define IT_AC_GC				0x54
-#define IT_AC_IMC				0x56
-#define IT_AC_ISC				0x5B
-#define IT_AC_OPL3SR				0x68
-#define IT_AC_OPL3DWDR				0x69
-#define IT_AC_OPL3AB1W				0x6A
-#define IT_AC_OPL3DW				0x6B
-#define IT_AC_BPDC				0x70
-
-
-// IT8172 Timer
-#define IT_TIMER_BASE				0x10800
-#define	TIMER_TCVR0				0x00
-#define TIMER_TRVR0				0x02
-#define	TIMER_TCR0				0x04
-#define TIMER_TIRR				0x06
-#define	TIMER_TCVR1				0x08
-#define TIMER_TRVR1				0x0A
-#define	TIMER_TCR1				0x0C
-#define TIMER_TIDR				0x0E
-
-
-#define IT_WRITE(ofs, data) *(volatile u32 *)KSEG1ADDR((IT8172_BASE+ofs)) = data
-#define IT_READ(ofs, data)  data = *(volatile u32 *)KSEG1ADDR((IT8172_BASE+ofs))
-
-#define IT_IO_WRITE(ofs, data) *(volatile u32 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs)) = data
-#define IT_IO_READ(ofs, data)  data = *(volatile u32 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs))
-
-#define IT_IO_WRITE16(ofs, data) *(volatile u16 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs)) = data
-#define IT_IO_READ16(ofs, data)  data = *(volatile u16 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs))
-
-#endif
diff --git a/include/asm-mips/it8172/it8172_cir.h b/include/asm-mips/it8172/it8172_cir.h
deleted file mode 100644
index 6a1dbd2..0000000
--- a/include/asm-mips/it8172/it8172_cir.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	IT8172 Consumer IR port defines.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define NUM_CIR_PORTS 2
-
-/* Master Control Register */
-#define CIR_RESET              0x1
-#define CIR_FIFO_CLEAR         0x2
-#define CIR_SET_FIFO_TL(x)     (((x)&0x3)<<2)
-#define CIR_ILE                0x10
-#define CIR_ILSEL              0x20
-
-/* Interrupt Enable Register */
-#define CIR_TLDLIE             0x1
-#define CIR_RDAIE              0x2
-#define CIR_RFOIE              0x4
-#define CIR_IEC                0x80
-
-/* Interrupt Identification Register */
-#define CIR_TLDLI              0x1
-#define CIR_RDAI               0x2
-#define CIR_RFOI               0x4
-#define CIR_NIP                0x80
-
-/* Carrier Frequency Register */
-#define CIR_SET_CF(x)          ((x)&0x1f)
-  #define CFQ_38_480           0xB       /* 38 KHz low, 480 KHz high */
-#define CIR_HCFS               0x20
-  #define CIR_SET_HS(x)        (((x)&0x1)<<5)
-
-
-/* Receiver Control Register */
-#define CIR_SET_RXDCR(x)       ((x)&0x7)
-#define CIR_RXACT              0x8
-#define CIR_RXEND              0x10
-#define CIR_RDWOS              0x20
-  #define CIR_SET_RDWOS(x)     (((x)&0x1)<<5)
-#define CIR_RXEN               0x80
-
-/* Transmitter Control Register */
-#define CIR_SET_TXMPW(x)       ((x)&0x7)
-#define CIR_SET_TXMPM(x)       (((x)&0x3)<<3)
-#define CIR_TXENDF             0x20
-#define CIR_TXRLE              0x40
-
-/* Receiver FIFO Status Register */
-#define CIR_RXFBC_MASK         0x3f
-#define CIR_RXFTO              0x80
-
-/* Wakeup Code Length Register */
-#define CIR_SET_WCL            ((x)&0x3f)
-#define CIR_WCL_MASK(x)        ((x)&0x3f)
-
-/* Wakeup Power Control/Status Register */
-#define CIR_BTMON              0x2
-#define CIR_CIRON              0x4
-#define CIR_RCRST              0x10
-#define CIR_WCRST              0x20
-
-struct cir_port {
-	int port;
-	unsigned short baud_rate;
-	unsigned char fifo_tl;
-	unsigned char cfq;
-	unsigned char hcfs;
-	unsigned char rdwos;
-	unsigned char rxdcr;
-};
-
-struct it8172_cir_regs {
-	unsigned char dr;       /* data                        */
-	char pad;
-	unsigned char mstcr;    /* master control              */
-	char pad1;
-	unsigned char ier;      /* interrupt enable            */
-	char pad2;
-	unsigned char iir;      /* interrupt identification    */
-	char pad3;
-	unsigned char cfr;      /* carrier frequency           */
-	char pad4;
-	unsigned char rcr;      /* receiver control            */
-	char pad5;
-	unsigned char tcr;      /* transmitter control         */
-	char pad6;
-	char pad7;
-	char pad8;
-	unsigned char bdlr;     /* baud rate divisor low byte  */
-	char pad9;
-	unsigned char bdhr;     /* baud rate divisor high byte */
-	char pad10;
-	unsigned char tfsr;     /* tx fifo byte count          */
-	char pad11;
-	unsigned char rfsr;     /* rx fifo status              */
-	char pad12;
-	unsigned char wcl;      /* wakeup code length          */
-	char pad13;
-	unsigned char wcr;      /* wakeup code read/write      */
-	char pad14;
-	unsigned char wps;      /* wakeup power control/status */
-};
-
-int cir_port_init(struct cir_port *cir);
-extern void clear_fifo(struct cir_port *cir);
-extern void enable_receiver(struct cir_port *cir);
-extern void disable_receiver(struct cir_port *cir);
-extern void enable_rx_demodulation(struct cir_port *cir);
-extern void disable_rx_demodulation(struct cir_port *cir);
-extern void set_rx_active(struct cir_port *cir);
-extern void int_enable(struct cir_port *cir);
-extern void rx_int_enable(struct cir_port *cir);
-extern char get_int_status(struct cir_port *cir);
-extern int cir_get_rx_count(struct cir_port *cir);
-extern char cir_read_data(struct cir_port *cir);
diff --git a/include/asm-mips/it8172/it8172_dbg.h b/include/asm-mips/it8172/it8172_dbg.h
deleted file mode 100644
index f404ec7c..0000000
--- a/include/asm-mips/it8172/it8172_dbg.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	Function prototypes for low level uart routines to
- *	directly access a 16550 uart.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-
-extern void putch(const unsigned char c);
-extern void puts(unsigned char *cp);
-extern void fputs(unsigned char *cp);
-extern void put64(uint64_t ul);
-extern void put32(unsigned u);
diff --git a/include/asm-mips/it8172/it8172_int.h b/include/asm-mips/it8172/it8172_int.h
deleted file mode 100644
index 837e83a..0000000
--- a/include/asm-mips/it8172/it8172_int.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	ITE 8172 Interrupt Numbering
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _MIPS_ITEINT_H
-#define _MIPS_ITEINT_H
-
-/*
- * Here's the "strategy":
- * We number the LPC serial irqs from 0 to 15,
- * the local bus irqs from 16 to 31,
- * the pci dev register interrupts from 32 to 47,
- * and the non-maskable ints from 48 to 53.
- */
-
-#define IT8172_LPC_IRQ_BASE  0    /* first LPC int number */
-#define IT8172_SERIRQ_0      (IT8172_LPC_IRQ_BASE + 0)
-#define IT8172_SERIRQ_1      (IT8172_LPC_IRQ_BASE + 1)
-#define IT8172_SERIRQ_2      (IT8172_LPC_IRQ_BASE + 2)
-#define IT8172_SERIRQ_3      (IT8172_LPC_IRQ_BASE + 3)
-#define IT8172_SERIRQ_4      (IT8172_LPC_IRQ_BASE + 4)
-#define IT8172_SERIRQ_5      (IT8172_LPC_IRQ_BASE + 5)
-#define IT8172_SERIRQ_6      (IT8172_LPC_IRQ_BASE + 6)
-#define IT8172_SERIRQ_7      (IT8172_LPC_IRQ_BASE + 7)
-#define IT8172_SERIRQ_8      (IT8172_LPC_IRQ_BASE + 8)
-#define IT8172_SERIRQ_9      (IT8172_LPC_IRQ_BASE + 9)
-#define IT8172_SERIRQ_10     (IT8172_LPC_IRQ_BASE + 10)
-#define IT8172_SERIRQ_11     (IT8172_LPC_IRQ_BASE + 11)
-#define IT8172_SERIRQ_12     (IT8172_LPC_IRQ_BASE + 12)
-#define IT8172_SERIRQ_13     (IT8172_LPC_IRQ_BASE + 13)
-#define IT8172_SERIRQ_14     (IT8172_LPC_IRQ_BASE + 14)
-#define IT8172_SERIRQ_15     (IT8172_LPC_IRQ_BASE + 15)
-
-#define IT8172_LB_IRQ_BASE  16   /* first local bus int number */
-#define IT8172_PPR_IRQ          (IT8172_LB_IRQ_BASE + 0) /* parallel port */
-#define IT8172_TIMER0_IRQ       (IT8172_LB_IRQ_BASE + 1)
-#define IT8172_TIMER1_IRQ       (IT8172_LB_IRQ_BASE + 2)
-#define IT8172_I2C_IRQ          (IT8172_LB_IRQ_BASE + 3)
-#define IT8172_GPIO_IRQ         (IT8172_LB_IRQ_BASE + 4)
-#define IT8172_CIR0_IRQ         (IT8172_LB_IRQ_BASE + 5)
-#define IT8172_CIR1_IRQ         (IT8172_LB_IRQ_BASE + 6)
-#define IT8172_UART_IRQ         (IT8172_LB_IRQ_BASE + 7)
-#define IT8172_SCR0_IRQ         (IT8172_LB_IRQ_BASE + 8)
-#define IT8172_SCR1_IRQ         (IT8172_LB_IRQ_BASE + 9)
-#define IT8172_RTC_IRQ          (IT8172_LB_IRQ_BASE + 10)
-#define IT8172_IOCHK_IRQ        (IT8172_LB_IRQ_BASE + 11)
-/* 12 - 15 reserved */
-
-/*
- * Note here that the pci dev registers includes bits for more than
- * just the pci devices.
- */
-#define IT8172_PCI_DEV_IRQ_BASE  32   /* first pci dev irq */
-#define IT8172_AC97_IRQ          (IT8172_PCI_DEV_IRQ_BASE + 0)
-#define IT8172_MC68K_IRQ         (IT8172_PCI_DEV_IRQ_BASE + 1)
-#define IT8172_IDE_IRQ           (IT8172_PCI_DEV_IRQ_BASE + 2)
-#define IT8172_USB_IRQ           (IT8172_PCI_DEV_IRQ_BASE + 3)
-#define IT8172_BRIDGE_MASTER_IRQ (IT8172_PCI_DEV_IRQ_BASE + 4)
-#define IT8172_BRIDGE_TARGET_IRQ (IT8172_PCI_DEV_IRQ_BASE + 5)
-#define IT8172_PCI_INTA_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 6)
-#define IT8172_PCI_INTB_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 7)
-#define IT8172_PCI_INTC_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 8)
-#define IT8172_PCI_INTD_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 9)
-#define IT8172_S_INTA_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 10)
-#define IT8172_S_INTB_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 11)
-#define IT8172_S_INTC_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 12)
-#define IT8172_S_INTD_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 13)
-#define IT8172_CDMA_IRQ          (IT8172_PCI_DEV_IRQ_BASE + 14)
-#define IT8172_DMA_IRQ           (IT8172_PCI_DEV_IRQ_BASE + 15)
-
-#define IT8172_NMI_IRQ_BASE      48
-#define IT8172_SER_NMI_IRQ       (IT8172_NMI_IRQ_BASE + 0)
-#define IT8172_PCI_NMI_IRQ       (IT8172_NMI_IRQ_BASE + 1)
-#define IT8172_RTC_NMI_IRQ       (IT8172_NMI_IRQ_BASE + 2)
-#define IT8172_CPUIF_NMI_IRQ     (IT8172_NMI_IRQ_BASE + 3)
-#define IT8172_PMER_NMI_IRQ      (IT8172_NMI_IRQ_BASE + 4)
-#define IT8172_POWER_NMI_IRQ     (IT8172_NMI_IRQ_BASE + 5)
-
-#define IT8172_LAST_IRQ          (IT8172_POWER_NMI_IRQ)
-/* Finally, let's move over here the mips cpu timer interrupt.
- */
-#define MIPS_CPU_TIMER_IRQ       (NR_IRQS-1)
-
-/*
- * IT8172 Interrupt Controller Registers
- */
-struct it8172_intc_regs {
-        volatile unsigned short lb_req;      /* offset 0 */
-        volatile unsigned short lb_mask;
-        volatile unsigned short lb_trigger;
-        volatile unsigned short lb_level;
-	unsigned char pad0[8];
-
-        volatile unsigned short lpc_req;     /* offset 0x10 */
-        volatile unsigned short lpc_mask;
-        volatile unsigned short lpc_trigger;
-        volatile unsigned short lpc_level;
-	unsigned char pad1[8];
-
-        volatile unsigned short pci_req;     /* offset 0x20 */
-        volatile unsigned short pci_mask;
-        volatile unsigned short pci_trigger;
-        volatile unsigned short pci_level;
-	unsigned char pad2[8];
-
-        volatile unsigned short nmi_req;     /* offset 0x30 */
-        volatile unsigned short nmi_mask;
-        volatile unsigned short nmi_trigger;
-        volatile unsigned short nmi_level;
-	unsigned char pad3[6];
-
-        volatile unsigned short nmi_redir;   /* offset 0x3E */
-	unsigned char pad4[0xBE];
-
-        volatile unsigned short intstatus;    /* offset 0xFE */
-};
-
-#endif /* _MIPS_ITEINT_H */
diff --git a/include/asm-mips/it8172/it8172_pci.h b/include/asm-mips/it8172/it8172_pci.h
deleted file mode 100644
index 42c61f5..0000000
--- a/include/asm-mips/it8172/it8172_pci.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	IT8172 system controller specific pci defines.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _8172PCI_H_
-#define _8172PCI_H_
-
-// PCI configuration space Type0
-#define	PCI_IDREG	0x00
-#define	PCI_CMDSTSREG	0x04
-#define	PCI_CLASSREG	0x08
-#define	PCI_BHLCREG	0x0C
-#define	PCI_BASE1REG	0x10
-#define	PCI_BASE2REG	0x14
-#define	PCI_BASE3REG	0x18
-#define	PCI_BASE4REG	0x1C
-#define	PCI_BASE5REG	0x20
-#define	PCI_BASE6REG	0x24
-#define	PCI_ROMBASEREG	0x30
-#define	PCI_INTRREG	0x3C
-
-// PCI configuration space Type1
-#define	PCI_BUSNOREG	0x18
-
-#define	IT_PCI_VENDORID(x)	((x) & 0xFFFF)
-#define	IT_PCI_DEVICEID(x)	(((x)>>16) & 0xFFFF)
-
-// Command register
-#define	PCI_CMD_IOEN		0x00000001
-#define	PCI_CMD_MEMEN		0x00000002
-#define	PCI_CMD_BUSMASTER	0x00000004
-#define	PCI_CMD_SPCYCLE		0x00000008
-#define	PCI_CMD_WRINV		0x00000010
-#define	PCI_CMD_VGASNOOP	0x00000020
-#define	PCI_CMD_PERR		0x00000040
-#define	PCI_CMD_WAITCTRL	0x00000080
-#define	PCI_CMD_SERR		0x00000100
-#define	PCI_CMD_FAST_BACKTOBACK	0x00000200
-
-// Status register
-#define	PCI_STS_66MHZ		0x00200000
-#define	PCI_STS_SUPPORT_UDF	0x00400000
-#define	PCI_STS_FAST_BACKTOBACK	0x00800000
-#define	PCI_STS_DATA_PERR	0x01000000
-#define	PCI_STS_DEVSEL0		0x02000000
-#define	PCI_STS_DEVSEL1		0x04000000
-#define	PCI_STS_SIG_TGTABORT	0x08000000
-#define	PCI_STS_RCV_TGTABORT	0x10000000
-#define	PCI_STS_RCV_MSTABORT	0x20000000
-#define	PCI_STS_SYSERR		0x40000000
-#define	PCI_STS_DETCT_PERR	0x80000000
-
-#define	IT_PCI_CLASS(x)		(((x)>>24) & 0xFF)
-#define	IT_PCI_SUBCLASS(x)		(((x)>>16) & 0xFF)
-#define	IT_PCI_INTERFACE(x)	(((x)>>8) & 0xFF)
-#define	IT_PCI_REVISION(x)		((x) & 0xFF)
-
-// PCI class code
-#define	PCI_CLASS_BRIDGE			0x06
-
-// bridge subclass
-#define	PCI_SUBCLASS_BRIDGE_HOST		0x00
-#define	PCI_SUBCLASS_BRIDGE_PCI			0x04
-
-// BHLCREG
-#define	IT_PCI_BIST(x)		(((x)>>24) & 0xFF)
-#define	IT_PCI_HEADERTYPE(x)	(((x)>>16) & 0xFF)
-#define	IT_PCI_LATENCYTIMER(x)	(((x)>>8) & 0xFF)
-#define	IT_PCI_CACHELINESIZE(x)	((x) & 0xFF)
-
-#define	PCI_MULTIFUNC	0x80
-
-// INTRREG
-#define	IT_PCI_MAXLAT(x)		(((x)>>24) & 0xFF)
-#define	IT_PCI_MINGNT(x)		(((x)>>16) & 0xFF)
-#define	IT_PCI_INTRPIN(x)		(((x)>>8) & 0xFF)
-#define	IT_PCI_INTRLINE(x)		((x) & 0xFF)
-
-#define	PCI_VENDOR_NEC	0x1033
-#define PCI_VENDOR_DEC	0x1101
-
-#endif // _8172PCI_H_
diff --git a/include/asm-mips/it8712.h b/include/asm-mips/it8712.h
deleted file mode 100644
index ca2dee0..0000000
--- a/include/asm-mips/it8712.h
+++ /dev/null
@@ -1,28 +0,0 @@
-
-#ifndef __IT8712_H__
-#define __IT8712_H__
-
-#define LPC_BASE_ADDR	0x14000000
-
-// MB PnP configuration register
-#define LPC_KEY_ADDR	0x1400002E
-#define LPC_DATA_ADDR	0x1400002F
-
-// Device LDN
-#define LDN_SERIAL1	0x01
-#define LDN_SERIAL2	0x02
-#define LDN_PARALLEL	0x03
-#define LDN_KEYBOARD	0x05
-#define LDN_MOUSE	0x06
-
-#define IT8712_UART1_PORT      0x3F8
-#define IT8712_UART2_PORT      0x2F8
-
-#ifndef ASM_ONLY
-
-void LPCSetConfig(char LdnNumber, char Index, char data);
-char LPCGetConfig(char LdnNumber, char Index);
-
-#endif
-
-#endif
diff --git a/include/asm-mips/mach-ev64120/mach-gt64120.h b/include/asm-mips/mach-ev64120/mach-gt64120.h
index 13b1443..7e272ce5 100644
--- a/include/asm-mips/mach-ev64120/mach-gt64120.h
+++ b/include/asm-mips/mach-ev64120/mach-gt64120.h
@@ -42,6 +42,7 @@
 #define EV64120_UART0_REGS_BASE	(KSEG1ADDR(EV64120_COM1_BASE_ADDR))
 #define EV64120_UART1_REGS_BASE	(KSEG1ADDR(EV64120_COM2_BASE_ADDR))
 #define EV64120_BASE_BAUD ( 3686400 / 16 )
+#define EV64120_UART_IRQ	6
 
 /*
  * PCI interrupts will come in on either the INTA or INTD interrups lines,
diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h
index 59d26b5..a13b715 100644
--- a/include/asm-mips/mach-ip27/topology.h
+++ b/include/asm-mips/mach-ip27/topology.h
@@ -22,6 +22,7 @@
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 4fb0fc4..5f3a907 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -44,9 +44,8 @@
 	unsigned long cp0_epc;
 #ifdef CONFIG_MIPS_MT_SMTC
 	unsigned long cp0_tcstatus;
-	unsigned long smtc_pad;
 #endif /* CONFIG_MIPS_MT_SMTC */
-};
+} __attribute__ ((aligned (8)));
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
 #define PTRACE_GETREGS		12
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index 035637c..d7a6513 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -55,51 +55,18 @@
  * Galileo EV64120 evaluation board
  */
 #ifdef CONFIG_MIPS_EV64120
-#include <asm/galileo-boards/ev96100.h>
-#include <asm/galileo-boards/ev96100int.h>
-#define EV96100_SERIAL_PORT_DEFNS                                  \
-    { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \
+#include <mach-gt64120.h>
+#define EV64120_SERIAL_PORT_DEFNS                                  \
+    { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
       .flags = STD_COM_FLAGS,  \
-      .iomem_base = EV96100_UART0_REGS_BASE, .iomem_reg_shift = 2, \
+      .iomem_base = EV64120_UART0_REGS_BASE, .iomem_reg_shift = 2, \
       .io_type = SERIAL_IO_MEM }, \
-    { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \
+    { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
       .flags = STD_COM_FLAGS, \
-      .iomem_base = EV96100_UART1_REGS_BASE, .iomem_reg_shift = 2, \
+      .iomem_base = EV64120_UART1_REGS_BASE, .iomem_reg_shift = 2, \
       .io_type = SERIAL_IO_MEM },
 #else
-#define EV96100_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_MIPS_ITE8172
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#include <asm/it8712.h>
-#define ITE_SERIAL_PORT_DEFNS                                  \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \
-      .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \
-    { .baud_base = (24000000/(16*13)), .port = (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \
-      .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \
-    /* Smart Card Reader 0 */ \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \
-      .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \
-    /* Smart Card Reader 1 */ \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \
-      .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 },
-#else
-#define ITE_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_MIPS_IVR
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#define IVR_SERIAL_PORT_DEFNS                                  \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \
-      .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 },         \
-    /* Smart Card Reader 1 */ \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \
-      .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 },
-#else
-#define IVR_SERIAL_PORT_DEFNS
+#define EV64120_SERIAL_PORT_DEFNS
 #endif
 
 #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
@@ -239,10 +206,8 @@
 
 #define SERIAL_PORT_DFNS				\
 	DDB5477_SERIAL_PORT_DEFNS			\
-	EV96100_SERIAL_PORT_DEFNS			\
+	EV64120_SERIAL_PORT_DEFNS			\
 	IP32_SERIAL_PORT_DEFNS                          \
-	ITE_SERIAL_PORT_DEFNS           		\
-	IVR_SERIAL_PORT_DEFNS           		\
 	JAZZ_SERIAL_PORT_DEFNS				\
 	STD_SERIAL_PORT_DEFNS				\
 	MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS		\
diff --git a/include/asm-mips/stacktrace.h b/include/asm-mips/stacktrace.h
new file mode 100644
index 0000000..07f8733
--- /dev/null
+++ b/include/asm-mips/stacktrace.h
@@ -0,0 +1,44 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H
+
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_KALLSYMS
+extern int raw_show_trace;
+extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+				  unsigned long pc, unsigned long *ra);
+#else
+#define raw_show_trace 1
+#define unwind_stack(task, sp, pc, ra)	0
+#endif
+
+static __always_inline void prepare_frametrace(struct pt_regs *regs)
+{
+#ifndef CONFIG_KALLSYMS
+	/*
+	 * Remove any garbage that may be in regs (specially func
+	 * addresses) to avoid show_raw_backtrace() to report them
+	 */
+	memset(regs, 0, sizeof(*regs));
+#endif
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set noat\n\t"
+#ifdef CONFIG_64BIT
+		"1: dla $1, 1b\n\t"
+		"sd $1, %0\n\t"
+		"sd $29, %1\n\t"
+		"sd $31, %2\n\t"
+#else
+		"1: la $1, 1b\n\t"
+		"sw $1, %0\n\t"
+		"sw $29, %1\n\t"
+		"sw $31, %2\n\t"
+#endif
+		".set pop\n\t"
+		: "=m" (regs->cp0_epc),
+		"=m" (regs->regs[29]), "=m" (regs->regs[31])
+		: : "memory");
+}
+
+#endif /* _ASM_STACKTRACE_H */
diff --git a/include/asm-mips/tx4938/tx4938_mips.h b/include/asm-mips/tx4938/tx4938_mips.h
index cf89b20..5f8498f 100644
--- a/include/asm-mips/tx4938/tx4938_mips.h
+++ b/include/asm-mips/tx4938/tx4938_mips.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-mips/tx4938/tx4938_bitmask.h
+ * linux/include/asm-mips/tx4938/tx4938_mips.h
  * Generic bitmask definitions
  *
  * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index c391429..685c914 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -1212,45 +1212,6 @@
 #  define __ARCH_WANT_COMPAT_SYS_TIME
 # endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm/sim.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage unsigned long sys_mmap(
-				unsigned long addr, size_t len,
-				int prot, int flags,
-				int fd, off_t offset);
-asmlinkage long sys_mmap2(
-			unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
 #endif /* !__ASSEMBLY__ */
 
 /*
diff --git a/include/asm-parisc/agp.h b/include/asm-parisc/agp.h
new file mode 100644
index 0000000..9f61d4e
--- /dev/null
+++ b/include/asm-parisc/agp.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_PARISC_AGP_H
+#define _ASM_PARISC_AGP_H
+
+/*
+ * PARISC specific AGP definitions.
+ * Copyright (c) 2006 Kyle McMartin <kyle@parisc-linux.org>
+ *
+ */
+
+#define map_page_into_agp(page)		/* nothing */
+#define unmap_page_from_agp(page)	/* nothing */
+#define flush_agp_mappings()		/* nothing */
+#define flush_agp_cache()		mb()
+
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
+#endif /* _ASM_PARISC_AGP_H */
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
index 1a7bfe6..5a1e0e8 100644
--- a/include/asm-parisc/assembly.h
+++ b/include/asm-parisc/assembly.h
@@ -29,7 +29,8 @@
 #define LDREGX  ldd,s
 #define LDREGM	ldd,mb
 #define STREGM	std,ma
-#define SHRREG  shrd
+#define SHRREG	shrd
+#define SHLREG	shld
 #define RP_OFFSET	16
 #define FRAME_SIZE	128
 #define CALLEE_REG_FRAME_SIZE	144
@@ -39,7 +40,8 @@
 #define LDREGX  ldwx,s
 #define LDREGM	ldwm
 #define STREGM	stwm
-#define SHRREG  shr
+#define SHRREG	shr
+#define SHLREG	shlw
 #define RP_OFFSET	20
 #define FRAME_SIZE	64
 #define CALLEE_REG_FRAME_SIZE	128
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index 0b459cd..2bc41f2 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -191,16 +191,38 @@
 }
 #define ARCH_HAS_FLUSH_ANON_PAGE
 
-static inline void
-flush_kernel_dcache_page(struct page *page)
-{
-	flush_kernel_dcache_page_asm(page_address(page));
-}
 #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+void flush_kernel_dcache_page_addr(void *addr);
+static inline void flush_kernel_dcache_page(struct page *page)
+{
+	flush_kernel_dcache_page_addr(page_address(page));
+}
 
 #ifdef CONFIG_DEBUG_RODATA
 void mark_rodata_ro(void);
 #endif
 
+#ifdef CONFIG_PA8X00
+/* Only pa8800, pa8900 needs this */
+#define ARCH_HAS_KMAP
+
+void kunmap_parisc(void *addr);
+
+static inline void *kmap(struct page *page)
+{
+	might_sleep();
+	return page_address(page);
+}
+
+#define kunmap(page)			kunmap_parisc(page_address(page))
+
+#define kmap_atomic(page, idx)		page_address(page)
+
+#define kunmap_atomic(addr, idx)	kunmap_parisc(addr)
+
+#define kmap_atomic_pfn(pfn, idx)	page_address(pfn_to_page(pfn))
+#define kmap_atomic_to_page(ptr)	virt_to_page(ptr)
+#endif
+
 #endif /* _PARISC_CACHEFLUSH_H */
 
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
index 71b4eee..fe85790 100644
--- a/include/asm-parisc/compat.h
+++ b/include/asm-parisc/compat.h
@@ -5,7 +5,7 @@
  */
 #include <linux/types.h>
 #include <linux/sched.h>
-#include <linux/personality.h>
+#include <linux/thread_info.h>
 
 #define COMPAT_USER_HZ 100
 
@@ -152,7 +152,7 @@
 
 static inline int __is_compat_task(struct task_struct *t)
 {
-	return personality(t->personality) == PER_LINUX32;
+	return test_ti_thread_flag(t->thread_info, TIF_32BIT);
 }
 
 static inline int is_compat_task(void)
diff --git a/include/asm-parisc/dma.h b/include/asm-parisc/dma.h
index 9979c3c..da2cf37 100644
--- a/include/asm-parisc/dma.h
+++ b/include/asm-parisc/dma.h
@@ -72,18 +72,13 @@
 #define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
 #define DMA2_EXT_MODE_REG	(0x400 | DMA2_MODE_REG)
 
-extern spinlock_t dma_spin_lock;
-
 static __inline__ unsigned long claim_dma_lock(void)
 {
-	unsigned long flags;
-	spin_lock_irqsave(&dma_spin_lock, flags);
-	return flags;
+	return 0;
 }
 
 static __inline__ void release_dma_lock(unsigned long flags)
 {
-	spin_unlock_irqrestore(&dma_spin_lock, flags);
 }
 
 
diff --git a/include/asm-parisc/futex.h b/include/asm-parisc/futex.h
index 6a332a9..d84bbb2 100644
--- a/include/asm-parisc/futex.h
+++ b/include/asm-parisc/futex.h
@@ -1,6 +1,71 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
+#ifndef _ASM_PARISC_FUTEX_H
+#define _ASM_PARISC_FUTEX_H
 
-#include <asm-generic/futex.h>
+#ifdef __KERNEL__
 
+#include <linux/futex.h>
+#include <asm/errno.h>
+#include <asm/uaccess.h>
+
+static inline int
+futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+{
+	int op = (encoded_op >> 28) & 7;
+	int cmp = (encoded_op >> 24) & 15;
+	int oparg = (encoded_op << 8) >> 20;
+	int cmparg = (encoded_op << 20) >> 20;
+	int oldval = 0, ret;
+	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+		oparg = 1 << oparg;
+
+	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	inc_preempt_count();
+
+	switch (op) {
+	case FUTEX_OP_SET:
+	case FUTEX_OP_ADD:
+	case FUTEX_OP_OR:
+	case FUTEX_OP_ANDN:
+	case FUTEX_OP_XOR:
+	default:
+		ret = -ENOSYS;
+	}
+
+	dec_preempt_count();
+
+	if (!ret) {
+		switch (cmp) {
+		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+		default: ret = -ENOSYS;
+		}
+	}
+	return ret;
+}
+
+/* Non-atomic version */
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+	int err = 0;
+	int uval;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	err = get_user(uval, uaddr);
+	if (err) return -EFAULT;
+	if (uval == oldval)
+		err = put_user(newval, uaddr);
+	if (err) return -EFAULT;
+	return uval;
+}
+
+#endif
 #endif
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index b9eb245..c1963ce 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -134,7 +134,7 @@
 }
 #define ioremap_nocache(off, sz)	ioremap((off), (sz))
 
-extern void iounmap(void __iomem *addr);
+extern void iounmap(const volatile void __iomem *addr);
 
 static inline unsigned char __raw_readb(const volatile void __iomem *addr)
 {
diff --git a/include/asm-parisc/iosapic.h b/include/asm-parisc/iosapic.h
deleted file mode 100644
index 613390e..0000000
--- a/include/asm-parisc/iosapic.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-** This file is private to iosapic driver.
-** If stuff needs to be used by another driver, move it to a common file.
-**
-** WARNING: fields most data structures here are ordered to make sure
-**          they pack nicely for 64-bit compilation. (ie sizeof(long) == 8)
-*/
-
-
-/*
-** I/O SAPIC init function
-** Caller knows where an I/O SAPIC is. LBA has an integrated I/O SAPIC.
-** Call setup as part of per instance initialization.
-** (ie *not* init_module() function unless only one is present.)
-** fixup_irq is to initialize PCI IRQ line support and
-** virtualize pcidev->irq value. To be called by pci_fixup_bus().
-*/
-extern void *iosapic_register(unsigned long hpa);
-extern int iosapic_fixup_irq(void *obj, struct pci_dev *pcidev);
-
-
-#ifdef __IA64__
-/*
-** PA: PIB (Processor Interrupt Block) is handled by Runway bus adapter.
-**     and is hardcoded to 0xfeeNNNN0 where NNNN is id_eid field.
-**
-** IA64: PIB is handled by "Local SAPIC" (integrated in the processor).
-*/
-struct local_sapic_info {
-	struct local_sapic_info *lsi_next;      /* point to next CPU info */
-	int                     *lsi_cpu_id;    /* point to logical CPU id */
-	unsigned long           *lsi_id_eid;    /* point to IA-64 CPU id */
-	int                     *lsi_status;    /* point to CPU status   */
-	void                    *lsi_private;   /* point to special info */
-};
-
-/*
-** "root" data structure which ties everything together.
-** Should always be able to start with sapic_root and locate
-** the desired information.
-*/
-struct sapic_info {
-	struct sapic_info	*si_next;	/* info is per cell */
-	int                     si_cellid;      /* cell id */
-	unsigned int            si_status;       /* status  */
-	char                    *si_pib_base;   /* intr blk base address */
-	local_sapic_info_t      *si_local_info;
-	io_sapic_info_t         *si_io_info;
-	extint_info_t           *si_extint_info;/* External Intr info      */
-};
-
-#endif /* IA64 */
-
diff --git a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h
index 5cae260..399c819 100644
--- a/include/asm-parisc/irq.h
+++ b/include/asm-parisc/irq.h
@@ -31,7 +31,7 @@
 	return (irq == 2) ? 9 : irq;
 }
 
-struct hw_interrupt_type;
+struct irq_chip;
 
 /*
  * Some useful "we don't have to do anything here" handlers.  Should
@@ -39,6 +39,8 @@
  */
 void no_ack_irq(unsigned int irq);
 void no_end_irq(unsigned int irq);
+void cpu_ack_irq(unsigned int irq);
+void cpu_end_irq(unsigned int irq);
 
 extern int txn_alloc_irq(unsigned int nbits);
 extern int txn_claim_irq(int);
@@ -46,7 +48,7 @@
 extern unsigned long txn_alloc_addr(unsigned int);
 extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
 
-extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *);
 extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest);
 
 /* soft power switch support (power.c) */
diff --git a/include/asm-parisc/mckinley.h b/include/asm-parisc/mckinley.h
new file mode 100644
index 0000000..d1ea6f1
--- /dev/null
+++ b/include/asm-parisc/mckinley.h
@@ -0,0 +1,9 @@
+#ifndef ASM_PARISC_MCKINLEY_H
+#define ASM_PARISC_MCKINLEY_H
+#ifdef __KERNEL__
+
+/* declared in arch/parisc/kernel/setup.c */
+extern struct proc_dir_entry * proc_mckinley_root;
+
+#endif /*__KERNEL__*/
+#endif /*ASM_PARISC_MCKINLEY_H*/
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index 57d6d82..3567208 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -26,24 +26,10 @@
 
 struct page;
 
-extern void purge_kernel_dcache_page(unsigned long);
-extern void copy_user_page_asm(void *to, void *from);
-extern void clear_user_page_asm(void *page, unsigned long vaddr);
-
-static inline void
-copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg)
-{
-	copy_user_page_asm(vto, vfrom);
-	flush_kernel_dcache_page_asm(vto);
-	/* XXX: ppc flushes icache too, should we? */
-}
-
-static inline void
-clear_user_page(void *page, unsigned long vaddr, struct page *pg)
-{
-	purge_kernel_dcache_page((unsigned long)page);
-	clear_user_page_asm(page, vaddr);
-}
+void copy_user_page_asm(void *to, void *from);
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+			   struct page *pg);
+void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
 
 /*
  * These are used to make use of C type-checking..
diff --git a/include/asm-parisc/param.h b/include/asm-parisc/param.h
index 07cb9b9..32e03d8 100644
--- a/include/asm-parisc/param.h
+++ b/include/asm-parisc/param.h
@@ -2,13 +2,9 @@
 #define _ASMPARISC_PARAM_H
 
 #ifdef __KERNEL__
-# ifdef CONFIG_PA20
-#  define HZ		1000		/* Faster machines */
-# else
-#  define HZ		100		/* Internal kernel timer frequency */
-# endif
-# define USER_HZ	100		/* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
+#define HZ		CONFIG_HZ
+#define USER_HZ		100		/* some user API use "ticks" */
+#define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
 #endif
 
 #ifndef HZ
diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
index 1d247e3..e12624d 100644
--- a/include/asm-parisc/parisc-device.h
+++ b/include/asm-parisc/parisc-device.h
@@ -1,3 +1,6 @@
+#ifndef _ASM_PARISC_PARISC_DEVICE_H_
+#define _ASM_PARISC_PARISC_DEVICE_H_
+
 #include <linux/device.h>
 
 struct parisc_device {
@@ -57,3 +60,5 @@
 }
 
 extern struct bus_type parisc_bus_type;
+
+#endif /*_ASM_PARISC_PARISC_DEVICE_H_*/
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 8b631f4..7b8ad11 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -293,4 +293,9 @@
 	/* We don't need to penalize isa irq's */
 }
 
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+	return channel ? 15 : 14;
+}
+
 #endif /* __ASM_PARISC_PCI_H */
diff --git a/include/asm-parisc/prefetch.h b/include/asm-parisc/prefetch.h
new file mode 100644
index 0000000..5d02172
--- /dev/null
+++ b/include/asm-parisc/prefetch.h
@@ -0,0 +1,39 @@
+/*
+ * include/asm-parisc/prefetch.h
+ *
+ * PA 2.0 defines data prefetch instructions on page 6-11 of the Kane book.
+ * In addition, many implementations do hardware prefetching of both
+ * instructions and data.
+ *
+ * PA7300LC (page 14-4 of the ERS) also implements prefetching by a load
+ * to gr0 but not in a way that Linux can use.  If the load would cause an
+ * interruption (eg due to prefetching 0), it is suppressed on PA2.0
+ * processors, but not on 7300LC.
+ *
+ */
+
+#ifndef __ASM_PARISC_PREFETCH_H
+#define __ASM_PARISC_PREFETCH_H
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_PREFETCH
+
+#define ARCH_HAS_PREFETCH
+extern inline void prefetch(const void *addr)
+{
+	__asm__("ldw 0(%0), %%r0" : : "r" (addr));
+}
+
+/* LDD is a PA2.0 addition. */
+#ifdef CONFIG_PA20
+#define ARCH_HAS_PREFETCHW
+extern inline void prefetchw(const void *addr)
+{
+	__asm__("ldd 0(%0), %%r0" : : "r" (addr));
+}
+#endif /* CONFIG_PA20 */
+
+#endif /* CONFIG_PREFETCH */
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_PARISC_PROCESSOR_H */
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index b73626f..fd7866d 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -9,6 +9,8 @@
 #define __ASM_PARISC_PROCESSOR_H
 
 #ifndef __ASSEMBLY__
+#include <asm/prefetch.h>	/* lockdep.h needs <linux/prefetch.h> */
+
 #include <linux/threads.h>
 #include <linux/spinlock_types.h>
 
@@ -276,7 +278,7 @@
  */
 
 #ifdef __LP64__
-#define USER_WIDE_MODE	(personality(current->personality) == PER_LINUX)
+#define USER_WIDE_MODE	(!test_thread_flag(TIF_32BIT))
 #else
 #define USER_WIDE_MODE	0
 #endif
@@ -328,34 +330,21 @@
 #define KSTK_EIP(tsk)	((tsk)->thread.regs.iaoq[0])
 #define KSTK_ESP(tsk)	((tsk)->thread.regs.gr[30])
 
-
-/*
- * PA 2.0 defines data prefetch instructions on page 6-11 of the Kane book.
- * In addition, many implementations do hardware prefetching of both
- * instructions and data.
- *
- * PA7300LC (page 14-4 of the ERS) also implements prefetching by a load
- * to gr0 but not in a way that Linux can use.  If the load would cause an
- * interruption (eg due to prefetching 0), it is suppressed on PA2.0
- * processors, but not on 7300LC.
- */
-#ifdef  CONFIG_PREFETCH
-#define ARCH_HAS_PREFETCH
-#define ARCH_HAS_PREFETCHW
-
-extern inline void prefetch(const void *addr)
-{
-	__asm__("ldw 0(%0), %%r0" : : "r" (addr));
-}
-
-extern inline void prefetchw(const void *addr)
-{
-	__asm__("ldd 0(%0), %%r0" : : "r" (addr));
-}
-#endif
-
 #define cpu_relax()	barrier()
 
+/* Used as a macro to identify the combined VIPT/PIPT cached
+ * CPUs which require a guarantee of coherency (no inequivalent
+ * aliases with different data, whether clean or not) to operate */
+static inline int parisc_requires_coherency(void)
+{
+#ifdef CONFIG_PA8X00
+	/* FIXME: also pa8900 - when we see one */
+	return boot_cpu_data.cpu_type == mako;
+#else
+	return 0;
+#endif
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_PARISC_PROCESSOR_H */
diff --git a/include/asm-parisc/ropes.h b/include/asm-parisc/ropes.h
new file mode 100644
index 0000000..5542dd0
--- /dev/null
+++ b/include/asm-parisc/ropes.h
@@ -0,0 +1,322 @@
+#ifndef _ASM_PARISC_ROPES_H_
+#define _ASM_PARISC_ROPES_H_
+
+#include <asm-parisc/parisc-device.h>
+
+#ifdef CONFIG_64BIT
+/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
+#define ZX1_SUPPORT
+#endif
+
+#ifdef CONFIG_PROC_FS
+/* depends on proc fs support. But costs CPU performance */
+#undef SBA_COLLECT_STATS
+#endif
+
+/*
+** The number of pdir entries to "free" before issueing
+** a read to PCOM register to flush out PCOM writes.
+** Interacts with allocation granularity (ie 4 or 8 entries
+** allocated and free'd/purged at a time might make this
+** less interesting).
+*/
+#define DELAYED_RESOURCE_CNT	16
+
+#define MAX_IOC		2	/* per Ike. Pluto/Astro only have 1. */
+#define ROPES_PER_IOC	8	/* per Ike half or Pluto/Astro */
+
+struct ioc {
+	void __iomem	*ioc_hpa;	/* I/O MMU base address */
+	char		*res_map;	/* resource map, bit == pdir entry */
+	u64		*pdir_base;	/* physical base address */
+	unsigned long	ibase;		/* pdir IOV Space base - shared w/lba_pci */
+	unsigned long	imask;		/* pdir IOV Space mask - shared w/lba_pci */
+#ifdef ZX1_SUPPORT
+	unsigned long	iovp_mask;	/* help convert IOVA to IOVP */
+#endif
+	unsigned long	*res_hint;	/* next avail IOVP - circular search */
+	spinlock_t	res_lock;
+	unsigned int	res_bitshift;	/* from the LEFT! */
+	unsigned int	res_size;	/* size of resource map in bytes */
+#ifdef SBA_HINT_SUPPORT
+/* FIXME : DMA HINTs not used */
+	unsigned long	hint_mask_pdir; /* bits used for DMA hints */
+	unsigned int	hint_shift_pdir;
+#endif
+#if DELAYED_RESOURCE_CNT > 0
+	int		saved_cnt;
+	struct sba_dma_pair {
+			dma_addr_t	iova;
+			size_t		size;
+        } saved[DELAYED_RESOURCE_CNT];
+#endif
+
+#ifdef SBA_COLLECT_STATS
+#define SBA_SEARCH_SAMPLE	0x100
+	unsigned long	avg_search[SBA_SEARCH_SAMPLE];
+	unsigned long	avg_idx;	/* current index into avg_search */
+	unsigned long	used_pages;
+	unsigned long	msingle_calls;
+	unsigned long	msingle_pages;
+	unsigned long	msg_calls;
+	unsigned long	msg_pages;
+	unsigned long	usingle_calls;
+	unsigned long	usingle_pages;
+	unsigned long	usg_calls;
+	unsigned long	usg_pages;
+#endif
+        /* STUFF We don't need in performance path */
+	unsigned int	pdir_size;	/* in bytes, determined by IOV Space size */
+};
+
+struct sba_device {
+	struct sba_device	*next;  /* list of SBA's in system */
+	struct parisc_device	*dev;   /* dev found in bus walk */
+	const char		*name;
+	void __iomem		*sba_hpa; /* base address */
+	spinlock_t		sba_lock;
+	unsigned int		flags;  /* state/functionality enabled */
+	unsigned int		hw_rev;  /* HW revision of chip */
+
+	struct resource		chip_resv; /* MMIO reserved for chip */
+	struct resource		iommu_resv; /* MMIO reserved for iommu */
+
+	unsigned int		num_ioc;  /* number of on-board IOC's */
+	struct ioc		ioc[MAX_IOC];
+};
+
+#define ASTRO_RUNWAY_PORT	0x582
+#define IKE_MERCED_PORT		0x803
+#define REO_MERCED_PORT		0x804
+#define REOG_MERCED_PORT	0x805
+#define PLUTO_MCKINLEY_PORT	0x880
+
+static inline int IS_ASTRO(struct parisc_device *d) {
+	return d->id.hversion == ASTRO_RUNWAY_PORT;
+}
+
+static inline int IS_IKE(struct parisc_device *d) {
+	return d->id.hversion == IKE_MERCED_PORT;
+}
+
+static inline int IS_PLUTO(struct parisc_device *d) {
+	return d->id.hversion == PLUTO_MCKINLEY_PORT;
+}
+
+#define PLUTO_IOVA_BASE	(1UL*1024*1024*1024)	/* 1GB */
+#define PLUTO_IOVA_SIZE	(1UL*1024*1024*1024)	/* 1GB */
+#define PLUTO_GART_SIZE	(PLUTO_IOVA_SIZE / 2)
+
+#define SBA_PDIR_VALID_BIT	0x8000000000000000ULL
+
+#define SBA_AGPGART_COOKIE	0x0000badbadc0ffeeULL
+
+#define SBA_FUNC_ID	0x0000	/* function id */
+#define SBA_FCLASS	0x0008	/* function class, bist, header, rev... */
+
+#define SBA_FUNC_SIZE 4096   /* SBA configuration function reg set */
+
+#define ASTRO_IOC_OFFSET	(32 * SBA_FUNC_SIZE)
+#define PLUTO_IOC_OFFSET	(1 * SBA_FUNC_SIZE)
+/* Ike's IOC's occupy functions 2 and 3 */
+#define IKE_IOC_OFFSET(p)	((p+2) * SBA_FUNC_SIZE)
+
+#define IOC_CTRL          0x8	/* IOC_CTRL offset */
+#define IOC_CTRL_TC       (1 << 0) /* TOC Enable */
+#define IOC_CTRL_CE       (1 << 1) /* Coalesce Enable */
+#define IOC_CTRL_DE       (1 << 2) /* Dillon Enable */
+#define IOC_CTRL_RM       (1 << 8) /* Real Mode */
+#define IOC_CTRL_NC       (1 << 9) /* Non Coherent Mode */
+#define IOC_CTRL_D4       (1 << 11) /* Disable 4-byte coalescing */
+#define IOC_CTRL_DD       (1 << 13) /* Disable distr. LMMIO range coalescing */
+
+/*
+** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
+** Firmware programs this stuff. Don't touch it.
+*/
+#define LMMIO_DIRECT0_BASE  0x300
+#define LMMIO_DIRECT0_MASK  0x308
+#define LMMIO_DIRECT0_ROUTE 0x310
+
+#define LMMIO_DIST_BASE  0x360
+#define LMMIO_DIST_MASK  0x368
+#define LMMIO_DIST_ROUTE 0x370
+
+#define IOS_DIST_BASE	0x390
+#define IOS_DIST_MASK	0x398
+#define IOS_DIST_ROUTE	0x3A0
+
+#define IOS_DIRECT_BASE	0x3C0
+#define IOS_DIRECT_MASK	0x3C8
+#define IOS_DIRECT_ROUTE 0x3D0
+
+/*
+** Offsets into I/O TLB (Function 2 and 3 on Ike)
+*/
+#define ROPE0_CTL	0x200  /* "regbus pci0" */
+#define ROPE1_CTL	0x208
+#define ROPE2_CTL	0x210
+#define ROPE3_CTL	0x218
+#define ROPE4_CTL	0x220
+#define ROPE5_CTL	0x228
+#define ROPE6_CTL	0x230
+#define ROPE7_CTL	0x238
+
+#define IOC_ROPE0_CFG	0x500	/* pluto only */
+#define   IOC_ROPE_AO	  0x10	/* Allow "Relaxed Ordering" */
+
+#define HF_ENABLE	0x40
+
+#define IOC_IBASE	0x300	/* IO TLB */
+#define IOC_IMASK	0x308
+#define IOC_PCOM	0x310
+#define IOC_TCNFG	0x318
+#define IOC_PDIR_BASE	0x320
+
+/*
+** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
+** It's safer (avoid memory corruption) to keep DMA page mappings
+** equivalently sized to VM PAGE_SIZE.
+**
+** We really can't avoid generating a new mapping for each
+** page since the Virtual Coherence Index has to be generated
+** and updated for each page.
+**
+** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
+*/
+#define IOVP_SIZE	PAGE_SIZE
+#define IOVP_SHIFT	PAGE_SHIFT
+#define IOVP_MASK	PAGE_MASK
+
+#define SBA_PERF_CFG	0x708	/* Performance Counter stuff */
+#define SBA_PERF_MASK1	0x718
+#define SBA_PERF_MASK2	0x730
+
+/*
+** Offsets into PCI Performance Counters (functions 12 and 13)
+** Controlled by PERF registers in function 2 & 3 respectively.
+*/
+#define SBA_PERF_CNT1	0x200
+#define SBA_PERF_CNT2	0x208
+#define SBA_PERF_CNT3	0x210
+
+/*
+** lba_device: Per instance Elroy data structure
+*/
+struct lba_device {
+	struct pci_hba_data	hba;
+
+	spinlock_t		lba_lock;
+	void			*iosapic_obj;
+
+#ifdef CONFIG_64BIT
+	void __iomem		*iop_base;	/* PA_VIEW - for IO port accessor funcs */
+#endif
+
+	int			flags;		/* state/functionality enabled */
+	int			hw_rev;		/* HW revision of chip */
+};
+
+#define ELROY_HVERS		0x782
+#define MERCURY_HVERS		0x783
+#define QUICKSILVER_HVERS	0x784
+
+static inline int IS_ELROY(struct parisc_device *d) {
+	return (d->id.hversion == ELROY_HVERS);
+}
+
+static inline int IS_MERCURY(struct parisc_device *d) {
+	return (d->id.hversion == MERCURY_HVERS);
+}
+
+static inline int IS_QUICKSILVER(struct parisc_device *d) {
+	return (d->id.hversion == QUICKSILVER_HVERS);
+}
+
+static inline int agp_mode_mercury(void __iomem *hpa) {
+	u64 bus_mode;
+
+	bus_mode = readl(hpa + 0x0620);
+	if (bus_mode & 1)
+		return 1;
+
+	return 0;
+}
+
+/*
+** I/O SAPIC init function
+** Caller knows where an I/O SAPIC is. LBA has an integrated I/O SAPIC.
+** Call setup as part of per instance initialization.
+** (ie *not* init_module() function unless only one is present.)
+** fixup_irq is to initialize PCI IRQ line support and
+** virtualize pcidev->irq value. To be called by pci_fixup_bus().
+*/
+extern void *iosapic_register(unsigned long hpa);
+extern int iosapic_fixup_irq(void *obj, struct pci_dev *pcidev);
+
+#define LBA_FUNC_ID	0x0000	/* function id */
+#define LBA_FCLASS	0x0008	/* function class, bist, header, rev... */
+#define LBA_CAPABLE	0x0030	/* capabilities register */
+
+#define LBA_PCI_CFG_ADDR	0x0040	/* poke CFG address here */
+#define LBA_PCI_CFG_DATA	0x0048	/* read or write data here */
+
+#define LBA_PMC_MTLT	0x0050	/* Firmware sets this - read only. */
+#define LBA_FW_SCRATCH	0x0058	/* Firmware writes the PCI bus number here. */
+#define LBA_ERROR_ADDR	0x0070	/* On error, address gets logged here */
+
+#define LBA_ARB_MASK	0x0080	/* bit 0 enable arbitration. PAT/PDC enables */
+#define LBA_ARB_PRI	0x0088	/* firmware sets this. */
+#define LBA_ARB_MODE	0x0090	/* firmware sets this. */
+#define LBA_ARB_MTLT	0x0098	/* firmware sets this. */
+
+#define LBA_MOD_ID	0x0100	/* Module ID. PDC_PAT_CELL reports 4 */
+
+#define LBA_STAT_CTL	0x0108	/* Status & Control */
+#define   LBA_BUS_RESET		0x01	/*  Deassert PCI Bus Reset Signal */
+#define   CLEAR_ERRLOG		0x10	/*  "Clear Error Log" cmd */
+#define   CLEAR_ERRLOG_ENABLE	0x20	/*  "Clear Error Log" Enable */
+#define   HF_ENABLE	0x40	/*    enable HF mode (default is -1 mode) */
+
+#define LBA_LMMIO_BASE	0x0200	/* < 4GB I/O address range */
+#define LBA_LMMIO_MASK	0x0208
+
+#define LBA_GMMIO_BASE	0x0210	/* > 4GB I/O address range */
+#define LBA_GMMIO_MASK	0x0218
+
+#define LBA_WLMMIO_BASE	0x0220	/* All < 4GB ranges under the same *SBA* */
+#define LBA_WLMMIO_MASK	0x0228
+
+#define LBA_WGMMIO_BASE	0x0230	/* All > 4GB ranges under the same *SBA* */
+#define LBA_WGMMIO_MASK	0x0238
+
+#define LBA_IOS_BASE	0x0240	/* I/O port space for this LBA */
+#define LBA_IOS_MASK	0x0248
+
+#define LBA_ELMMIO_BASE	0x0250	/* Extra LMMIO range */
+#define LBA_ELMMIO_MASK	0x0258
+
+#define LBA_EIOS_BASE	0x0260	/* Extra I/O port space */
+#define LBA_EIOS_MASK	0x0268
+
+#define LBA_GLOBAL_MASK	0x0270	/* Mercury only: Global Address Mask */
+#define LBA_DMA_CTL	0x0278	/* firmware sets this */
+
+#define LBA_IBASE	0x0300	/* SBA DMA support */
+#define LBA_IMASK	0x0308
+
+/* FIXME: ignore DMA Hint stuff until we can measure performance */
+#define LBA_HINT_CFG	0x0310
+#define LBA_HINT_BASE	0x0380	/* 14 registers at every 8 bytes. */
+
+#define LBA_BUS_MODE	0x0620
+
+/* ERROR regs are needed for config cycle kluges */
+#define LBA_ERROR_CONFIG 0x0680
+#define     LBA_SMART_MODE 0x20
+#define LBA_ERROR_STATUS 0x0688
+#define LBA_ROPE_CTL     0x06A0
+
+#define LBA_IOSAPIC_BASE	0x800 /* Offset of IRQ logic */
+
+#endif /*_ASM_PARISC_ROPES_H_*/
diff --git a/include/asm-parisc/rtc.h b/include/asm-parisc/rtc.h
index f3d3d6b..f4ebff1 100644
--- a/include/asm-parisc/rtc.h
+++ b/include/asm-parisc/rtc.h
@@ -1,5 +1,5 @@
 /* 
- * inclue/asm-parisc/rtc.h
+ * include/asm-parisc/rtc.h
  *
  * Copyright 2002 Randolph CHung <tausq@debian.org>
  *
diff --git a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h
index 82fd820..d7e3cc6 100644
--- a/include/asm-parisc/serial.h
+++ b/include/asm-parisc/serial.h
@@ -3,20 +3,8 @@
  */
 
 /*
- * This assumes you have a 7.272727 MHz clock for your UART.
- * The documentation implies a 40Mhz clock, and elsewhere a 7Mhz clock
- * Clarified: 7.2727MHz on LASI. Not yet clarified for DINO
+ * This is used for 16550-compatible UARTs
  */
+#define BASE_BAUD ( 1843200 / 16 )
 
-#define LASI_BASE_BAUD ( 7272727 / 16 )
-#define BASE_BAUD  LASI_BASE_BAUD
-
-/*
- * We don't use the ISA probing code, so these entries are just to reserve
- * space.  Some example (maximal) configurations:
- * - 712 w/ additional Lasi & RJ16 ports: 4
- * - J5k w/ PCI serial cards: 2 + 4 * card ~= 34
- * A500 w/ PCI serial cards: 5 + 4 * card ~= 17
- */
- 
 #define SERIAL_PORT_DFNS
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index e182553..f3d2090 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -56,50 +56,79 @@
 }
 
 /*
- * Read-write spinlocks, allowing multiple readers
- * but only one writer.
+ * Read-write spinlocks, allowing multiple readers but only one writer.
+ * Linux rwlocks are unfair to writers; they can be starved for an indefinite
+ * time by readers.  With care, they can also be taken in interrupt context.
+ *
+ * In the PA-RISC implementation, we have a spinlock and a counter.
+ * Readers use the lock to serialise their access to the counter (which
+ * records how many readers currently hold the lock).
+ * Writers hold the spinlock, preventing any readers or other writers from
+ * grabbing the rwlock.
  */
 
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
-
-/* read_lock, read_unlock are pretty straightforward.  Of course it somehow
- * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
-
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to grab the same read lock */
 static  __inline__ void __raw_read_lock(raw_rwlock_t *rw)
 {
-	__raw_spin_lock(&rw->lock);
-
+	unsigned long flags;
+	local_irq_save(flags);
+	__raw_spin_lock_flags(&rw->lock, flags);
 	rw->counter++;
-
 	__raw_spin_unlock(&rw->lock);
+	local_irq_restore(flags);
 }
 
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to grab the same read lock */
 static  __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
 {
-	__raw_spin_lock(&rw->lock);
-
+	unsigned long flags;
+	local_irq_save(flags);
+	__raw_spin_lock_flags(&rw->lock, flags);
 	rw->counter--;
-
 	__raw_spin_unlock(&rw->lock);
+	local_irq_restore(flags);
 }
 
-/* write_lock is less trivial.  We optimistically grab the lock and check
- * if we surprised any readers.  If so we release the lock and wait till
- * they're all gone before trying again
- *
- * Also note that we don't use the _irqsave / _irqrestore suffixes here.
- * If we're called with interrupts enabled and we've got readers (or other
- * writers) in interrupt handlers someone fucked up and we'd dead-lock
- * sooner or later anyway.   prumpf */
-
-static  __inline__ void __raw_write_lock(raw_rwlock_t *rw)
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to grab the same read lock */
+static __inline__ int __raw_read_trylock(raw_rwlock_t *rw)
 {
-retry:
-	__raw_spin_lock(&rw->lock);
-
-	if(rw->counter != 0) {
-		/* this basically never happens */
+	unsigned long flags;
+ retry:
+	local_irq_save(flags);
+	if (__raw_spin_trylock(&rw->lock)) {
+		rw->counter++;
 		__raw_spin_unlock(&rw->lock);
+		local_irq_restore(flags);
+		return 1;
+	}
+
+	local_irq_restore(flags);
+	/* If write-locked, we fail to acquire the lock */
+	if (rw->counter < 0)
+		return 0;
+
+	/* Wait until we have a realistic chance at the lock */
+	while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0)
+		cpu_relax();
+
+	goto retry;
+}
+
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to read_trylock() this lock */
+static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
+{
+	unsigned long flags;
+retry:
+	local_irq_save(flags);
+	__raw_spin_lock_flags(&rw->lock, flags);
+
+	if (rw->counter != 0) {
+		__raw_spin_unlock(&rw->lock);
+		local_irq_restore(flags);
 
 		while (rw->counter != 0)
 			cpu_relax();
@@ -107,31 +136,37 @@
 		goto retry;
 	}
 
-	/* got it.  now leave without unlocking */
-	rw->counter = -1; /* remember we are locked */
+	rw->counter = -1; /* mark as write-locked */
+	mb();
+	local_irq_restore(flags);
 }
 
-/* write_unlock is absolutely trivial - we don't have to wait for anything */
-
-static  __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
+static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
 {
 	rw->counter = 0;
 	__raw_spin_unlock(&rw->lock);
 }
 
-static  __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to read_trylock() this lock */
+static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
 {
-	__raw_spin_lock(&rw->lock);
-	if (rw->counter != 0) {
-		/* this basically never happens */
-		__raw_spin_unlock(&rw->lock);
+	unsigned long flags;
+	int result = 0;
 
-		return 0;
+	local_irq_save(flags);
+	if (__raw_spin_trylock(&rw->lock)) {
+		if (rw->counter == 0) {
+			rw->counter = -1;
+			result = 1;
+		} else {
+			/* Read-locked.  Oh well. */
+			__raw_spin_unlock(&rw->lock);
+		}
 	}
+	local_irq_restore(flags);
 
-	/* got it.  now leave without unlocking */
-	rw->counter = -1; /* remember we are locked */
-	return 1;
+	return result;
 }
 
 /*
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index 27bcfad..53b0f5d 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -952,92 +952,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-/* mmap & mmap2 take 6 arguments */
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
-{									        \
-    return K_INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6);	\
-}
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <asm/current.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-static inline pid_t setsid(void)
-{
-	return sys_setsid();
-}
-
-static inline int write(int fd, const char *buf, off_t count)
-{
-	return sys_write(fd, buf, count);
-}
-
-static inline int read(int fd, char *buf, off_t count)
-{
-	return sys_read(fd, buf, count);
-}
-
-static inline off_t lseek(int fd, off_t offset, int count)
-{
-	return sys_lseek(fd, offset, count);
-}
-
-static inline int dup(int fd)
-{
-	return sys_dup(fd);
-}
-
-static inline int execve(char *filename, char * argv [],
-	char * envp[])
-{
-	extern int __execve(char *, char **, char **, struct task_struct *);
-	return __execve(filename, argv, envp, current);
-}
-
-static inline int open(const char *file, int flag, int mode)
-{
-	return sys_open(file, flag, mode);
-}
-
-static inline int close(int fd)
-{
-	return sys_close(fd);
-}
-
-static inline void _exit(int exitcode)
-{
-	sys_exit(exitcode);
-}
-
-static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
-{
-	return sys_wait4(pid, wait_stat, options, NULL);
-}
-
-asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
-				unsigned long prot, unsigned long flags,
-				unsigned long fd, unsigned long offset);
-asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
-				unsigned long prot, unsigned long flags,
-				unsigned long fd, unsigned long pgoff);
-struct pt_regs;
-asmlinkage int sys_execve(struct pt_regs *regs);
-int sys_clone(unsigned long clone_flags, unsigned long usp,
-		struct pt_regs *regs);
-int sys_vfork(struct pt_regs *regs);
-int sys_pipe(int *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif	/* __KERNEL_SYSCALLS__ */
-
 #endif /* __ASSEMBLY__ */
 
 #undef STR
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index 77069df..1022737 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -14,34 +14,36 @@
 
 #ifdef __KERNEL__
 
-#ifndef __ASSEMBLY__
+#include <asm/asm-compat.h>
 
 /* firmware feature bitmask values */
 #define FIRMWARE_MAX_FEATURES 63
 
-#define FW_FEATURE_PFT		(1UL<<0)
-#define FW_FEATURE_TCE		(1UL<<1)
-#define FW_FEATURE_SPRG0	(1UL<<2)
-#define FW_FEATURE_DABR		(1UL<<3)
-#define FW_FEATURE_COPY		(1UL<<4)
-#define FW_FEATURE_ASR		(1UL<<5)
-#define FW_FEATURE_DEBUG	(1UL<<6)
-#define FW_FEATURE_TERM		(1UL<<7)
-#define FW_FEATURE_PERF		(1UL<<8)
-#define FW_FEATURE_DUMP		(1UL<<9)
-#define FW_FEATURE_INTERRUPT	(1UL<<10)
-#define FW_FEATURE_MIGRATE	(1UL<<11)
-#define FW_FEATURE_PERFMON	(1UL<<12)
-#define FW_FEATURE_CRQ		(1UL<<13)
-#define FW_FEATURE_VIO		(1UL<<14)
-#define FW_FEATURE_RDMA		(1UL<<15)
-#define FW_FEATURE_LLAN		(1UL<<16)
-#define FW_FEATURE_BULK		(1UL<<17)
-#define FW_FEATURE_XDABR	(1UL<<18)
-#define FW_FEATURE_MULTITCE	(1UL<<19)
-#define FW_FEATURE_SPLPAR	(1UL<<20)
-#define FW_FEATURE_ISERIES	(1UL<<21)
-#define FW_FEATURE_LPAR		(1UL<<22)
+#define FW_FEATURE_PFT		ASM_CONST(0x0000000000000001)
+#define FW_FEATURE_TCE		ASM_CONST(0x0000000000000002)
+#define FW_FEATURE_SPRG0	ASM_CONST(0x0000000000000004)
+#define FW_FEATURE_DABR		ASM_CONST(0x0000000000000008)
+#define FW_FEATURE_COPY		ASM_CONST(0x0000000000000010)
+#define FW_FEATURE_ASR		ASM_CONST(0x0000000000000020)
+#define FW_FEATURE_DEBUG	ASM_CONST(0x0000000000000040)
+#define FW_FEATURE_TERM		ASM_CONST(0x0000000000000080)
+#define FW_FEATURE_PERF		ASM_CONST(0x0000000000000100)
+#define FW_FEATURE_DUMP		ASM_CONST(0x0000000000000200)
+#define FW_FEATURE_INTERRUPT	ASM_CONST(0x0000000000000400)
+#define FW_FEATURE_MIGRATE	ASM_CONST(0x0000000000000800)
+#define FW_FEATURE_PERFMON	ASM_CONST(0x0000000000001000)
+#define FW_FEATURE_CRQ		ASM_CONST(0x0000000000002000)
+#define FW_FEATURE_VIO		ASM_CONST(0x0000000000004000)
+#define FW_FEATURE_RDMA		ASM_CONST(0x0000000000008000)
+#define FW_FEATURE_LLAN		ASM_CONST(0x0000000000010000)
+#define FW_FEATURE_BULK		ASM_CONST(0x0000000000020000)
+#define FW_FEATURE_XDABR	ASM_CONST(0x0000000000040000)
+#define FW_FEATURE_MULTITCE	ASM_CONST(0x0000000000080000)
+#define FW_FEATURE_SPLPAR	ASM_CONST(0x0000000000100000)
+#define FW_FEATURE_ISERIES	ASM_CONST(0x0000000000200000)
+#define FW_FEATURE_LPAR		ASM_CONST(0x0000000000400000)
+
+#ifndef __ASSEMBLY__
 
 enum {
 #ifdef CONFIG_PPC64
@@ -94,6 +96,23 @@
 /* This is true if we are using the firmware NMI handler (typically LPAR) */
 extern int fwnmi_active;
 
+#else /* __ASSEMBLY__ */
+
+#define BEGIN_FW_FTR_SECTION		96:
+
+#define END_FW_FTR_SECTION(msk, val)		\
+97:						\
+	.section __fw_ftr_fixup,"a";		\
+	.align 3;				\
+	.llong msk;				\
+	.llong val;				\
+	.llong 96b;				\
+	.llong 97b;				\
+	.previous
+
+#define END_FW_FTR_SECTION_IFSET(msk)	END_FW_FTR_SECTION((msk), (msk))
+#define END_FW_FTR_SECTION_IFCLR(msk)	END_FW_FTR_SECTION((msk), 0)
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_FIRMWARE_H */
diff --git a/include/asm-powerpc/fs_pd.h b/include/asm-powerpc/fs_pd.h
new file mode 100644
index 0000000..3d0e819
--- /dev/null
+++ b/include/asm-powerpc/fs_pd.h
@@ -0,0 +1,45 @@
+/*
+ * Platform information definitions.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.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.
+ */
+
+#ifndef FS_PD_H
+#define FS_PD_H
+#include <asm/cpm2.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/time.h>
+
+static inline int uart_baudrate(void)
+{
+        return get_baudrate();
+}
+
+static inline int uart_clock(void)
+{
+        return ppc_proc_freq;
+}
+
+#define cpm2_map(member)						\
+({									\
+	u32 offset = offsetof(cpm2_map_t, member);			\
+	void *addr = ioremap (CPM_MAP_ADDR + offset,			\
+			      sizeof( ((cpm2_map_t*)0)->member));	\
+	addr;								\
+})
+
+#define cpm2_map_size(member, size)					\
+({									\
+	u32 offset = offsetof(cpm2_map_t, member);			\
+	void *addr = ioremap (CPM_MAP_ADDR + offset, size);		\
+	addr;								\
+})
+
+#define cpm2_unmap(addr)	iounmap(addr)
+
+#endif
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h
new file mode 100644
index 0000000..ce12f85
--- /dev/null
+++ b/include/asm-powerpc/immap_qe.h
@@ -0,0 +1,477 @@
+/*
+ * include/asm-powerpc/immap_qe.h
+ *
+ * QUICC Engine (QE) Internal Memory Map.
+ * The Internal Memory Map for devices with QE on them. This
+ * is the superset of all QE devices (8360, etc.).
+
+ * Copyright (C) 2006. Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.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 _ASM_POWERPC_IMMAP_QE_H
+#define _ASM_POWERPC_IMMAP_QE_H
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+
+#define QE_IMMAP_SIZE	(1024 * 1024)	/* 1MB from 1MB+IMMR */
+
+/* QE I-RAM */
+struct qe_iram {
+	__be32	iadd;		/* I-RAM Address Register */
+	__be32	idata;		/* I-RAM Data Register */
+	u8	res0[0x78];
+} __attribute__ ((packed));
+
+/* QE Interrupt Controller */
+struct qe_ic_regs {
+	__be32	qicr;
+	__be32	qivec;
+	__be32	qripnr;
+	__be32	qipnr;
+	__be32	qipxcc;
+	__be32	qipycc;
+	__be32	qipwcc;
+	__be32	qipzcc;
+	__be32	qimr;
+	__be32	qrimr;
+	__be32	qicnr;
+	u8	res0[0x4];
+	__be32	qiprta;
+	__be32	qiprtb;
+	u8	res1[0x4];
+	__be32	qricr;
+	u8	res2[0x20];
+	__be32	qhivec;
+	u8	res3[0x1C];
+} __attribute__ ((packed));
+
+/* Communications Processor */
+struct cp_qe {
+	__be32	cecr;		/* QE command register */
+	__be32	ceccr;		/* QE controller configuration register */
+	__be32	cecdr;		/* QE command data register */
+	u8	res0[0xA];
+	__be16	ceter;		/* QE timer event register */
+	u8	res1[0x2];
+	__be16	cetmr;		/* QE timers mask register */
+	__be32	cetscr;		/* QE time-stamp timer control register */
+	__be32	cetsr1;		/* QE time-stamp register 1 */
+	__be32	cetsr2;		/* QE time-stamp register 2 */
+	u8	res2[0x8];
+	__be32	cevter;		/* QE virtual tasks event register */
+	__be32	cevtmr;		/* QE virtual tasks mask register */
+	__be16	cercr;		/* QE RAM control register */
+	u8	res3[0x2];
+	u8	res4[0x24];
+	__be16	ceexe1;		/* QE external request 1 event register */
+	u8	res5[0x2];
+	__be16	ceexm1;		/* QE external request 1 mask register */
+	u8	res6[0x2];
+	__be16	ceexe2;		/* QE external request 2 event register */
+	u8	res7[0x2];
+	__be16	ceexm2;		/* QE external request 2 mask register */
+	u8	res8[0x2];
+	__be16	ceexe3;		/* QE external request 3 event register */
+	u8	res9[0x2];
+	__be16	ceexm3;		/* QE external request 3 mask register */
+	u8	res10[0x2];
+	__be16	ceexe4;		/* QE external request 4 event register */
+	u8	res11[0x2];
+	__be16	ceexm4;		/* QE external request 4 mask register */
+	u8	res12[0x2];
+	u8	res13[0x280];
+} __attribute__ ((packed));
+
+/* QE Multiplexer */
+struct qe_mux {
+	__be32	cmxgcr;		/* CMX general clock route register */
+	__be32	cmxsi1cr_l;	/* CMX SI1 clock route low register */
+	__be32	cmxsi1cr_h;	/* CMX SI1 clock route high register */
+	__be32	cmxsi1syr;	/* CMX SI1 SYNC route register */
+	__be32	cmxucr1;	/* CMX UCC1, UCC3 clock route register */
+	__be32	cmxucr2;	/* CMX UCC5, UCC7 clock route register */
+	__be32	cmxucr3;	/* CMX UCC2, UCC4 clock route register */
+	__be32	cmxucr4;	/* CMX UCC6, UCC8 clock route register */
+	__be32	cmxupcr;	/* CMX UPC clock route register */
+	u8	res0[0x1C];
+} __attribute__ ((packed));
+
+/* QE Timers */
+struct qe_timers {
+	u8	gtcfr1;		/* Timer 1 and Timer 2 global config register*/
+	u8	res0[0x3];
+	u8	gtcfr2;		/* Timer 3 and timer 4 global config register*/
+	u8	res1[0xB];
+	__be16	gtmdr1;		/* Timer 1 mode register */
+	__be16	gtmdr2;		/* Timer 2 mode register */
+	__be16	gtrfr1;		/* Timer 1 reference register */
+	__be16	gtrfr2;		/* Timer 2 reference register */
+	__be16	gtcpr1;		/* Timer 1 capture register */
+	__be16	gtcpr2;		/* Timer 2 capture register */
+	__be16	gtcnr1;		/* Timer 1 counter */
+	__be16	gtcnr2;		/* Timer 2 counter */
+	__be16	gtmdr3;		/* Timer 3 mode register */
+	__be16	gtmdr4;		/* Timer 4 mode register */
+	__be16	gtrfr3;		/* Timer 3 reference register */
+	__be16	gtrfr4;		/* Timer 4 reference register */
+	__be16	gtcpr3;		/* Timer 3 capture register */
+	__be16	gtcpr4;		/* Timer 4 capture register */
+	__be16	gtcnr3;		/* Timer 3 counter */
+	__be16	gtcnr4;		/* Timer 4 counter */
+	__be16	gtevr1;		/* Timer 1 event register */
+	__be16	gtevr2;		/* Timer 2 event register */
+	__be16	gtevr3;		/* Timer 3 event register */
+	__be16	gtevr4;		/* Timer 4 event register */
+	__be16	gtps;		/* Timer 1 prescale register */
+	u8 res2[0x46];
+} __attribute__ ((packed));
+
+/* BRG */
+struct qe_brg {
+	__be32	brgc1;		/* BRG1 configuration register */
+	__be32	brgc2;		/* BRG2 configuration register */
+	__be32	brgc3;		/* BRG3 configuration register */
+	__be32	brgc4;		/* BRG4 configuration register */
+	__be32	brgc5;		/* BRG5 configuration register */
+	__be32	brgc6;		/* BRG6 configuration register */
+	__be32	brgc7;		/* BRG7 configuration register */
+	__be32	brgc8;		/* BRG8 configuration register */
+	__be32	brgc9;		/* BRG9 configuration register */
+	__be32	brgc10;		/* BRG10 configuration register */
+	__be32	brgc11;		/* BRG11 configuration register */
+	__be32	brgc12;		/* BRG12 configuration register */
+	__be32	brgc13;		/* BRG13 configuration register */
+	__be32	brgc14;		/* BRG14 configuration register */
+	__be32	brgc15;		/* BRG15 configuration register */
+	__be32	brgc16;		/* BRG16 configuration register */
+	u8	res0[0x40];
+} __attribute__ ((packed));
+
+/* SPI */
+struct spi {
+	u8	res0[0x20];
+	__be32	spmode;		/* SPI mode register */
+	u8	res1[0x2];
+	u8	spie;		/* SPI event register */
+	u8	res2[0x1];
+	u8	res3[0x2];
+	u8	spim;		/* SPI mask register */
+	u8	res4[0x1];
+	u8	res5[0x1];
+	u8	spcom;		/* SPI command register */
+	u8	res6[0x2];
+	__be32	spitd;		/* SPI transmit data register (cpu mode) */
+	__be32	spird;		/* SPI receive data register (cpu mode) */
+	u8	res7[0x8];
+} __attribute__ ((packed));
+
+/* SI */
+struct si1 {
+	__be16	siamr1;		/* SI1 TDMA mode register */
+	__be16	sibmr1;		/* SI1 TDMB mode register */
+	__be16	sicmr1;		/* SI1 TDMC mode register */
+	__be16	sidmr1;		/* SI1 TDMD mode register */
+	u8	siglmr1_h;	/* SI1 global mode register high */
+	u8	res0[0x1];
+	u8	sicmdr1_h;	/* SI1 command register high */
+	u8	res2[0x1];
+	u8	sistr1_h;	/* SI1 status register high */
+	u8	res3[0x1];
+	__be16	sirsr1_h;	/* SI1 RAM shadow address register high */
+	u8	sitarc1;	/* SI1 RAM counter Tx TDMA */
+	u8	sitbrc1;	/* SI1 RAM counter Tx TDMB */
+	u8	sitcrc1;	/* SI1 RAM counter Tx TDMC */
+	u8	sitdrc1;	/* SI1 RAM counter Tx TDMD */
+	u8	sirarc1;	/* SI1 RAM counter Rx TDMA */
+	u8	sirbrc1;	/* SI1 RAM counter Rx TDMB */
+	u8	sircrc1;	/* SI1 RAM counter Rx TDMC */
+	u8	sirdrc1;	/* SI1 RAM counter Rx TDMD */
+	u8	res4[0x8];
+	__be16	siemr1;		/* SI1 TDME mode register 16 bits */
+	__be16	sifmr1;		/* SI1 TDMF mode register 16 bits */
+	__be16	sigmr1;		/* SI1 TDMG mode register 16 bits */
+	__be16	sihmr1;		/* SI1 TDMH mode register 16 bits */
+	u8	siglmg1_l;	/* SI1 global mode register low 8 bits */
+	u8	res5[0x1];
+	u8	sicmdr1_l;	/* SI1 command register low 8 bits */
+	u8	res6[0x1];
+	u8	sistr1_l;	/* SI1 status register low 8 bits */
+	u8	res7[0x1];
+	__be16	sirsr1_l;	/* SI1 RAM shadow address register low 16 bits*/
+	u8	siterc1;	/* SI1 RAM counter Tx TDME 8 bits */
+	u8	sitfrc1;	/* SI1 RAM counter Tx TDMF 8 bits */
+	u8	sitgrc1;	/* SI1 RAM counter Tx TDMG 8 bits */
+	u8	sithrc1;	/* SI1 RAM counter Tx TDMH 8 bits */
+	u8	sirerc1;	/* SI1 RAM counter Rx TDME 8 bits */
+	u8	sirfrc1;	/* SI1 RAM counter Rx TDMF 8 bits */
+	u8	sirgrc1;	/* SI1 RAM counter Rx TDMG 8 bits */
+	u8	sirhrc1;	/* SI1 RAM counter Rx TDMH 8 bits */
+	u8	res8[0x8];
+	__be32	siml1;		/* SI1 multiframe limit register */
+	u8	siedm1;		/* SI1 extended diagnostic mode register */
+	u8	res9[0xBB];
+} __attribute__ ((packed));
+
+/* SI Routing Tables */
+struct sir {
+	u8 	tx[0x400];
+	u8	rx[0x400];
+	u8	res0[0x800];
+} __attribute__ ((packed));
+
+/* USB Controller */
+struct usb_ctlr {
+	u8	usb_usmod;
+	u8	usb_usadr;
+	u8	usb_uscom;
+	u8	res1[1];
+	__be16	usb_usep1;
+	__be16	usb_usep2;
+	__be16	usb_usep3;
+	__be16	usb_usep4;
+	u8	res2[4];
+	__be16	usb_usber;
+	u8	res3[2];
+	__be16	usb_usbmr;
+	u8	res4[1];
+	u8	usb_usbs;
+	__be16	usb_ussft;
+	u8	res5[2];
+	__be16	usb_usfrn;
+	u8	res6[0x22];
+} __attribute__ ((packed));
+
+/* MCC */
+struct mcc {
+	__be32	mcce;		/* MCC event register */
+	__be32	mccm;		/* MCC mask register */
+	__be32	mccf;		/* MCC configuration register */
+	__be32	merl;		/* MCC emergency request level register */
+	u8	res0[0xF0];
+} __attribute__ ((packed));
+
+/* QE UCC Slow */
+struct ucc_slow {
+	__be32	gumr_l;		/* UCCx general mode register (low) */
+	__be32	gumr_h;		/* UCCx general mode register (high) */
+	__be16	upsmr;		/* UCCx protocol-specific mode register */
+	u8	res0[0x2];
+	__be16	utodr;		/* UCCx transmit on demand register */
+	__be16	udsr;		/* UCCx data synchronization register */
+	__be16	ucce;		/* UCCx event register */
+	u8	res1[0x2];
+	__be16	uccm;		/* UCCx mask register */
+	u8	res2[0x1];
+	u8	uccs;		/* UCCx status register */
+	u8	res3[0x24];
+	__be16	utpt;
+	u8	guemr;		/* UCC general extended mode register */
+	u8	res4[0x200 - 0x091];
+} __attribute__ ((packed));
+
+/* QE UCC Fast */
+struct ucc_fast {
+	__be32	gumr;		/* UCCx general mode register */
+	__be32	upsmr;		/* UCCx protocol-specific mode register */
+	__be16	utodr;		/* UCCx transmit on demand register */
+	u8	res0[0x2];
+	__be16	udsr;		/* UCCx data synchronization register */
+	u8	res1[0x2];
+	__be32	ucce;		/* UCCx event register */
+	__be32	uccm;		/* UCCx mask register */
+	u8	uccs;		/* UCCx status register */
+	u8	res2[0x7];
+	__be32	urfb;		/* UCC receive FIFO base */
+	__be16	urfs;		/* UCC receive FIFO size */
+	u8	res3[0x2];
+	__be16	urfet;		/* UCC receive FIFO emergency threshold */
+	__be16	urfset;		/* UCC receive FIFO special emergency
+				   threshold */
+	__be32	utfb;		/* UCC transmit FIFO base */
+	__be16	utfs;		/* UCC transmit FIFO size */
+	u8	res4[0x2];
+	__be16	utfet;		/* UCC transmit FIFO emergency threshold */
+	u8	res5[0x2];
+	__be16	utftt;		/* UCC transmit FIFO transmit threshold */
+	u8	res6[0x2];
+	__be16	utpt;		/* UCC transmit polling timer */
+	u8	res7[0x2];
+	__be32	urtry;		/* UCC retry counter register */
+	u8	res8[0x4C];
+	u8	guemr;		/* UCC general extended mode register */
+	u8	res9[0x100 - 0x091];
+} __attribute__ ((packed));
+
+/* QE UCC */
+struct ucc_common {
+	u8	res1[0x90];
+	u8	guemr;
+	u8	res2[0x200 - 0x091];
+} __attribute__ ((packed));
+
+struct ucc {
+	union {
+		struct	ucc_slow slow;
+		struct	ucc_fast fast;
+		struct	ucc_common common;
+	};
+} __attribute__ ((packed));
+
+/* MultiPHY UTOPIA POS Controllers (UPC) */
+struct upc {
+	__be32	upgcr;		/* UTOPIA/POS general configuration register */
+	__be32	uplpa;		/* UTOPIA/POS last PHY address */
+	__be32	uphec;		/* ATM HEC register */
+	__be32	upuc;		/* UTOPIA/POS UCC configuration */
+	__be32	updc1;		/* UTOPIA/POS device 1 configuration */
+	__be32	updc2;		/* UTOPIA/POS device 2 configuration */
+	__be32	updc3;		/* UTOPIA/POS device 3 configuration */
+	__be32	updc4;		/* UTOPIA/POS device 4 configuration */
+	__be32	upstpa;		/* UTOPIA/POS STPA threshold */
+	u8	res0[0xC];
+	__be32	updrs1_h;	/* UTOPIA/POS device 1 rate select */
+	__be32	updrs1_l;	/* UTOPIA/POS device 1 rate select */
+	__be32	updrs2_h;	/* UTOPIA/POS device 2 rate select */
+	__be32	updrs2_l;	/* UTOPIA/POS device 2 rate select */
+	__be32	updrs3_h;	/* UTOPIA/POS device 3 rate select */
+	__be32	updrs3_l;	/* UTOPIA/POS device 3 rate select */
+	__be32	updrs4_h;	/* UTOPIA/POS device 4 rate select */
+	__be32	updrs4_l;	/* UTOPIA/POS device 4 rate select */
+	__be32	updrp1;		/* UTOPIA/POS device 1 receive priority low */
+	__be32	updrp2;		/* UTOPIA/POS device 2 receive priority low */
+	__be32	updrp3;		/* UTOPIA/POS device 3 receive priority low */
+	__be32	updrp4;		/* UTOPIA/POS device 4 receive priority low */
+	__be32	upde1;		/* UTOPIA/POS device 1 event */
+	__be32	upde2;		/* UTOPIA/POS device 2 event */
+	__be32	upde3;		/* UTOPIA/POS device 3 event */
+	__be32	upde4;		/* UTOPIA/POS device 4 event */
+	__be16	uprp1;
+	__be16	uprp2;
+	__be16	uprp3;
+	__be16	uprp4;
+	u8	res1[0x8];
+	__be16	uptirr1_0;	/* Device 1 transmit internal rate 0 */
+	__be16	uptirr1_1;	/* Device 1 transmit internal rate 1 */
+	__be16	uptirr1_2;	/* Device 1 transmit internal rate 2 */
+	__be16	uptirr1_3;	/* Device 1 transmit internal rate 3 */
+	__be16	uptirr2_0;	/* Device 2 transmit internal rate 0 */
+	__be16	uptirr2_1;	/* Device 2 transmit internal rate 1 */
+	__be16	uptirr2_2;	/* Device 2 transmit internal rate 2 */
+	__be16	uptirr2_3;	/* Device 2 transmit internal rate 3 */
+	__be16	uptirr3_0;	/* Device 3 transmit internal rate 0 */
+	__be16	uptirr3_1;	/* Device 3 transmit internal rate 1 */
+	__be16	uptirr3_2;	/* Device 3 transmit internal rate 2 */
+	__be16	uptirr3_3;	/* Device 3 transmit internal rate 3 */
+	__be16	uptirr4_0;	/* Device 4 transmit internal rate 0 */
+	__be16	uptirr4_1;	/* Device 4 transmit internal rate 1 */
+	__be16	uptirr4_2;	/* Device 4 transmit internal rate 2 */
+	__be16	uptirr4_3;	/* Device 4 transmit internal rate 3 */
+	__be32	uper1;		/* Device 1 port enable register */
+	__be32	uper2;		/* Device 2 port enable register */
+	__be32	uper3;		/* Device 3 port enable register */
+	__be32	uper4;		/* Device 4 port enable register */
+	u8	res2[0x150];
+} __attribute__ ((packed));
+
+/* SDMA */
+struct sdma {
+	__be32	sdsr;		/* Serial DMA status register */
+	__be32	sdmr;		/* Serial DMA mode register */
+	__be32	sdtr1;		/* SDMA system bus threshold register */
+	__be32	sdtr2;		/* SDMA secondary bus threshold register */
+	__be32	sdhy1;		/* SDMA system bus hysteresis register */
+	__be32	sdhy2;		/* SDMA secondary bus hysteresis register */
+	__be32	sdta1;		/* SDMA system bus address register */
+	__be32	sdta2;		/* SDMA secondary bus address register */
+	__be32	sdtm1;		/* SDMA system bus MSNUM register */
+	__be32	sdtm2;		/* SDMA secondary bus MSNUM register */
+	u8	res0[0x10];
+	__be32	sdaqr;		/* SDMA address bus qualify register */
+	__be32	sdaqmr;		/* SDMA address bus qualify mask register */
+	u8	res1[0x4];
+	__be32	sdebcr;		/* SDMA CAM entries base register */
+	u8	res2[0x38];
+} __attribute__ ((packed));
+
+/* Debug Space */
+struct dbg {
+	__be32	bpdcr;		/* Breakpoint debug command register */
+	__be32	bpdsr;		/* Breakpoint debug status register */
+	__be32	bpdmr;		/* Breakpoint debug mask register */
+	__be32	bprmrr0;	/* Breakpoint request mode risc register 0 */
+	__be32	bprmrr1;	/* Breakpoint request mode risc register 1 */
+	u8	res0[0x8];
+	__be32	bprmtr0;	/* Breakpoint request mode trb register 0 */
+	__be32	bprmtr1;	/* Breakpoint request mode trb register 1 */
+	u8	res1[0x8];
+	__be32	bprmir;		/* Breakpoint request mode immediate register */
+	__be32	bprmsr;		/* Breakpoint request mode serial register */
+	__be32	bpemr;		/* Breakpoint exit mode register */
+	u8	res2[0x48];
+} __attribute__ ((packed));
+
+/* RISC Special Registers (Trap and Breakpoint) */
+struct rsp {
+	u8	fixme[0x100];
+} __attribute__ ((packed));
+
+struct qe_immap {
+	struct qe_iram		iram;		/* I-RAM */
+	struct qe_ic_regs	ic;		/* Interrupt Controller */
+	struct cp_qe		cp;		/* Communications Processor */
+	struct qe_mux		qmx;		/* QE Multiplexer */
+	struct qe_timers	qet;		/* QE Timers */
+	struct spi		spi[0x2];	/* spi */
+	struct mcc		mcc;		/* mcc */
+	struct qe_brg		brg;		/* brg */
+	struct usb_ctlr		usb;		/* USB */
+	struct si1		si1;		/* SI */
+	u8			res11[0x800];
+	struct sir		sir;		/* SI Routing Tables */
+	struct ucc		ucc1;		/* ucc1 */
+	struct ucc		ucc3;		/* ucc3 */
+	struct ucc		ucc5;		/* ucc5 */
+	struct ucc		ucc7;		/* ucc7 */
+	u8			res12[0x600];
+	struct upc		upc1;		/* MultiPHY UTOPIA POS Ctrlr 1*/
+	struct ucc		ucc2;		/* ucc2 */
+	struct ucc		ucc4;		/* ucc4 */
+	struct ucc		ucc6;		/* ucc6 */
+	struct ucc		ucc8;		/* ucc8 */
+	u8			res13[0x600];
+	struct upc		upc2;		/* MultiPHY UTOPIA POS Ctrlr 2*/
+	struct sdma		sdma;		/* SDMA */
+	struct dbg		dbg;		/* Debug Space */
+	struct rsp		rsp[0x2];	/* RISC Special Registers
+						   (Trap and Breakpoint) */
+	u8			res14[0x300];
+	u8			res15[0x3A00];
+	u8			res16[0x8000];	/* 0x108000 - 0x110000 */
+	u8			muram[0xC000];	/* 0x110000 - 0x11C000
+						   Multi-user RAM */
+	u8			res17[0x24000];	/* 0x11C000 - 0x140000 */
+	u8			res18[0xC0000];	/* 0x140000 - 0x200000 */
+} __attribute__ ((packed));
+
+extern struct qe_immap *qe_immr;
+extern phys_addr_t get_qe_base(void);
+
+static inline unsigned long immrbar_virt_to_phys(volatile void * address)
+{
+	if ( ((u32)address >= (u32)qe_immr) &&
+			((u32)address < ((u32)qe_immr + QE_IMMAP_SIZE)) )
+		return (unsigned long)(address - (u32)qe_immr +
+				(u32)get_qe_base());
+	return (unsigned long)virt_to_phys(address);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_IMMAP_QE_H */
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 19b2ec1..cbbd8c6 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -11,7 +11,6 @@
 
 /* Check of existence of legacy devices */
 extern int check_legacy_ioport(unsigned long base_port);
-#define PARALLEL_BASE	0x378
 #define PNPBIOS_BASE	0xf000	/* only relevant for PReP */
 
 #ifndef CONFIG_PPC64
diff --git a/include/asm-powerpc/ipic.h b/include/asm-powerpc/ipic.h
index 53079ec..1ce09a3 100644
--- a/include/asm-powerpc/ipic.h
+++ b/include/asm-powerpc/ipic.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/ipic.h
+ * include/asm-powerpc/ipic.h
  *
  * IPIC external definitions and structure.
  *
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index 34e1f89..2dafa37 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -44,6 +44,28 @@
 #define IS_TDI(instr)		(((instr) & 0xfc000000) == 0x08000000)
 #define IS_TWI(instr)		(((instr) & 0xfc000000) == 0x0c000000)
 
+/*
+ * 64bit powerpc uses function descriptors.
+ * Handle cases where:
+ * 		- User passes a <.symbol> or <module:.symbol>
+ * 		- User passes a <symbol> or <module:symbol>
+ * 		- User passes a non-existant symbol, kallsyms_lookup_name
+ * 		  returns 0. Don't deref the NULL pointer in that case
+ */
+#define kprobe_lookup_name(name, addr)					\
+{									\
+	addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);		\
+	if (addr) {							\
+		char *colon;						\
+		if ((colon = strchr(name, ':')) != NULL) {		\
+			colon++;					\
+			if (*colon != '\0' && *colon != '.')		\
+				addr = *(kprobe_opcode_t **)addr;	\
+		} else if (name[0] != '.')				\
+			addr = *(kprobe_opcode_t **)addr;		\
+	}								\
+}
+
 #define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)((func_descr_t *)pentry)
 
 #define is_trap(instr)	(IS_TW(instr) || IS_TD(instr) || \
diff --git a/include/asm-powerpc/mpc85xx.h b/include/asm-powerpc/mpc85xx.h
new file mode 100644
index 0000000..ccdb8a2
--- /dev/null
+++ b/include/asm-powerpc/mpc85xx.h
@@ -0,0 +1,53 @@
+/*
+ * include/asm-powerpc/mpc85xx.h
+ *
+ * MPC85xx definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor, 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_MPC85xx_H__
+#define __ASM_MPC85xx_H__
+
+#include <asm/mmu.h>
+
+#ifdef CONFIG_85xx
+
+#if defined(CONFIG_MPC8540_ADS) || defined(CONFIG_MPC8560_ADS)
+#include <platforms/85xx/mpc85xx_ads.h>
+#endif
+#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
+#include <platforms/85xx/mpc8555_cds.h>
+#endif
+#ifdef CONFIG_MPC85xx_CDS
+#include <platforms/85xx/mpc85xx_cds.h>
+#endif
+
+#define _IO_BASE        isa_io_base
+#define _ISA_MEM_BASE   isa_mem_base
+#ifdef CONFIG_PCI
+#define PCI_DRAM_OFFSET pci_dram_offset
+#else
+#define PCI_DRAM_OFFSET 0
+#endif
+
+/* Let modules/drivers get at CCSRBAR */
+extern phys_addr_t get_ccsrbar(void);
+
+#ifdef MODULE
+#define CCSRBAR get_ccsrbar()
+#else
+#define CCSRBAR BOARD_CCSRBAR
+#endif
+
+#endif /* CONFIG_85xx */
+#endif /* __ASM_MPC85xx_H__ */
+#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 4435efe..4ad77a1 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -73,6 +73,8 @@
 #ifndef __ASSEMBLY__
 
 #define instruction_pointer(regs) ((regs)->nip)
+#define regs_return_value(regs) ((regs)->gpr[3])
+
 #ifdef CONFIG_SMP
 extern unsigned long profile_pc(struct pt_regs *regs);
 #else
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h
new file mode 100644
index 0000000..a62168ec
--- /dev/null
+++ b/include/asm-powerpc/qe.h
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * QUICC Engine (QE) external definitions and structure.
+ *
+ * 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_POWERPC_QE_H
+#define _ASM_POWERPC_QE_H
+#ifdef __KERNEL__
+
+#include <asm/immap_qe.h>
+
+#define QE_NUM_OF_SNUM	28
+#define QE_NUM_OF_BRGS	16
+#define QE_NUM_OF_PORTS	1024
+
+/* Memory partitions
+*/
+#define MEM_PART_SYSTEM		0
+#define MEM_PART_SECONDARY	1
+#define MEM_PART_MURAM		2
+
+/* Export QE common operations */
+extern void qe_reset(void);
+extern int par_io_init(struct device_node *np);
+extern int par_io_of_config(struct device_node *np);
+
+/* QE internal API */
+int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
+void qe_setbrg(u32 brg, u32 rate);
+int qe_get_snum(void);
+void qe_put_snum(u8 snum);
+u32 qe_muram_alloc(u32 size, u32 align);
+int qe_muram_free(u32 offset);
+u32 qe_muram_alloc_fixed(u32 offset, u32 size);
+void qe_muram_dump(void);
+void *qe_muram_addr(u32 offset);
+
+/* Buffer descriptors */
+struct qe_bd {
+	u16 status;
+	u16 length;
+	u32 buf;
+} __attribute__ ((packed));
+
+#define BD_STATUS_MASK	0xffff0000
+#define BD_LENGTH_MASK	0x0000ffff
+
+/* Alignment */
+#define QE_INTR_TABLE_ALIGN	16	/* ??? */
+#define QE_ALIGNMENT_OF_BD	8
+#define QE_ALIGNMENT_OF_PRAM	64
+
+/* RISC allocation */
+enum qe_risc_allocation {
+	QE_RISC_ALLOCATION_RISC1 = 1,	/* RISC 1 */
+	QE_RISC_ALLOCATION_RISC2 = 2,	/* RISC 2 */
+	QE_RISC_ALLOCATION_RISC1_AND_RISC2 = 3	/* Dynamically choose
+						   RISC 1 or RISC 2 */
+};
+
+/* QE extended filtering Table Lookup Key Size */
+enum qe_fltr_tbl_lookup_key_size {
+	QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES
+		= 0x3f,		/* LookupKey parsed by the Generate LookupKey
+				   CMD is truncated to 8 bytes */
+	QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES
+		= 0x5f,		/* LookupKey parsed by the Generate LookupKey
+				   CMD is truncated to 16 bytes */
+};
+
+/* QE FLTR extended filtering Largest External Table Lookup Key Size */
+enum qe_fltr_largest_external_tbl_lookup_key_size {
+	QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE
+		= 0x0,/* not used */
+	QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES
+		= QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES,	/* 8 bytes */
+	QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES
+		= QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES,	/* 16 bytes */
+};
+
+/* structure representing QE parameter RAM */
+struct qe_timer_tables {
+	u16 tm_base;		/* QE timer table base adr */
+	u16 tm_ptr;		/* QE timer table pointer */
+	u16 r_tmr;		/* QE timer mode register */
+	u16 r_tmv;		/* QE timer valid register */
+	u32 tm_cmd;		/* QE timer cmd register */
+	u32 tm_cnt;		/* QE timer internal cnt */
+} __attribute__ ((packed));
+
+#define QE_FLTR_TAD_SIZE	8
+
+/* QE extended filtering Termination Action Descriptor (TAD) */
+struct qe_fltr_tad {
+	u8 serialized[QE_FLTR_TAD_SIZE];
+} __attribute__ ((packed));
+
+/* Communication Direction */
+enum comm_dir {
+	COMM_DIR_NONE = 0,
+	COMM_DIR_RX = 1,
+	COMM_DIR_TX = 2,
+	COMM_DIR_RX_AND_TX = 3
+};
+
+/* Clocks and BRGs */
+enum qe_clock {
+	QE_CLK_NONE = 0,
+	QE_BRG1,		/* Baud Rate Generator 1 */
+	QE_BRG2,		/* Baud Rate Generator 2 */
+	QE_BRG3,		/* Baud Rate Generator 3 */
+	QE_BRG4,		/* Baud Rate Generator 4 */
+	QE_BRG5,		/* Baud Rate Generator 5 */
+	QE_BRG6,		/* Baud Rate Generator 6 */
+	QE_BRG7,		/* Baud Rate Generator 7 */
+	QE_BRG8,		/* Baud Rate Generator 8 */
+	QE_BRG9,		/* Baud Rate Generator 9 */
+	QE_BRG10,		/* Baud Rate Generator 10 */
+	QE_BRG11,		/* Baud Rate Generator 11 */
+	QE_BRG12,		/* Baud Rate Generator 12 */
+	QE_BRG13,		/* Baud Rate Generator 13 */
+	QE_BRG14,		/* Baud Rate Generator 14 */
+	QE_BRG15,		/* Baud Rate Generator 15 */
+	QE_BRG16,		/* Baud Rate Generator 16 */
+	QE_CLK1,		/* Clock 1 */
+	QE_CLK2,		/* Clock 2 */
+	QE_CLK3,		/* Clock 3 */
+	QE_CLK4,		/* Clock 4 */
+	QE_CLK5,		/* Clock 5 */
+	QE_CLK6,		/* Clock 6 */
+	QE_CLK7,		/* Clock 7 */
+	QE_CLK8,		/* Clock 8 */
+	QE_CLK9,		/* Clock 9 */
+	QE_CLK10,		/* Clock 10 */
+	QE_CLK11,		/* Clock 11 */
+	QE_CLK12,		/* Clock 12 */
+	QE_CLK13,		/* Clock 13 */
+	QE_CLK14,		/* Clock 14 */
+	QE_CLK15,		/* Clock 15 */
+	QE_CLK16,		/* Clock 16 */
+	QE_CLK17,		/* Clock 17 */
+	QE_CLK18,		/* Clock 18 */
+	QE_CLK19,		/* Clock 19 */
+	QE_CLK20,		/* Clock 20 */
+	QE_CLK21,		/* Clock 21 */
+	QE_CLK22,		/* Clock 22 */
+	QE_CLK23,		/* Clock 23 */
+	QE_CLK24,		/* Clock 24 */
+	QE_CLK_DUMMY,
+};
+
+/* QE CMXUCR Registers.
+ * There are two UCCs represented in each of the four CMXUCR registers.
+ * These values are for the UCC in the LSBs
+ */
+#define QE_CMXUCR_MII_ENET_MNG		0x00007000
+#define QE_CMXUCR_MII_ENET_MNG_SHIFT	12
+#define QE_CMXUCR_GRANT			0x00008000
+#define QE_CMXUCR_TSA			0x00004000
+#define QE_CMXUCR_BKPT			0x00000100
+#define QE_CMXUCR_TX_CLK_SRC_MASK	0x0000000F
+
+/* QE CMXGCR Registers.
+*/
+#define QE_CMXGCR_MII_ENET_MNG		0x00007000
+#define QE_CMXGCR_MII_ENET_MNG_SHIFT	12
+#define QE_CMXGCR_USBCS			0x0000000f
+
+/* QE CECR Commands.
+*/
+#define QE_CR_FLG			0x00010000
+#define QE_RESET			0x80000000
+#define QE_INIT_TX_RX			0x00000000
+#define QE_INIT_RX			0x00000001
+#define QE_INIT_TX			0x00000002
+#define QE_ENTER_HUNT_MODE		0x00000003
+#define QE_STOP_TX			0x00000004
+#define QE_GRACEFUL_STOP_TX		0x00000005
+#define QE_RESTART_TX			0x00000006
+#define QE_CLOSE_RX_BD			0x00000007
+#define QE_SWITCH_COMMAND		0x00000007
+#define QE_SET_GROUP_ADDRESS		0x00000008
+#define QE_START_IDMA			0x00000009
+#define QE_MCC_STOP_RX			0x00000009
+#define QE_ATM_TRANSMIT			0x0000000a
+#define QE_HPAC_CLEAR_ALL		0x0000000b
+#define QE_GRACEFUL_STOP_RX		0x0000001a
+#define QE_RESTART_RX			0x0000001b
+#define QE_HPAC_SET_PRIORITY		0x0000010b
+#define QE_HPAC_STOP_TX			0x0000020b
+#define QE_HPAC_STOP_RX			0x0000030b
+#define QE_HPAC_GRACEFUL_STOP_TX	0x0000040b
+#define QE_HPAC_GRACEFUL_STOP_RX	0x0000050b
+#define QE_HPAC_START_TX		0x0000060b
+#define QE_HPAC_START_RX		0x0000070b
+#define QE_USB_STOP_TX			0x0000000a
+#define QE_USB_RESTART_TX		0x0000000b
+#define QE_QMC_STOP_TX			0x0000000c
+#define QE_QMC_STOP_RX			0x0000000d
+#define QE_SS7_SU_FIL_RESET		0x0000000e
+/* jonathbr added from here down for 83xx */
+#define QE_RESET_BCS			0x0000000a
+#define QE_MCC_INIT_TX_RX_16		0x00000003
+#define QE_MCC_STOP_TX			0x00000004
+#define QE_MCC_INIT_TX_1		0x00000005
+#define QE_MCC_INIT_RX_1		0x00000006
+#define QE_MCC_RESET			0x00000007
+#define QE_SET_TIMER			0x00000008
+#define QE_RANDOM_NUMBER		0x0000000c
+#define QE_ATM_MULTI_THREAD_INIT	0x00000011
+#define QE_ASSIGN_PAGE			0x00000012
+#define QE_ADD_REMOVE_HASH_ENTRY	0x00000013
+#define QE_START_FLOW_CONTROL		0x00000014
+#define QE_STOP_FLOW_CONTROL		0x00000015
+#define QE_ASSIGN_PAGE_TO_DEVICE	0x00000016
+
+#define QE_ASSIGN_RISC			0x00000010
+#define QE_CR_MCN_NORMAL_SHIFT		6
+#define QE_CR_MCN_USB_SHIFT		4
+#define QE_CR_MCN_RISC_ASSIGN_SHIFT	8
+#define QE_CR_SNUM_SHIFT		17
+
+/* QE CECR Sub Block - sub block of QE command.
+*/
+#define QE_CR_SUBBLOCK_INVALID		0x00000000
+#define QE_CR_SUBBLOCK_USB		0x03200000
+#define QE_CR_SUBBLOCK_UCCFAST1		0x02000000
+#define QE_CR_SUBBLOCK_UCCFAST2		0x02200000
+#define QE_CR_SUBBLOCK_UCCFAST3		0x02400000
+#define QE_CR_SUBBLOCK_UCCFAST4		0x02600000
+#define QE_CR_SUBBLOCK_UCCFAST5		0x02800000
+#define QE_CR_SUBBLOCK_UCCFAST6		0x02a00000
+#define QE_CR_SUBBLOCK_UCCFAST7		0x02c00000
+#define QE_CR_SUBBLOCK_UCCFAST8		0x02e00000
+#define QE_CR_SUBBLOCK_UCCSLOW1		0x00000000
+#define QE_CR_SUBBLOCK_UCCSLOW2		0x00200000
+#define QE_CR_SUBBLOCK_UCCSLOW3		0x00400000
+#define QE_CR_SUBBLOCK_UCCSLOW4		0x00600000
+#define QE_CR_SUBBLOCK_UCCSLOW5		0x00800000
+#define QE_CR_SUBBLOCK_UCCSLOW6		0x00a00000
+#define QE_CR_SUBBLOCK_UCCSLOW7		0x00c00000
+#define QE_CR_SUBBLOCK_UCCSLOW8		0x00e00000
+#define QE_CR_SUBBLOCK_MCC1		0x03800000
+#define QE_CR_SUBBLOCK_MCC2		0x03a00000
+#define QE_CR_SUBBLOCK_MCC3		0x03000000
+#define QE_CR_SUBBLOCK_IDMA1		0x02800000
+#define QE_CR_SUBBLOCK_IDMA2		0x02a00000
+#define QE_CR_SUBBLOCK_IDMA3		0x02c00000
+#define QE_CR_SUBBLOCK_IDMA4		0x02e00000
+#define QE_CR_SUBBLOCK_HPAC		0x01e00000
+#define QE_CR_SUBBLOCK_SPI1		0x01400000
+#define QE_CR_SUBBLOCK_SPI2		0x01600000
+#define QE_CR_SUBBLOCK_RAND		0x01c00000
+#define QE_CR_SUBBLOCK_TIMER		0x01e00000
+#define QE_CR_SUBBLOCK_GENERAL		0x03c00000
+
+/* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command */
+#define QE_CR_PROTOCOL_UNSPECIFIED	0x00	/* For all other protocols */
+#define QE_CR_PROTOCOL_HDLC_TRANSPARENT	0x00
+#define QE_CR_PROTOCOL_ATM_POS		0x0A
+#define QE_CR_PROTOCOL_ETHERNET		0x0C
+#define QE_CR_PROTOCOL_L2_SWITCH	0x0D
+
+/* BMR byte order */
+#define QE_BMR_BYTE_ORDER_BO_PPC	0x08	/* powerpc little endian */
+#define QE_BMR_BYTE_ORDER_BO_MOT	0x10	/* motorola big endian */
+#define QE_BMR_BYTE_ORDER_BO_MAX	0x18
+
+/* BRG configuration register */
+#define QE_BRGC_ENABLE		0x00010000
+#define QE_BRGC_DIVISOR_SHIFT	1
+#define QE_BRGC_DIVISOR_MAX	0xFFF
+#define QE_BRGC_DIV16		1
+
+/* QE Timers registers */
+#define QE_GTCFR1_PCAS	0x80
+#define QE_GTCFR1_STP2	0x20
+#define QE_GTCFR1_RST2	0x10
+#define QE_GTCFR1_GM2	0x08
+#define QE_GTCFR1_GM1	0x04
+#define QE_GTCFR1_STP1	0x02
+#define QE_GTCFR1_RST1	0x01
+
+/* SDMA registers */
+#define QE_SDSR_BER1	0x02000000
+#define QE_SDSR_BER2	0x01000000
+
+#define QE_SDMR_GLB_1_MSK	0x80000000
+#define QE_SDMR_ADR_SEL		0x20000000
+#define QE_SDMR_BER1_MSK	0x02000000
+#define QE_SDMR_BER2_MSK	0x01000000
+#define QE_SDMR_EB1_MSK		0x00800000
+#define QE_SDMR_ER1_MSK		0x00080000
+#define QE_SDMR_ER2_MSK		0x00040000
+#define QE_SDMR_CEN_MASK	0x0000E000
+#define QE_SDMR_SBER_1		0x00000200
+#define QE_SDMR_SBER_2		0x00000200
+#define QE_SDMR_EB1_PR_MASK	0x000000C0
+#define QE_SDMR_ER1_PR		0x00000008
+
+#define QE_SDMR_CEN_SHIFT	13
+#define QE_SDMR_EB1_PR_SHIFT	6
+
+#define QE_SDTM_MSNUM_SHIFT	24
+
+#define QE_SDEBCR_BA_MASK	0x01FFFFFF
+
+/* UPC */
+#define UPGCR_PROTOCOL	0x80000000	/* protocol ul2 or pl2 */
+#define UPGCR_TMS	0x40000000	/* Transmit master/slave mode */
+#define UPGCR_RMS	0x20000000	/* Receive master/slave mode */
+#define UPGCR_ADDR	0x10000000	/* Master MPHY Addr multiplexing */
+#define UPGCR_DIAG	0x01000000	/* Diagnostic mode */
+
+/* UCC */
+#define UCC_GUEMR_MODE_MASK_RX	0x02
+#define UCC_GUEMR_MODE_MASK_TX	0x01
+#define UCC_GUEMR_MODE_FAST_RX	0x02
+#define UCC_GUEMR_MODE_FAST_TX	0x01
+#define UCC_GUEMR_MODE_SLOW_RX	0x00
+#define UCC_GUEMR_MODE_SLOW_TX	0x00
+#define UCC_GUEMR_SET_RESERVED3	0x10	/* Bit 3 in the guemr is reserved but
+					   must be set 1 */
+
+/* structure representing UCC SLOW parameter RAM */
+struct ucc_slow_pram {
+	u16 rbase;		/* RX BD base address */
+	u16 tbase;		/* TX BD base address */
+	u8 rfcr;		/* Rx function code */
+	u8 tfcr;		/* Tx function code */
+	u16 mrblr;		/* Rx buffer length */
+	u32 rstate;		/* Rx internal state */
+	u32 rptr;		/* Rx internal data pointer */
+	u16 rbptr;		/* rb BD Pointer */
+	u16 rcount;		/* Rx internal byte count */
+	u32 rtemp;		/* Rx temp */
+	u32 tstate;		/* Tx internal state */
+	u32 tptr;		/* Tx internal data pointer */
+	u16 tbptr;		/* Tx BD pointer */
+	u16 tcount;		/* Tx byte count */
+	u32 ttemp;		/* Tx temp */
+	u32 rcrc;		/* temp receive CRC */
+	u32 tcrc;		/* temp transmit CRC */
+} __attribute__ ((packed));
+
+/* General UCC SLOW Mode Register (GUMRH & GUMRL) */
+#define UCC_SLOW_GUMR_H_CRC16		0x00004000
+#define UCC_SLOW_GUMR_H_CRC16CCITT	0x00000000
+#define UCC_SLOW_GUMR_H_CRC32CCITT	0x00008000
+#define UCC_SLOW_GUMR_H_REVD		0x00002000
+#define UCC_SLOW_GUMR_H_TRX		0x00001000
+#define UCC_SLOW_GUMR_H_TTX		0x00000800
+#define UCC_SLOW_GUMR_H_CDP		0x00000400
+#define UCC_SLOW_GUMR_H_CTSP		0x00000200
+#define UCC_SLOW_GUMR_H_CDS		0x00000100
+#define UCC_SLOW_GUMR_H_CTSS		0x00000080
+#define UCC_SLOW_GUMR_H_TFL		0x00000040
+#define UCC_SLOW_GUMR_H_RFW		0x00000020
+#define UCC_SLOW_GUMR_H_TXSY		0x00000010
+#define UCC_SLOW_GUMR_H_4SYNC		0x00000004
+#define UCC_SLOW_GUMR_H_8SYNC		0x00000008
+#define UCC_SLOW_GUMR_H_16SYNC		0x0000000c
+#define UCC_SLOW_GUMR_H_RTSM		0x00000002
+#define UCC_SLOW_GUMR_H_RSYN		0x00000001
+
+#define UCC_SLOW_GUMR_L_TCI		0x10000000
+#define UCC_SLOW_GUMR_L_RINV		0x02000000
+#define UCC_SLOW_GUMR_L_TINV		0x01000000
+#define UCC_SLOW_GUMR_L_TEND		0x00020000
+#define UCC_SLOW_GUMR_L_ENR		0x00000020
+#define UCC_SLOW_GUMR_L_ENT		0x00000010
+
+/* General UCC FAST Mode Register */
+#define UCC_FAST_GUMR_TCI	0x20000000
+#define UCC_FAST_GUMR_TRX	0x10000000
+#define UCC_FAST_GUMR_TTX	0x08000000
+#define UCC_FAST_GUMR_CDP	0x04000000
+#define UCC_FAST_GUMR_CTSP	0x02000000
+#define UCC_FAST_GUMR_CDS	0x01000000
+#define UCC_FAST_GUMR_CTSS	0x00800000
+#define UCC_FAST_GUMR_TXSY	0x00020000
+#define UCC_FAST_GUMR_RSYN	0x00010000
+#define UCC_FAST_GUMR_RTSM	0x00002000
+#define UCC_FAST_GUMR_REVD	0x00000400
+#define UCC_FAST_GUMR_ENR	0x00000020
+#define UCC_FAST_GUMR_ENT	0x00000010
+
+/* Slow UCC Event Register (UCCE) */
+#define UCC_SLOW_UCCE_GLR	0x1000
+#define UCC_SLOW_UCCE_GLT	0x0800
+#define UCC_SLOW_UCCE_DCC	0x0400
+#define UCC_SLOW_UCCE_FLG	0x0200
+#define UCC_SLOW_UCCE_AB	0x0200
+#define UCC_SLOW_UCCE_IDLE	0x0100
+#define UCC_SLOW_UCCE_GRA	0x0080
+#define UCC_SLOW_UCCE_TXE	0x0010
+#define UCC_SLOW_UCCE_RXF	0x0008
+#define UCC_SLOW_UCCE_CCR	0x0008
+#define UCC_SLOW_UCCE_RCH	0x0008
+#define UCC_SLOW_UCCE_BSY	0x0004
+#define UCC_SLOW_UCCE_TXB	0x0002
+#define UCC_SLOW_UCCE_TX	0x0002
+#define UCC_SLOW_UCCE_RX	0x0001
+#define UCC_SLOW_UCCE_GOV	0x0001
+#define UCC_SLOW_UCCE_GUN	0x0002
+#define UCC_SLOW_UCCE_GINT	0x0004
+#define UCC_SLOW_UCCE_IQOV	0x0008
+
+#define UCC_SLOW_UCCE_HDLC_SET	(UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+		UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF | \
+		UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
+#define UCC_SLOW_UCCE_ENET_SET	(UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+		UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF)
+#define UCC_SLOW_UCCE_TRANS_SET	(UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+		UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \
+		UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
+#define UCC_SLOW_UCCE_UART_SET	(UCC_SLOW_UCCE_BSY | UCC_SLOW_UCCE_GRA | \
+		UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \
+		UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
+#define UCC_SLOW_UCCE_QMC_SET	(UCC_SLOW_UCCE_IQOV | UCC_SLOW_UCCE_GINT | \
+		UCC_SLOW_UCCE_GUN | UCC_SLOW_UCCE_GOV)
+
+#define UCC_SLOW_UCCE_OTHER	(UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+		UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | \
+		UCC_SLOW_UCCE_GLR)
+
+#define UCC_SLOW_INTR_TX	UCC_SLOW_UCCE_TXB
+#define UCC_SLOW_INTR_RX	(UCC_SLOW_UCCE_RXF | UCC_SLOW_UCCE_RX)
+#define UCC_SLOW_INTR		(UCC_SLOW_INTR_TX | UCC_SLOW_INTR_RX)
+
+/* UCC Transmit On Demand Register (UTODR) */
+#define UCC_SLOW_TOD	0x8000
+#define UCC_FAST_TOD	0x8000
+
+/* Function code masks */
+#define FC_GBL				0x20
+#define FC_DTB_LCL			0x02
+#define UCC_FAST_FUNCTION_CODE_GBL	0x20
+#define UCC_FAST_FUNCTION_CODE_DTB_LCL	0x02
+#define UCC_FAST_FUNCTION_CODE_BDB_LCL	0x01
+
+static inline long IS_MURAM_ERR(const u32 offset)
+{
+	return offset > (u32) - 1000L;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_QE_H */
diff --git a/include/asm-powerpc/qe_ic.h b/include/asm-powerpc/qe_ic.h
new file mode 100644
index 0000000..e386fb7
--- /dev/null
+++ b/include/asm-powerpc/qe_ic.h
@@ -0,0 +1,64 @@
+/*
+ * include/asm-powerpc/qe_ic.h
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * QE IC external definitions and structure.
+ *
+ * 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_POWERPC_QE_IC_H
+#define _ASM_POWERPC_QE_IC_H
+
+#include <linux/irq.h>
+
+#define NUM_OF_QE_IC_GROUPS	6
+
+/* Flags when we init the QE IC */
+#define QE_IC_SPREADMODE_GRP_W			0x00000001
+#define QE_IC_SPREADMODE_GRP_X			0x00000002
+#define QE_IC_SPREADMODE_GRP_Y			0x00000004
+#define QE_IC_SPREADMODE_GRP_Z			0x00000008
+#define QE_IC_SPREADMODE_GRP_RISCA		0x00000010
+#define QE_IC_SPREADMODE_GRP_RISCB		0x00000020
+
+#define QE_IC_LOW_SIGNAL			0x00000100
+#define QE_IC_HIGH_SIGNAL			0x00000200
+
+#define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH	0x00001000
+#define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH	0x00002000
+#define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH	0x00004000
+#define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH	0x00008000
+#define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH	0x00010000
+#define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH	0x00020000
+#define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH	0x00040000
+#define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH	0x00080000
+#define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH	0x00100000
+#define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH	0x00200000
+#define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH	0x00400000
+#define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH	0x00800000
+#define QE_IC_GRP_W_DEST_SIGNAL_SHIFT		(12)
+
+/* QE interrupt sources groups */
+enum qe_ic_grp_id {
+	QE_IC_GRP_W = 0,	/* QE interrupt controller group W */
+	QE_IC_GRP_X,		/* QE interrupt controller group X */
+	QE_IC_GRP_Y,		/* QE interrupt controller group Y */
+	QE_IC_GRP_Z,		/* QE interrupt controller group Z */
+	QE_IC_GRP_RISCA,	/* QE interrupt controller RISC group A */
+	QE_IC_GRP_RISCB		/* QE interrupt controller RISC group B */
+};
+
+void qe_ic_init(struct device_node *node, unsigned int flags);
+void qe_ic_set_highest_priority(unsigned int virq, int high);
+int qe_ic_set_priority(unsigned int virq, unsigned int priority);
+int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
+
+#endif /* _ASM_POWERPC_QE_IC_H */
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 4b41dea..4362759 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -91,10 +91,6 @@
 DEBUGGER_BOILERPLATE(debugger_dabr_match)
 DEBUGGER_BOILERPLATE(debugger_fault_handler)
 
-#ifdef CONFIG_XMON
-extern void xmon_init(int enable);
-#endif
-
 #else
 static inline int debugger(struct pt_regs *regs) { return 0; }
 static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
index 5785ac4..b051d4c 100644
--- a/include/asm-powerpc/time.h
+++ b/include/asm-powerpc/time.h
@@ -39,6 +39,10 @@
 extern void wakeup_decrementer(void);
 extern void snapshot_timebase(void);
 
+#ifdef CONFIG_RTC_CLASS
+extern int __init rtc_class_hookup(void);
+#endif
+
 /* Some sane defaults: 125 MHz timebase, 1GHz processor */
 extern unsigned long ppc_proc_freq;
 #define DEFAULT_PROC_FREQ	(DEFAULT_TB_FREQ * 8)
@@ -234,4 +238,4 @@
 #endif
 
 #endif /* __KERNEL__ */
-#endif /* __PPC64_TIME_H */
+#endif /* __POWERPC_TIME_H */
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index bbc3844..8f7ee16 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -43,6 +43,7 @@
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
diff --git a/include/asm-powerpc/ucc.h b/include/asm-powerpc/ucc.h
new file mode 100644
index 0000000..afe3076
--- /dev/null
+++ b/include/asm-powerpc/ucc.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * Internal header file for UCC unit routines.
+ *
+ * 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 __UCC_H__
+#define __UCC_H__
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#define STATISTICS
+
+#define UCC_MAX_NUM	8
+
+/* Slow or fast type for UCCs.
+*/
+enum ucc_speed_type {
+	UCC_SPEED_TYPE_FAST, UCC_SPEED_TYPE_SLOW
+};
+
+/* Initial UCCs Parameter RAM address relative to: MEM_MAP_BASE (IMMR).
+*/
+enum ucc_pram_initial_offset {
+	UCC_PRAM_OFFSET_UCC1 = 0x8400,
+	UCC_PRAM_OFFSET_UCC2 = 0x8500,
+	UCC_PRAM_OFFSET_UCC3 = 0x8600,
+	UCC_PRAM_OFFSET_UCC4 = 0x9000,
+	UCC_PRAM_OFFSET_UCC5 = 0x8000,
+	UCC_PRAM_OFFSET_UCC6 = 0x8100,
+	UCC_PRAM_OFFSET_UCC7 = 0x8200,
+	UCC_PRAM_OFFSET_UCC8 = 0x8300
+};
+
+/* ucc_set_type
+ * Sets UCC to slow or fast mode.
+ *
+ * ucc_num - (In) number of UCC (0-7).
+ * regs    - (In) pointer to registers base for the UCC.
+ * speed   - (In) slow or fast mode for UCC.
+ */
+int ucc_set_type(int ucc_num, struct ucc_common *regs,
+		 enum ucc_speed_type speed);
+
+/* ucc_init_guemr
+ * Init the Guemr register.
+ *
+ * regs - (In) pointer to registers base for the UCC.
+ */
+int ucc_init_guemr(struct ucc_common *regs);
+
+int ucc_set_qe_mux_mii_mng(int ucc_num);
+
+int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode);
+
+int ucc_mux_set_grant_tsa_bkpt(int ucc_num, int set, u32 mask);
+
+/* QE MUX clock routing for UCC
+*/
+static inline int ucc_set_qe_mux_grant(int ucc_num, int set)
+{
+	return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_GRANT);
+}
+
+static inline int ucc_set_qe_mux_tsa(int ucc_num, int set)
+{
+	return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_TSA);
+}
+
+static inline int ucc_set_qe_mux_bkpt(int ucc_num, int set)
+{
+	return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_BKPT);
+}
+
+#endif				/* __UCC_H__ */
diff --git a/include/asm-powerpc/ucc_fast.h b/include/asm-powerpc/ucc_fast.h
new file mode 100644
index 0000000..39d1c90
--- /dev/null
+++ b/include/asm-powerpc/ucc_fast.h
@@ -0,0 +1,243 @@
+/*
+ * include/asm-powerpc/ucc_fast.h
+ *
+ * Internal header file for UCC FAST unit routines.
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.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 __UCC_FAST_H__
+#define __UCC_FAST_H__
+
+#include <linux/kernel.h>
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include "ucc.h"
+
+/* Receive BD's status */
+#define R_E	0x80000000	/* buffer empty */
+#define R_W	0x20000000	/* wrap bit */
+#define R_I	0x10000000	/* interrupt on reception */
+#define R_L	0x08000000	/* last */
+#define R_F	0x04000000	/* first */
+
+/* transmit BD's status */
+#define T_R	0x80000000	/* ready bit */
+#define T_W	0x20000000	/* wrap bit */
+#define T_I	0x10000000	/* interrupt on completion */
+#define T_L	0x08000000	/* last */
+
+/* Rx Data buffer must be 4 bytes aligned in most cases */
+#define UCC_FAST_RX_ALIGN			4
+#define UCC_FAST_MRBLR_ALIGNMENT		4
+#define UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT	8
+
+/* Sizes */
+#define UCC_FAST_URFS_MIN_VAL				0x88
+#define UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR	8
+
+/* ucc_fast_channel_protocol_mode - UCC FAST mode */
+enum ucc_fast_channel_protocol_mode {
+	UCC_FAST_PROTOCOL_MODE_HDLC = 0x00000000,
+	UCC_FAST_PROTOCOL_MODE_RESERVED01 = 0x00000001,
+	UCC_FAST_PROTOCOL_MODE_RESERVED_QMC = 0x00000002,
+	UCC_FAST_PROTOCOL_MODE_RESERVED02 = 0x00000003,
+	UCC_FAST_PROTOCOL_MODE_RESERVED_UART = 0x00000004,
+	UCC_FAST_PROTOCOL_MODE_RESERVED03 = 0x00000005,
+	UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_1 = 0x00000006,
+	UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_2 = 0x00000007,
+	UCC_FAST_PROTOCOL_MODE_RESERVED_BISYNC = 0x00000008,
+	UCC_FAST_PROTOCOL_MODE_RESERVED04 = 0x00000009,
+	UCC_FAST_PROTOCOL_MODE_ATM = 0x0000000A,
+	UCC_FAST_PROTOCOL_MODE_RESERVED05 = 0x0000000B,
+	UCC_FAST_PROTOCOL_MODE_ETHERNET = 0x0000000C,
+	UCC_FAST_PROTOCOL_MODE_RESERVED06 = 0x0000000D,
+	UCC_FAST_PROTOCOL_MODE_POS = 0x0000000E,
+	UCC_FAST_PROTOCOL_MODE_RESERVED07 = 0x0000000F
+};
+
+/* ucc_fast_transparent_txrx - UCC Fast Transparent TX & RX */
+enum ucc_fast_transparent_txrx {
+	UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL = 0x00000000,
+	UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_TRANSPARENT = 0x18000000
+};
+
+/* UCC fast diagnostic mode */
+enum ucc_fast_diag_mode {
+	UCC_FAST_DIAGNOSTIC_NORMAL = 0x0,
+	UCC_FAST_DIAGNOSTIC_LOCAL_LOOP_BACK = 0x40000000,
+	UCC_FAST_DIAGNOSTIC_AUTO_ECHO = 0x80000000,
+	UCC_FAST_DIAGNOSTIC_LOOP_BACK_AND_ECHO = 0xC0000000
+};
+
+/* UCC fast Sync length (transparent mode only) */
+enum ucc_fast_sync_len {
+	UCC_FAST_SYNC_LEN_NOT_USED = 0x0,
+	UCC_FAST_SYNC_LEN_AUTOMATIC = 0x00004000,
+	UCC_FAST_SYNC_LEN_8_BIT = 0x00008000,
+	UCC_FAST_SYNC_LEN_16_BIT = 0x0000C000
+};
+
+/* UCC fast RTS mode */
+enum ucc_fast_ready_to_send {
+	UCC_FAST_SEND_IDLES_BETWEEN_FRAMES = 0x00000000,
+	UCC_FAST_SEND_FLAGS_BETWEEN_FRAMES = 0x00002000
+};
+
+/* UCC fast receiver decoding mode */
+enum ucc_fast_rx_decoding_method {
+	UCC_FAST_RX_ENCODING_NRZ = 0x00000000,
+	UCC_FAST_RX_ENCODING_NRZI = 0x00000800,
+	UCC_FAST_RX_ENCODING_RESERVED0 = 0x00001000,
+	UCC_FAST_RX_ENCODING_RESERVED1 = 0x00001800
+};
+
+/* UCC fast transmitter encoding mode */
+enum ucc_fast_tx_encoding_method {
+	UCC_FAST_TX_ENCODING_NRZ = 0x00000000,
+	UCC_FAST_TX_ENCODING_NRZI = 0x00000100,
+	UCC_FAST_TX_ENCODING_RESERVED0 = 0x00000200,
+	UCC_FAST_TX_ENCODING_RESERVED1 = 0x00000300
+};
+
+/* UCC fast CRC length */
+enum ucc_fast_transparent_tcrc {
+	UCC_FAST_16_BIT_CRC = 0x00000000,
+	UCC_FAST_CRC_RESERVED0 = 0x00000040,
+	UCC_FAST_32_BIT_CRC = 0x00000080,
+	UCC_FAST_CRC_RESERVED1 = 0x000000C0
+};
+
+/* Fast UCC initialization structure */
+struct ucc_fast_info {
+	int ucc_num;
+	enum qe_clock rx_clock;
+	enum qe_clock tx_clock;
+	u32 regs;
+	int irq;
+	u32 uccm_mask;
+	int bd_mem_part;
+	int brkpt_support;
+	int grant_support;
+	int tsa;
+	int cdp;
+	int cds;
+	int ctsp;
+	int ctss;
+	int tci;
+	int txsy;
+	int rtsm;
+	int revd;
+	int rsyn;
+	u16 max_rx_buf_length;
+	u16 urfs;
+	u16 urfet;
+	u16 urfset;
+	u16 utfs;
+	u16 utfet;
+	u16 utftt;
+	u16 ufpt;
+	enum ucc_fast_channel_protocol_mode mode;
+	enum ucc_fast_transparent_txrx ttx_trx;
+	enum ucc_fast_tx_encoding_method tenc;
+	enum ucc_fast_rx_decoding_method renc;
+	enum ucc_fast_transparent_tcrc tcrc;
+	enum ucc_fast_sync_len synl;
+};
+
+struct ucc_fast_private {
+	struct ucc_fast_info *uf_info;
+	struct ucc_fast *uf_regs;	/* a pointer to memory map of UCC regs. */
+	u32 *p_ucce;		/* a pointer to the event register in memory. */
+	u32 *p_uccm;		/* a pointer to the mask register in memory. */
+	int enabled_tx;		/* Whether channel is enabled for Tx (ENT) */
+	int enabled_rx;		/* Whether channel is enabled for Rx (ENR) */
+	int stopped_tx;		/* Whether channel has been stopped for Tx
+				   (STOP_TX, etc.) */
+	int stopped_rx;		/* Whether channel has been stopped for Rx */
+	u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
+						    virtual fifo */
+	u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
+						    virtual fifo */
+#ifdef STATISTICS
+	u32 tx_frames;		/* Transmitted frames counter. */
+	u32 rx_frames;		/* Received frames counter (only frames
+				   passed to application). */
+	u32 tx_discarded;	/* Discarded tx frames counter (frames that
+				   were discarded by the driver due to errors).
+				   */
+	u32 rx_discarded;	/* Discarded rx frames counter (frames that
+				   were discarded by the driver due to errors).
+				   */
+#endif				/* STATISTICS */
+	u16 mrblr;		/* maximum receive buffer length */
+};
+
+/* ucc_fast_init
+ * Initializes Fast UCC according to user provided parameters.
+ *
+ * uf_info  - (In) pointer to the fast UCC info structure.
+ * uccf_ret - (Out) pointer to the fast UCC structure.
+ */
+int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret);
+
+/* ucc_fast_free
+ * Frees all resources for fast UCC.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ */
+void ucc_fast_free(struct ucc_fast_private * uccf);
+
+/* ucc_fast_enable
+ * Enables a fast UCC port.
+ * This routine enables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode);
+
+/* ucc_fast_disable
+ * Disables a fast UCC port.
+ * This routine disables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode);
+
+/* ucc_fast_irq
+ * Handles interrupts on fast UCC.
+ * Called from the general interrupt routine to handle interrupts on fast UCC.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ */
+void ucc_fast_irq(struct ucc_fast_private * uccf);
+
+/* ucc_fast_transmit_on_demand
+ * Immediately forces a poll of the transmitter for data to be sent.
+ * Typically, the hardware performs a periodic poll for data that the
+ * transmit routine has set up to be transmitted. In cases where
+ * this polling cycle is not soon enough, this optional routine can
+ * be invoked to force a poll right away, instead. Proper use for
+ * each transmission for which this functionality is desired is to
+ * call the transmit routine and then this routine right after.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ */
+void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf);
+
+u32 ucc_fast_get_qe_cr_subblock(int uccf_num);
+
+void ucc_fast_dump_regs(struct ucc_fast_private * uccf);
+
+#endif				/* __UCC_FAST_H__ */
diff --git a/include/asm-powerpc/ucc_slow.h b/include/asm-powerpc/ucc_slow.h
new file mode 100644
index 0000000..ca93bc9
--- /dev/null
+++ b/include/asm-powerpc/ucc_slow.h
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors: 	Shlomi Gridish <gridish@freescale.com>
+ * 		Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * Internal header file for UCC SLOW unit routines.
+ *
+ * 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 __UCC_SLOW_H__
+#define __UCC_SLOW_H__
+
+#include <linux/kernel.h>
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include "ucc.h"
+
+/* transmit BD's status */
+#define T_R	0x80000000	/* ready bit */
+#define T_PAD	0x40000000	/* add pads to short frames */
+#define T_W	0x20000000	/* wrap bit */
+#define T_I	0x10000000	/* interrupt on completion */
+#define T_L	0x08000000	/* last */
+
+#define T_A	0x04000000	/* Address - the data transmitted as address
+				   chars */
+#define T_TC	0x04000000	/* transmit CRC */
+#define T_CM	0x02000000	/* continuous mode */
+#define T_DEF	0x02000000	/* collision on previous attempt to transmit */
+#define T_P	0x01000000	/* Preamble - send Preamble sequence before
+				   data */
+#define T_HB	0x01000000	/* heartbeat */
+#define T_NS	0x00800000	/* No Stop */
+#define T_LC	0x00800000	/* late collision */
+#define T_RL	0x00400000	/* retransmission limit */
+#define T_UN	0x00020000	/* underrun */
+#define T_CT	0x00010000	/* CTS lost */
+#define T_CSL	0x00010000	/* carrier sense lost */
+#define T_RC	0x003c0000	/* retry count */
+
+/* Receive BD's status */
+#define R_E	0x80000000	/* buffer empty */
+#define R_W	0x20000000	/* wrap bit */
+#define R_I	0x10000000	/* interrupt on reception */
+#define R_L	0x08000000	/* last */
+#define R_C	0x08000000	/* the last byte in this buffer is a cntl
+				   char */
+#define R_F	0x04000000	/* first */
+#define R_A	0x04000000	/* the first byte in this buffer is address
+				   byte */
+#define R_CM	0x02000000	/* continuous mode */
+#define R_ID	0x01000000	/* buffer close on reception of idles */
+#define R_M	0x01000000	/* Frame received because of promiscuous
+				   mode */
+#define R_AM	0x00800000	/* Address match */
+#define R_DE	0x00800000	/* Address match */
+#define R_LG	0x00200000	/* Break received */
+#define R_BR	0x00200000	/* Frame length violation */
+#define R_NO	0x00100000	/* Rx Non Octet Aligned Packet */
+#define R_FR	0x00100000	/* Framing Error (no stop bit) character
+				   received */
+#define R_PR	0x00080000	/* Parity Error character received */
+#define R_AB	0x00080000	/* Frame Aborted */
+#define R_SH	0x00080000	/* frame is too short */
+#define R_CR	0x00040000	/* CRC Error */
+#define R_OV	0x00020000	/* Overrun */
+#define R_CD	0x00010000	/* CD lost */
+#define R_CL	0x00010000	/* this frame is closed because of a
+				   collision */
+
+/* Rx Data buffer must be 4 bytes aligned in most cases.*/
+#define UCC_SLOW_RX_ALIGN		4
+#define UCC_SLOW_MRBLR_ALIGNMENT	4
+#define UCC_SLOW_PRAM_SIZE		0x100
+#define ALIGNMENT_OF_UCC_SLOW_PRAM	64
+
+/* UCC Slow Channel Protocol Mode */
+enum ucc_slow_channel_protocol_mode {
+	UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002,
+	UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004,
+	UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008,
+};
+
+/* UCC Slow Transparent Transmit CRC (TCRC) */
+enum ucc_slow_transparent_tcrc {
+	/* 16-bit CCITT CRC (HDLC).  (X16 + X12 + X5 + 1) */
+	UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000,
+	/* CRC16 (BISYNC).  (X16 + X15 + X2 + 1) */
+	UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000,
+	/* 32-bit CCITT CRC (Ethernet and HDLC) */
+	UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000,
+};
+
+/* UCC Slow oversampling rate for transmitter (TDCR) */
+enum ucc_slow_tx_oversampling_rate {
+	/* 1x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000,
+	/* 8x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000,
+	/* 16x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000,
+	/* 32x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000,
+};
+
+/* UCC Slow Oversampling rate for receiver (RDCR)
+*/
+enum ucc_slow_rx_oversampling_rate {
+	/* 1x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000,
+	/* 8x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000,
+	/* 16x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000,
+	/* 32x clock mode */
+	UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000,
+};
+
+/* UCC Slow Transmitter encoding method (TENC)
+*/
+enum ucc_slow_tx_encoding_method {
+	UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000,
+	UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100
+};
+
+/* UCC Slow Receiver decoding method (RENC)
+*/
+enum ucc_slow_rx_decoding_method {
+	UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000,
+	UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800
+};
+
+/* UCC Slow Diagnostic mode (DIAG)
+*/
+enum ucc_slow_diag_mode {
+	UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000,
+	UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040,
+	UCC_SLOW_DIAG_MODE_ECHO = 0x00000080,
+	UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0
+};
+
+struct ucc_slow_info {
+	int ucc_num;
+	enum qe_clock rx_clock;
+	enum qe_clock tx_clock;
+	struct ucc_slow *us_regs;
+	int irq;
+	u16 uccm_mask;
+	int data_mem_part;
+	int init_tx;
+	int init_rx;
+	u32 tx_bd_ring_len;
+	u32 rx_bd_ring_len;
+	int rx_interrupts;
+	int brkpt_support;
+	int grant_support;
+	int tsa;
+	int cdp;
+	int cds;
+	int ctsp;
+	int ctss;
+	int rinv;
+	int tinv;
+	int rtsm;
+	int rfw;
+	int tci;
+	int tend;
+	int tfl;
+	int txsy;
+	u16 max_rx_buf_length;
+	enum ucc_slow_transparent_tcrc tcrc;
+	enum ucc_slow_channel_protocol_mode mode;
+	enum ucc_slow_diag_mode diag;
+	enum ucc_slow_tx_oversampling_rate tdcr;
+	enum ucc_slow_rx_oversampling_rate rdcr;
+	enum ucc_slow_tx_encoding_method tenc;
+	enum ucc_slow_rx_decoding_method renc;
+};
+
+struct ucc_slow_private {
+	struct ucc_slow_info *us_info;
+	struct ucc_slow *us_regs;	/* a pointer to memory map of UCC regs */
+	struct ucc_slow_pram *us_pram;	/* a pointer to the parameter RAM */
+	u32 us_pram_offset;
+	int enabled_tx;		/* Whether channel is enabled for Tx (ENT) */
+	int enabled_rx;		/* Whether channel is enabled for Rx (ENR) */
+	int stopped_tx;		/* Whether channel has been stopped for Tx
+				   (STOP_TX, etc.) */
+	int stopped_rx;		/* Whether channel has been stopped for Rx */
+	struct list_head confQ;	/* frames passed to chip waiting for tx */
+	u32 first_tx_bd_mask;	/* mask is used in Tx routine to save status
+				   and length for first BD in a frame */
+	u32 tx_base_offset;	/* first BD in Tx BD table offset (In MURAM) */
+	u32 rx_base_offset;	/* first BD in Rx BD table offset (In MURAM) */
+	u8 *confBd;		/* next BD for confirm after Tx */
+	u8 *tx_bd;		/* next BD for new Tx request */
+	u8 *rx_bd;		/* next BD to collect after Rx */
+	void *p_rx_frame;	/* accumulating receive frame */
+	u16 *p_ucce;		/* a pointer to the event register in memory.
+				 */
+	u16 *p_uccm;		/* a pointer to the mask register in memory */
+	u16 saved_uccm;		/* a saved mask for the RX Interrupt bits */
+#ifdef STATISTICS
+	u32 tx_frames;		/* Transmitted frames counters */
+	u32 rx_frames;		/* Received frames counters (only frames
+				   passed to application) */
+	u32 rx_discarded;	/* Discarded frames counters (frames that
+				   were discarded by the driver due to
+				   errors) */
+#endif				/* STATISTICS */
+};
+
+/* ucc_slow_init
+ * Initializes Slow UCC according to provided parameters.
+ *
+ * us_info  - (In) pointer to the slow UCC info structure.
+ * uccs_ret - (Out) pointer to the slow UCC structure.
+ */
+int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret);
+
+/* ucc_slow_free
+ * Frees all resources for slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_free(struct ucc_slow_private * uccs);
+
+/* ucc_slow_enable
+ * Enables a fast UCC port.
+ * This routine enables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode);
+
+/* ucc_slow_disable
+ * Disables a fast UCC port.
+ * This routine disables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode);
+
+/* ucc_slow_poll_transmitter_now
+ * Immediately forces a poll of the transmitter for data to be sent.
+ * Typically, the hardware performs a periodic poll for data that the
+ * transmit routine has set up to be transmitted. In cases where
+ * this polling cycle is not soon enough, this optional routine can
+ * be invoked to force a poll right away, instead. Proper use for
+ * each transmission for which this functionality is desired is to
+ * call the transmit routine and then this routine right after.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs);
+
+/* ucc_slow_graceful_stop_tx
+ * Smoothly stops transmission on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs);
+
+/* ucc_slow_stop_tx
+ * Stops transmission on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_stop_tx(struct ucc_slow_private * uccs);
+
+/* ucc_slow_restart_x
+ * Restarts transmitting on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_restart_x(struct ucc_slow_private * uccs);
+
+u32 ucc_slow_get_qe_cr_subblock(int uccs_num);
+
+#endif				/* __UCC_SLOW_H__ */
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index eb66eae..464a48c 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -479,13 +479,6 @@
 #endif
 
 /*
- * System call prototypes.
- */
-#ifdef __KERNEL_SYSCALLS__
-extern int execve(const char *file, char **argv, char **envp);
-#endif /* __KERNEL_SYSCALLS__ */
-
-/*
  * "Conditional" syscalls
  *
  * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
index 43f7129..f1d337e 100644
--- a/include/asm-powerpc/xmon.h
+++ b/include/asm-powerpc/xmon.h
@@ -1,12 +1,22 @@
-#ifndef __PPC_XMON_H
-#define __PPC_XMON_H
+#ifndef __ASM_POWERPC_XMON_H
+#define __ASM_POWERPC_XMON_H
+
+/*
+ * Copyrignt (C) 2006 IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
 #ifdef __KERNEL__
 
-struct pt_regs;
-
-extern int xmon(struct pt_regs *excp);
-extern void xmon_printf(const char *fmt, ...);
-extern void xmon_init(int);
-
+#ifdef CONFIG_XMON
+extern void xmon_setup(void);
+#else
+static inline void xmon_setup(void) { };
 #endif
-#endif
+
+#endif /* __KERNEL __ */
+#endif /* __ASM_POWERPC_XMON_H */
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index f6a7ff0..220cc2d 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -42,6 +42,8 @@
 #define CPM_CR_IDMA4_SBLOCK	(0x17)
 #define CPM_CR_MCC1_SBLOCK	(0x1c)
 
+#define CPM_CR_FCC_SBLOCK(x)	(x + 0x10)
+
 #define CPM_CR_SCC1_PAGE	(0x00)
 #define CPM_CR_SCC2_PAGE	(0x01)
 #define CPM_CR_SCC3_PAGE	(0x02)
@@ -62,6 +64,8 @@
 #define CPM_CR_MCC1_PAGE	(0x07)
 #define CPM_CR_MCC2_PAGE	(0x08)
 
+#define CPM_CR_FCC_PAGE(x)	(x + 0x04)
+
 /* Some opcodes (there are more...later)
 */
 #define CPM_CR_INIT_TRX		((ushort)0x0000)
@@ -173,6 +177,10 @@
 #define PROFF_I2C_BASE		((uint)0x8afc)
 #define PROFF_IDMA4_BASE	((uint)0x8afe)
 
+#define PROFF_SCC_SIZE		((uint)0x100)
+#define PROFF_FCC_SIZE		((uint)0x100)
+#define PROFF_SMC_SIZE		((uint)64)
+
 /* The SMCs are relocated to any of the first eight DPRAM pages.
  * We will fix these at the first locations of DPRAM, until we
  * get some microcode patches :-).
@@ -1186,7 +1194,60 @@
 #define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128))
 #define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0)
 #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
-#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(2)
+#define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2)
+
+/* Clocks and GRG's */
+
+enum cpm_clk_dir {
+	CPM_CLK_RX,
+	CPM_CLK_TX,
+	CPM_CLK_RTX
+};
+
+enum cpm_clk_target {
+	CPM_CLK_SCC1,
+	CPM_CLK_SCC2,
+	CPM_CLK_SCC3,
+	CPM_CLK_SCC4,
+	CPM_CLK_FCC1,
+	CPM_CLK_FCC2,
+	CPM_CLK_FCC3
+};
+
+enum cpm_clk {
+	CPM_CLK_NONE = 0,
+	CPM_BRG1,	/* Baud Rate Generator  1 */
+	CPM_BRG2,	/* Baud Rate Generator  2 */
+	CPM_BRG3,	/* Baud Rate Generator  3 */
+	CPM_BRG4,	/* Baud Rate Generator  4 */
+	CPM_BRG5,	/* Baud Rate Generator  5 */
+	CPM_BRG6,	/* Baud Rate Generator  6 */
+	CPM_BRG7,	/* Baud Rate Generator  7 */
+	CPM_BRG8,	/* Baud Rate Generator  8 */
+	CPM_CLK1,	/* Clock  1 */
+	CPM_CLK2,	/* Clock  2 */
+	CPM_CLK3,	/* Clock  3 */
+	CPM_CLK4,	/* Clock  4 */
+	CPM_CLK5,	/* Clock  5 */
+	CPM_CLK6,	/* Clock  6 */
+	CPM_CLK7,	/* Clock  7 */
+	CPM_CLK8,	/* Clock  8 */
+	CPM_CLK9,	/* Clock  9 */
+	CPM_CLK10,	/* Clock 10 */
+	CPM_CLK11,	/* Clock 11 */
+	CPM_CLK12,	/* Clock 12 */
+	CPM_CLK13,	/* Clock 13 */
+	CPM_CLK14,	/* Clock 14 */
+	CPM_CLK15,	/* Clock 15 */
+	CPM_CLK16,	/* Clock 16 */
+	CPM_CLK17,	/* Clock 17 */
+	CPM_CLK18,	/* Clock 18 */
+	CPM_CLK19,	/* Clock 19 */
+	CPM_CLK20,	/* Clock 20 */
+	CPM_CLK_DUMMY
+};
+
+extern int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode);
 
 #endif /* __CPM2__ */
 #endif /* __KERNEL__ */
diff --git a/include/asm-ppc/fs_pd.h b/include/asm-ppc/fs_pd.h
new file mode 100644
index 0000000..8691327
--- /dev/null
+++ b/include/asm-ppc/fs_pd.h
@@ -0,0 +1,36 @@
+/*
+ * Platform information definitions.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.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.
+ */
+
+#ifndef FS_PD_H
+#define FS_PD_H
+
+static inline int uart_baudrate(void)
+{
+	int baud;
+	bd_t *bd = (bd_t *) __res;
+
+	if (bd->bi_baudrate)
+		baud = bd->bi_baudrate;
+	else
+		baud = -1;
+	return baud;
+}
+
+static inline int uart_clock(void)
+{
+	return (((bd_t *) __res)->bi_intfreq);
+}
+
+#define cpm2_map(member)	(&cpm2_immr->member)
+#define cpm2_map_size(member, size)	(&cpm2_immr->member)
+#define cpm2_unmap(addr)        do {} while(0)
+
+#endif
diff --git a/include/asm-ppc/mv64x60_defs.h b/include/asm-ppc/mv64x60_defs.h
index f8f7f16..5b0704a 100644
--- a/include/asm-ppc/mv64x60_defs.h
+++ b/include/asm-ppc/mv64x60_defs.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/gt64260_defs.h
+ * include/asm-ppc/mv64x60_defs.h
  *
  * Register definitions for the Marvell/Galileo GT64260, MV64360, etc.
  * host bridges.
diff --git a/include/asm-ppc/rheap.h b/include/asm-ppc/rheap.h
index e6ca1f6..39a10d8 100644
--- a/include/asm-ppc/rheap.h
+++ b/include/asm-ppc/rheap.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/rheap.c
+ * include/asm-ppc/rheap.h
  *
  * Header file for the implementation of a remote heap.
  *
@@ -62,6 +62,10 @@
 /* Detach a free region */
 extern void *rh_detach_region(rh_info_t * info, void *start, int size);
 
+/* Allocate the given size from the remote heap (with alignment) */
+extern void *rh_alloc_align(rh_info_t * info, int size, int alignment,
+		const char *owner);
+
 /* Allocate the given size from the remote heap */
 extern void *rh_alloc(rh_info_t * info, int size, const char *owner);
 
diff --git a/include/asm-ppc/rtc.h b/include/asm-ppc/rtc.h
index 05fbf91..6025b46 100644
--- a/include/asm-ppc/rtc.h
+++ b/include/asm-ppc/rtc.h
@@ -1,5 +1,5 @@
 /*
- * inclue/asm-ppc/rtc.h
+ * include/asm-ppc/rtc.h
  *
  * Author: Tom Rini <trini@mvista.com>
  *
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
index 8d2bf65..7b768c5 100644
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -472,6 +472,7 @@
 
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
+#define regs_return_value(regs)((regs)->gprs[2])
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs * regs);
 #endif
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index a2f37a9..7189c79 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm/qdio.h
+ * linux/include/asm-s390/qdio.h
  *
  * Linux for S/390 QDIO base support, Hipersocket base support
  * version 2
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index 0361ac5..0cccfd8 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -523,57 +523,6 @@
 #   define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 # endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-#include <asm/stat.h>
-#include <linux/syscalls.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-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)
-static inline _syscall2(long,stat,char *,filename,struct stat *,statbuf)
-
-static inline pid_t waitpid(int pid, int *wait_stat, int flags)
-{
-	return sys_wait4(pid, wait_stat, flags, NULL);
-}
-struct mmap_arg_struct;
-asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg);
-
-asmlinkage long sys_execve(struct pt_regs regs);
-asmlinkage long sys_clone(struct pt_regs regs);
-asmlinkage long sys_fork(struct pt_regs regs);
-asmlinkage long sys_vfork(struct pt_regs regs);
-asmlinkage long sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-sh/.gitignore b/include/asm-sh/.gitignore
new file mode 100644
index 0000000..9218ef8
--- /dev/null
+++ b/include/asm-sh/.gitignore
@@ -0,0 +1,3 @@
+cpu
+mach
+machtypes.h
diff --git a/include/asm-sh/bigsur/io.h b/include/asm-sh/bigsur/io.h
index 939735e..1470ac8 100644
--- a/include/asm-sh/bigsur/io.h
+++ b/include/asm-sh/bigsur/io.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_bigsur.h
+ * include/asm-sh/bigsur/io.h
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  * Derived from io_hd64465.h, which bore the message:
diff --git a/include/asm-sh/bigsur/serial.h b/include/asm-sh/bigsur/serial.h
index 7233af4..a08fa82 100644
--- a/include/asm-sh/bigsur/serial.h
+++ b/include/asm-sh/bigsur/serial.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/serial-bigsur.h
+ * include/asm-sh/bigsur/serial.h
  *
  * Configuration details for Big Sur 16550 based serial ports 
  * i.e. HD64465, PCMCIA, etc.
diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h
index b4000c8..beeea40 100644
--- a/include/asm-sh/bugs.h
+++ b/include/asm-sh/bugs.h
@@ -18,7 +18,7 @@
 {
 	extern char *get_cpu_subtype(void);
 	extern unsigned long loops_per_jiffy;
-	char *p= &system_utsname.machine[2]; /* "sh" */
+	char *p= &init_utsname()->machine[2]; /* "sh" */
 
 	cpu_data->loops_per_jiffy = loops_per_jiffy;
 
diff --git a/include/asm-sh/cpu-sh3/rtc.h b/include/asm-sh/cpu-sh3/rtc.h
deleted file mode 100644
index 2d92667..0000000
--- a/include/asm-sh/cpu-sh3/rtc.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __ASM_CPU_SH3_RTC_H
-#define __ASM_CPU_SH3_RTC_H
-
-/* SH-3 RTC */
-#define R64CNT  	0xfffffec0
-#define RSECCNT 	0xfffffec2
-#define RMINCNT 	0xfffffec4
-#define RHRCNT  	0xfffffec6
-#define RWKCNT  	0xfffffec8
-#define RDAYCNT 	0xfffffeca
-#define RMONCNT 	0xfffffecc
-#define RYRCNT  	0xfffffece
-#define RSECAR  	0xfffffed0
-#define RMINAR  	0xfffffed2
-#define RHRAR   	0xfffffed4
-#define RWKAR   	0xfffffed6
-#define RDAYAR  	0xfffffed8
-#define RMONAR  	0xfffffeda
-#define RCR1    	0xfffffedc
-#define RCR2    	0xfffffede
-
-#define RTC_BIT_INVERTED	0	/* No bug on SH7708, SH7709A */
-
-#endif /* __ASM_CPU_SH3_RTC_H */
-
diff --git a/include/asm-sh/cpu-sh4/rtc.h b/include/asm-sh/cpu-sh4/rtc.h
deleted file mode 100644
index e091e32..0000000
--- a/include/asm-sh/cpu-sh4/rtc.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __ASM_CPU_SH4_RTC_H
-#define __ASM_CPU_SH4_RTC_H
-
-/* SH-4 RTC */
-#define R64CNT  	0xffc80000
-#define RSECCNT 	0xffc80004
-#define RMINCNT 	0xffc80008
-#define RHRCNT  	0xffc8000c
-#define RWKCNT  	0xffc80010
-#define RDAYCNT 	0xffc80014
-#define RMONCNT 	0xffc80018
-#define RYRCNT  	0xffc8001c  /* 16bit */
-#define RSECAR  	0xffc80020
-#define RMINAR  	0xffc80024
-#define RHRAR   	0xffc80028
-#define RWKAR   	0xffc8002c
-#define RDAYAR  	0xffc80030
-#define RMONAR  	0xffc80034
-#define RCR1    	0xffc80038
-#define RCR2    	0xffc8003c
-
-#define RTC_BIT_INVERTED	0x40	/* bug on SH7750, SH7750S */
-
-#endif /* __ASM_CPU_SH4_RTC_H */
-
diff --git a/include/asm-sh/dreamcast/sysasic.h b/include/asm-sh/dreamcast/sysasic.h
index c885853..7874e3d 100644
--- a/include/asm-sh/dreamcast/sysasic.h
+++ b/include/asm-sh/dreamcast/sysasic.h
@@ -1,4 +1,4 @@
-/* include/asm-sh/dc_sysasic.h
+/* include/asm-sh/dreamcast/sysasic.h
  *
  * Definitions for the Dreamcast System ASIC and related peripherals.
  *
diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h
index 3a07ab4..fc050fd 100644
--- a/include/asm-sh/elf.h
+++ b/include/asm-sh/elf.h
@@ -1,7 +1,6 @@
 #ifndef __ASM_SH_ELF_H
 #define __ASM_SH_ELF_H
 
-#include <asm/processor.h>
 #include <asm/auxvec.h>
 #include <asm/ptrace.h>
 #include <asm/user.h>
diff --git a/include/asm-sh/hd64465/io.h b/include/asm-sh/hd64465/io.h
index 1100bcf..139f147 100644
--- a/include/asm-sh/hd64465/io.h
+++ b/include/asm-sh/hd64465/io.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_hd64465.h
+ * include/asm-sh/hd64465/io.h
  *
  * By Greg Banks <gbanks@pocketpenguins.com>
  * (c) 2000 PocketPenguins Inc.
diff --git a/include/asm-sh/hs7751rvoip/io.h b/include/asm-sh/hs7751rvoip/io.h
deleted file mode 100644
index 513c851..0000000
--- a/include/asm-sh/hs7751rvoip/io.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * include/asm-sh/hs7751rvoip/hs7751rvoip.h
- *
- * Modified version of io_se.h for the hs7751rvoip-specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an Renesas Technology sales HS7751RVOIP
- */
-
-#ifndef _ASM_SH_IO_HS7751RVOIP_H
-#define _ASM_SH_IO_HS7751RVOIP_H
-
-#include <asm/io_generic.h>
-
-extern unsigned char hs7751rvoip_inb(unsigned long port);
-extern unsigned short hs7751rvoip_inw(unsigned long port);
-extern unsigned int hs7751rvoip_inl(unsigned long port);
-
-extern void hs7751rvoip_outb(unsigned char value, unsigned long port);
-extern void hs7751rvoip_outw(unsigned short value, unsigned long port);
-extern void hs7751rvoip_outl(unsigned int value, unsigned long port);
-
-extern unsigned char hs7751rvoip_inb_p(unsigned long port);
-extern void hs7751rvoip_outb_p(unsigned char value, unsigned long port);
-
-extern void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size);
-
-extern unsigned long hs7751rvoip_isa_port2addr(unsigned long offset);
-
-#endif /* _ASM_SH_IO_HS7751RVOIP_H */
diff --git a/include/asm-sh/mpc1211/io.h b/include/asm-sh/mpc1211/io.h
index eba8a0b..6298370 100644
--- a/include/asm-sh/mpc1211/io.h
+++ b/include/asm-sh/mpc1211/io.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_mpc1211.h
+ * include/asm-sh/mpc1211/io.h
  *
  * Copyright 2001 Saito.K & Jeanne
  *
diff --git a/include/asm-sh/rts7751r2d/io.h b/include/asm-sh/rts7751r2d/io.h
deleted file mode 100644
index 2410940..0000000
--- a/include/asm-sh/rts7751r2d/io.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * include/asm-sh/io_rts7751r2d.h
- *
- * Modified version of io_se.h for the rts7751r2d-specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an Renesas Technology sales RTS7751R2D
- */
-
-#ifndef _ASM_SH_IO_RTS7751R2D_H
-#define _ASM_SH_IO_RTS7751R2D_H
-
-extern unsigned char rts7751r2d_inb(unsigned long port);
-extern unsigned short rts7751r2d_inw(unsigned long port);
-extern unsigned int rts7751r2d_inl(unsigned long port);
-
-extern void rts7751r2d_outb(unsigned char value, unsigned long port);
-extern void rts7751r2d_outw(unsigned short value, unsigned long port);
-extern void rts7751r2d_outl(unsigned int value, unsigned long port);
-
-extern unsigned char rts7751r2d_inb_p(unsigned long port);
-extern void rts7751r2d_outb_p(unsigned char value, unsigned long port);
-
-extern void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern void *rts7751r2d_ioremap(unsigned long offset, unsigned long size);
-
-extern unsigned long rts7751r2d_isa_port2addr(unsigned long offset);
-
-#endif /* _ASM_SH_IO_RTS7751R2D_H */
diff --git a/include/asm-sh/rts7751r2d/rts7751r2d.h b/include/asm-sh/rts7751r2d/rts7751r2d.h
index b112ae2..796b8fc 100644
--- a/include/asm-sh/rts7751r2d/rts7751r2d.h
+++ b/include/asm-sh/rts7751r2d/rts7751r2d.h
@@ -68,4 +68,7 @@
 #define IRQ_PCISLOT2	10		/* PCI Slot #2 IRQ */
 #define	IRQ_EXTENTION	11		/* EXTn IRQ */
 
+#define __IO_PREFIX rts7751r2d
+#include <asm/io_generic.h>
+
 #endif  /* __ASM_SH_RENESAS_RTS7751R2D */
diff --git a/include/asm-sh/sfp-machine.h b/include/asm-sh/sfp-machine.h
index 8a6399a..d3c5484 100644
--- a/include/asm-sh/sfp-machine.h
+++ b/include/asm-sh/sfp-machine.h
@@ -25,8 +25,6 @@
 #ifndef _SFP_MACHINE_H
 #define _SFP_MACHINE_H
 
-#include <linux/config.h>
-
 #define _FP_W_TYPE_SIZE		32
 #define _FP_W_TYPE		unsigned long
 #define _FP_WS_TYPE		signed long
diff --git a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h
index 54458fd..2586eef 100644
--- a/include/asm-sh/spinlock.h
+++ b/include/asm-sh/spinlock.h
@@ -88,7 +88,14 @@
 	__raw_spin_unlock(&rw->lock);
 }
 
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
+static inline int __raw_read_trylock(raw_rwlock_t *lock)
+{
+	atomic_t *count = (atomic_t*)lock;
+	if (atomic_dec_return(count) >= 0)
+		return 1;
+	atomic_inc(count);
+	return 0;
+}
 
 static inline int __raw_write_trylock(raw_rwlock_t *rw)
 {
diff --git a/include/asm-sh/string.h b/include/asm-sh/string.h
index 3e0cff0..95bc7db 100644
--- a/include/asm-sh/string.h
+++ b/include/asm-sh/string.h
@@ -1,13 +1,15 @@
 #ifndef __ASM_SH_STRING_H
 #define __ASM_SH_STRING_H
 
+#ifdef __KERNEL__
+
 /*
  * Copyright (C) 1999 Niibe Yutaka
  * But consider these trivial functions to be public domain.
  */
 
 #define __HAVE_ARCH_STRCPY
-static __inline__ char *strcpy(char *__dest, const char *__src)
+static inline char *strcpy(char *__dest, const char *__src)
 {
 	register char *__xdest = __dest;
 	unsigned long __dummy;
@@ -26,7 +28,7 @@
 }
 
 #define __HAVE_ARCH_STRNCPY
-static __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
+static inline char *strncpy(char *__dest, const char *__src, size_t __n)
 {
 	register char *__xdest = __dest;
 	unsigned long __dummy;
@@ -52,7 +54,7 @@
 }
 
 #define __HAVE_ARCH_STRCMP
-static __inline__ int strcmp(const char *__cs, const char *__ct)
+static inline int strcmp(const char *__cs, const char *__ct)
 {
 	register int __res;
 	unsigned long __dummy;
@@ -78,7 +80,7 @@
 }
 
 #define __HAVE_ARCH_STRNCMP
-static __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
+static inline int strncmp(const char *__cs, const char *__ct, size_t __n)
 {
 	register int __res;
 	unsigned long __dummy;
@@ -124,4 +126,9 @@
 #define __HAVE_ARCH_STRLEN
 extern size_t strlen(const char *);
 
+/* arch/sh/lib/strcasecmp.c */
+extern int strcasecmp(const char *, const char *);
+
+#endif /* __KERNEL__ */
+
 #endif /* __ASM_SH_STRING_H */
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index 5d5e9f9..f1a0cbc 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -472,76 +472,6 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static __inline__ _syscall0(int,pause)
-static __inline__ _syscall0(int,sync)
-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)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static __inline__ _syscall1(int,delete_module,const char *,name)
-
-static __inline__ pid_t wait(int * wait_stat)
-{
-	return waitpid(-1,wait_stat,0);
-}
-
-asmlinkage long sys_mmap2(
-			unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *ufilename, char **uargv,
-			char **uenvp, unsigned long r7,
-			struct pt_regs regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-			unsigned long parent_tidptr,
-			unsigned long child_tidptr,
-			struct pt_regs regs);
-asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
-			unsigned long r6, unsigned long r7,
-			struct pt_regs regs);
-asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
-			unsigned long r6, unsigned long r7,
-			struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
-			unsigned long r6, unsigned long r7,
-			struct pt_regs regs);
-asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
-				size_t count, long dummy, loff_t pos);
-asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
-				size_t count, long dummy, loff_t pos);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-sh64/serial.h b/include/asm-sh64/serial.h
index 29c9be1..e8d7b3f 100644
--- a/include/asm-sh64/serial.h
+++ b/include/asm-sh64/serial.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/serial.h
+ * include/asm-sh64/serial.h
  *
  * Configuration details for 8250, 16450, 16550, etc. serial ports
  */
diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h
index c113566..ee7828b 100644
--- a/include/asm-sh64/unistd.h
+++ b/include/asm-sh64/unistd.h
@@ -513,47 +513,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-/* Copy from sh */
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall1(int,setup,int,magic)
-static inline _syscall0(int,sync)
-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)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
-	return waitpid(-1,wait_stat,0);
-}
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-sparc/reg.h b/include/asm-sparc/reg.h
index ed60ebe..ea0a7e5 100644
--- a/include/asm-sparc/reg.h
+++ b/include/asm-sparc/reg.h
@@ -1,5 +1,5 @@
 /*
- * linux/asm-sparc/reg.h
+ * linux/include/asm-sparc/reg.h
  * Layout of the registers as expected by gdb on the Sparc
  * we should replace the user.h definitions with those in
  * this file, we don't even use the other 
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 2553762..c7a495a 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -478,53 +478,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-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)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-#include <linux/linkage.h>
-
-asmlinkage unsigned long sys_mmap(
-				unsigned long addr, unsigned long len,
-				unsigned long prot, unsigned long flags,
-				unsigned long fd, unsigned long off);
-asmlinkage unsigned long sys_mmap2(
-				unsigned long addr, unsigned long len,
-				unsigned long prot, unsigned long flags,
-				unsigned long fd, unsigned long pgoff);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				void __user *restorer,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-sparc64/compat_signal.h b/include/asm-sparc64/compat_signal.h
new file mode 100644
index 0000000..7aefa30
--- /dev/null
+++ b/include/asm-sparc64/compat_signal.h
@@ -0,0 +1,30 @@
+#ifndef _COMPAT_SIGNAL_H
+#define _COMPAT_SIGNAL_H
+
+#include <linux/config.h>
+#include <linux/compat.h>
+#include <asm/signal.h>
+
+#ifdef CONFIG_COMPAT
+struct __new_sigaction32 {
+	unsigned		sa_handler;
+	unsigned int    	sa_flags;
+	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
+	compat_sigset_t 	sa_mask;
+};
+
+struct __old_sigaction32 {
+	unsigned		sa_handler;
+	compat_old_sigset_t  	sa_mask;
+	unsigned int    	sa_flags;
+	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
+};
+
+typedef struct sigaltstack32 {
+	u32			ss_sp;
+	int			ss_flags;
+	compat_size_t		ss_size;
+} stack_t32;
+#endif
+
+#endif /* !(_COMPAT_SIGNAL_H) */
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
index 9968871..fa6f467 100644
--- a/include/asm-sparc64/signal.h
+++ b/include/asm-sparc64/signal.h
@@ -8,7 +8,6 @@
 #ifndef __ASSEMBLY__
 #include <linux/personality.h>
 #include <linux/types.h>
-#include <linux/compat.h>
 #endif
 #endif
 
@@ -167,23 +166,6 @@
 	__new_sigset_t		sa_mask;
 };
 
-#ifdef __KERNEL__
-
-#ifdef CONFIG_COMPAT
-struct __new_sigaction32 {
-	unsigned		sa_handler;
-	unsigned int    	sa_flags;
-	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
-	compat_sigset_t 	sa_mask;
-};
-#endif
-
-struct k_sigaction {
-	struct __new_sigaction 	sa;
-	void __user		*ka_restorer;
-};
-#endif
-
 struct __old_sigaction {
 	__sighandler_t  	sa_handler;
 	__old_sigset_t  	sa_mask;
@@ -191,19 +173,6 @@
 	void 			(*sa_restorer)(void);     /* not used by Linux/SPARC yet */
 };
 
-#ifdef __KERNEL__
-
-#ifdef CONFIG_COMPAT
-struct __old_sigaction32 {
-	unsigned		sa_handler;
-	compat_old_sigset_t  	sa_mask;
-	unsigned int    	sa_flags;
-	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
-};
-#endif
-
-#endif
-
 typedef struct sigaltstack {
 	void			__user *ss_sp;
 	int			ss_flags;
@@ -212,13 +181,10 @@
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_COMPAT
-typedef struct sigaltstack32 {
-	u32			ss_sp;
-	int			ss_flags;
-	compat_size_t		ss_size;
-} stack_t32;
-#endif
+struct k_sigaction {
+	struct __new_sigaction 	sa;
+	void __user		*ka_restorer;
+};
 
 struct signal_deliver_cookie {
 	int restart_syscall;
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index badc73f..124cf07 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -445,48 +445,6 @@
 errno = -__res; \
 return -1; \
 }
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-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)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-#include <linux/linkage.h>
-
-asmlinkage unsigned long sys_mmap(
-				unsigned long addr, unsigned long len,
-				unsigned long prot, unsigned long flags,
-				unsigned long fd, unsigned long off);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				void __user *restorer,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
 
 /* sysconf options, for SunOS compatibility */
 #define   _SC_ARG_MAX             1
diff --git a/include/asm-um/unistd.h b/include/asm-um/unistd.h
index afccfca..732c83f 100644
--- a/include/asm-um/unistd.h
+++ b/include/asm-um/unistd.h
@@ -37,34 +37,6 @@
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-static inline int execve(const char *filename, char *const argv[],
-			 char *const envp[])
-{
-	mm_segment_t fs;
-	int ret;
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = um_execve(filename, argv, envp);
-	set_fs(fs);
-
-	if (ret >= 0)
-		return ret;
-
-	errno = -(long)ret;
-	return -1;
-}
-
-int sys_execve(char *file, char **argv, char **env);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
-#undef __KERNEL_SYSCALLS__
 #include "asm/arch/unistd.h"
 
 #endif /* _UM_UNISTD_H_*/
diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
index 552b7c8..737401e 100644
--- a/include/asm-v850/unistd.h
+++ b/include/asm-v850/unistd.h
@@ -387,57 +387,6 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * 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)
-extern inline _syscall1(int,_exit,int,exitcode)
-extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-extern inline pid_t wait(int * wait_stat)
-{
-	return waitpid (-1, wait_stat, 0);
-}
-
-unsigned long sys_mmap(unsigned long addr, size_t len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, off_t offset);
-unsigned long sys_mmap2(unsigned long addr, size_t len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-struct pt_regs;
-int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
-int sys_pipe (int *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  */
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h
index ed8a9d2..052df75 100644
--- a/include/asm-x86_64/cache.h
+++ b/include/asm-x86_64/cache.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-x8664/cache.h
+ * include/asm-x86_64/cache.h
  */
 #ifndef __ARCH_X8664_CACHE_H
 #define __ARCH_X8664_CACHE_H
diff --git a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h
index 64a65ce..95d5e09 100644
--- a/include/asm-x86_64/hardirq.h
+++ b/include/asm-x86_64/hardirq.h
@@ -6,6 +6,9 @@
 #include <asm/pda.h>
 #include <asm/apic.h>
 
+/* We can have at most NR_VECTORS irqs routed to a cpu at a time */
+#define MAX_HARDIRQS_PER_CPU NR_VECTORS
+
 #define __ARCH_IRQ_STAT 1
 
 #define local_softirq_pending() read_pda(__softirq_pending)
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 48a4a53..53d0d9f 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -19,8 +19,7 @@
 #include <asm/irq.h>
 #include <linux/profile.h>
 #include <linux/smp.h>
-
-struct hw_interrupt_type;
+#include <linux/percpu.h>
 #endif
 
 #define NMI_VECTOR		0x02
@@ -75,9 +74,10 @@
 
 
 #ifndef __ASSEMBLY__
-extern u8 irq_vector[NR_IRQ_VECTORS];
+extern unsigned int irq_vector[NR_IRQ_VECTORS];
+typedef int vector_irq_t[NR_VECTORS];
+DECLARE_PER_CPU(vector_irq_t, vector_irq);
 #define IO_APIC_VECTOR(irq)	(irq_vector[irq])
-#define AUTO_ASSIGN		-1
 
 /*
  * Various low-level irq details needed by irq.c, process.c,
diff --git a/include/asm-x86_64/hypertransport.h b/include/asm-x86_64/hypertransport.h
new file mode 100644
index 0000000..c16c6ff
--- /dev/null
+++ b/include/asm-x86_64/hypertransport.h
@@ -0,0 +1,42 @@
+#ifndef ASM_HYPERTRANSPORT_H
+#define ASM_HYPERTRANSPORT_H
+
+/*
+ * Constants for x86 Hypertransport Interrupts.
+ */
+
+#define HT_IRQ_LOW_BASE			0xf8000000
+
+#define HT_IRQ_LOW_VECTOR_SHIFT		16
+#define  HT_IRQ_LOW_VECTOR_MASK		0x00ff0000
+#define  HT_IRQ_LOW_VECTOR(v)		(((v) << HT_IRQ_LOW_VECTOR_SHIFT) & HT_IRQ_LOW_VECTOR_MASK)
+
+#define HT_IRQ_LOW_DEST_ID_SHIFT	8
+#define  HT_IRQ_LOW_DEST_ID_MASK	0x0000ff00
+#define  HT_IRQ_LOW_DEST_ID(v)		(((v) << HT_IRQ_LOW_DEST_ID_SHIFT) & HT_IRQ_LOW_DEST_ID_MASK)
+
+#define HT_IRQ_LOW_DM_PHYSICAL		0x0000000
+#define HT_IRQ_LOW_DM_LOGICAL		0x0000040
+
+#define HT_IRQ_LOW_RQEOI_EDGE		0x0000000
+#define HT_IRQ_LOW_RQEOI_LEVEL		0x0000020
+
+
+#define HT_IRQ_LOW_MT_FIXED		0x0000000
+#define HT_IRQ_LOW_MT_ARBITRATED	0x0000004
+#define HT_IRQ_LOW_MT_SMI		0x0000008
+#define HT_IRQ_LOW_MT_NMI		0x000000c
+#define HT_IRQ_LOW_MT_INIT		0x0000010
+#define HT_IRQ_LOW_MT_STARTUP		0x0000014
+#define HT_IRQ_LOW_MT_EXTINT		0x0000018
+#define HT_IRQ_LOW_MT_LINT1		0x000008c
+#define HT_IRQ_LOW_MT_LINT0		0x0000098
+
+#define HT_IRQ_LOW_IRQ_MASKED		0x0000001
+
+
+#define HT_IRQ_HIGH_DEST_ID_SHIFT	0
+#define  HT_IRQ_HIGH_DEST_ID_MASK	0x00ffffff
+#define  HT_IRQ_HIGH_DEST_ID(v)		((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
+
+#endif /* ASM_HYPERTRANSPORT_H */
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 5d1b5c6..171ec2d 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -10,46 +10,6 @@
  * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
  */
 
-#ifdef CONFIG_PCI_MSI
-static inline int use_pci_vector(void)	{return 1;}
-static inline void disable_edge_ioapic_vector(unsigned int vector) { }
-static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
-static inline void end_edge_ioapic_vector (unsigned int vector) { }
-#define startup_level_ioapic	startup_level_ioapic_vector
-#define shutdown_level_ioapic	mask_IO_APIC_vector
-#define enable_level_ioapic	unmask_IO_APIC_vector
-#define disable_level_ioapic	mask_IO_APIC_vector
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
-#define end_level_ioapic	end_level_ioapic_vector
-#define set_ioapic_affinity	set_ioapic_affinity_vector
-
-#define startup_edge_ioapic 	startup_edge_ioapic_vector
-#define shutdown_edge_ioapic 	disable_edge_ioapic_vector
-#define enable_edge_ioapic 	unmask_IO_APIC_vector
-#define disable_edge_ioapic 	disable_edge_ioapic_vector
-#define ack_edge_ioapic 	ack_edge_ioapic_vector
-#define end_edge_ioapic 	end_edge_ioapic_vector
-#else
-static inline int use_pci_vector(void)	{return 0;}
-static inline void disable_edge_ioapic_irq(unsigned int irq) { }
-static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
-static inline void end_edge_ioapic_irq (unsigned int irq) { }
-#define startup_level_ioapic	startup_level_ioapic_irq
-#define shutdown_level_ioapic	mask_IO_APIC_irq
-#define enable_level_ioapic	unmask_IO_APIC_irq
-#define disable_level_ioapic	mask_IO_APIC_irq
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
-#define end_level_ioapic	end_level_ioapic_irq
-#define set_ioapic_affinity	set_ioapic_affinity_irq
-
-#define startup_edge_ioapic 	startup_edge_ioapic_irq
-#define shutdown_edge_ioapic 	disable_edge_ioapic_irq
-#define enable_edge_ioapic 	unmask_IO_APIC_irq
-#define disable_edge_ioapic 	disable_edge_ioapic_irq
-#define ack_edge_ioapic 	ack_edge_ioapic_irq
-#define end_edge_ioapic 	end_edge_ioapic_irq
-#endif
-
 #define APIC_MISMATCH_DEBUG
 
 #define IO_APIC_BASE(idx) \
@@ -202,13 +162,10 @@
 extern int io_apic_get_version (int ioapic);
 extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int);
-extern int timer_uses_ioapic_pin_0;
 #endif
 
 extern int sis_apic_bug; /* dummy */ 
 
-extern int assign_irq_vector(int irq);
-
 void enable_NMI_through_LVT0 (void * dummy);
 
 extern spinlock_t i8259A_lock;
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
index 43469d8a..5006c6e 100644
--- a/include/asm-x86_64/irq.h
+++ b/include/asm-x86_64/irq.h
@@ -31,13 +31,8 @@
 
 #define FIRST_SYSTEM_VECTOR	0xef   /* duplicated in hw_irq.h */
 
-#ifdef CONFIG_PCI_MSI
-#define NR_IRQS FIRST_SYSTEM_VECTOR
+#define NR_IRQS (NR_VECTORS + (32 *NR_CPUS))
 #define NR_IRQ_VECTORS NR_IRQS
-#else
-#define NR_IRQS 224
-#define NR_IRQ_VECTORS (32 * NR_CPUS)
-#endif
 
 static __inline__ int irq_canonicalize(int irq)
 {
diff --git a/include/asm-x86_64/msi.h b/include/asm-x86_64/msi.h
deleted file mode 100644
index 3ad23466..0000000
--- a/include/asm-x86_64/msi.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
- */
-
-#ifndef ASM_MSI_H
-#define ASM_MSI_H
-
-#include <asm/desc.h>
-#include <asm/mach_apic.h>
-#include <asm/smp.h>
-
-#define LAST_DEVICE_VECTOR	(FIRST_SYSTEM_VECTOR - 1)
-#define MSI_TARGET_CPU_SHIFT	12
-
-extern struct msi_ops msi_apic_ops;
-
-static inline int msi_arch_init(void)
-{
-	msi_register(&msi_apic_ops);
-	return 0;
-}
-
-#endif /* ASM_MSI_H */
diff --git a/include/asm-x86_64/msidef.h b/include/asm-x86_64/msidef.h
new file mode 100644
index 0000000..5b8acdd
--- /dev/null
+++ b/include/asm-x86_64/msidef.h
@@ -0,0 +1,47 @@
+#ifndef ASM_MSIDEF_H
+#define ASM_MSIDEF_H
+
+/*
+ * Constants for Intel APIC based MSI messages.
+ */
+
+/*
+ * Shifts for MSI data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT		0
+#define  MSI_DATA_VECTOR_MASK		0x000000ff
+#define	 MSI_DATA_VECTOR(v)		(((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK)
+
+#define MSI_DATA_DELIVERY_MODE_SHIFT	8
+#define  MSI_DATA_DELIVERY_FIXED	(0 << MSI_DATA_DELIVERY_MODE_SHIFT)
+#define  MSI_DATA_DELIVERY_LOWPRI	(1 << MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT		14
+#define	 MSI_DATA_LEVEL_DEASSERT	(0 << MSI_DATA_LEVEL_SHIFT)
+#define	 MSI_DATA_LEVEL_ASSERT		(1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT		15
+#define  MSI_DATA_TRIGGER_EDGE		(0 << MSI_DATA_TRIGGER_SHIFT)
+#define  MSI_DATA_TRIGGER_LEVEL		(1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for msi address
+ */
+
+#define MSI_ADDR_BASE_HI		0
+#define MSI_ADDR_BASE_LO		0xfee00000
+
+#define MSI_ADDR_DEST_MODE_SHIFT	2
+#define  MSI_ADDR_DEST_MODE_PHYSICAL	(0 << MSI_ADDR_DEST_MODE_SHIFT)
+#define	 MSI_ADDR_DEST_MODE_LOGICAL	(1 << MSI_ADDR_DEST_MODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT	3
+#define  MSI_ADDR_REDIRECTION_CPU	(0 << MSI_ADDR_REDIRECTION_SHIFT) /* dedicated cpu */
+#define  MSI_ADDR_REDIRECTION_LOWPRI	(1 << MSI_ADDR_REDIRECTION_SHIFT) /* lowest priority */
+
+#define MSI_ADDR_DEST_ID_SHIFT		12
+#define	 MSI_ADDR_DEST_ID_MASK		0x00ffff0
+#define  MSI_ADDR_DEST_ID(dest)		(((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK)
+
+#endif /* ASM_MSIDEF_H */
diff --git a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h
index ab827dc..5ea84db 100644
--- a/include/asm-x86_64/ptrace.h
+++ b/include/asm-x86_64/ptrace.h
@@ -39,6 +39,8 @@
 #define user_mode(regs) (!!((regs)->cs & 3))
 #define user_mode_vm(regs) user_mode(regs)
 #define instruction_pointer(regs) ((regs)->rip)
+#define regs_return_value(regs) ((regs)->rax)
+
 extern unsigned long profile_pc(struct pt_regs *regs);
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index 6e7a2e9..5c8f492 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -31,6 +31,7 @@
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 6137146..777288e 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -620,10 +620,11 @@
 #define __NR_move_pages		279
 __SYSCALL(__NR_move_pages, sys_move_pages)
 
-#ifdef __KERNEL__
-
 #define __NR_syscall_max __NR_move_pages
+
+#ifdef __KERNEL__
 #include <linux/err.h>
+#endif
 
 #ifndef __NO_STUBS
 
@@ -663,8 +664,6 @@
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_TIME
 
-#ifndef __KERNEL_SYSCALLS__
-
 #define __syscall "syscall"
 
 #define _syscall0(type,name) \
@@ -746,83 +745,7 @@
 __syscall_return(type,__res); \
 }
 
-#else /* __KERNEL_SYSCALLS__ */
-
-#include <linux/syscalls.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-
-static inline pid_t setsid(void)
-{
-	return sys_setsid();
-}
-
-static inline ssize_t write(unsigned int fd, char * buf, size_t count)
-{
-	return sys_write(fd, buf, count);
-}
-
-static inline ssize_t read(unsigned int fd, char * buf, size_t count)
-{
-	return sys_read(fd, buf, count);
-}
-
-static inline off_t lseek(unsigned int fd, off_t offset, unsigned int origin)
-{
-	return sys_lseek(fd, offset, origin);
-}
-
-static inline long dup(unsigned int fd)
-{
-	return sys_dup(fd);
-}
-
-/* implemented in asm in arch/x86_64/kernel/entry.S */
-extern int execve(const char *, char * const *, char * const *);
-
-static inline long open(const char * filename, int flags, int mode)
-{
-	return sys_open(filename, flags, mode);
-}
-
-static inline long close(unsigned int fd)
-{
-	return sys_close(fd);
-}
-
-static inline pid_t waitpid(int pid, int * wait_stat, int flags)
-{
-	return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-extern long sys_mmap(unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long off);
-
-extern int sys_modify_ldt(int func, void *ptr, unsigned long bytecount);
-
-asmlinkage long sys_execve(char *name, char **argv, char **envp,
-			struct pt_regs regs);
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
-			void *parent_tid, void *child_tid,
-			struct pt_regs regs);
-asmlinkage long sys_fork(struct pt_regs regs);
-asmlinkage long sys_vfork(struct pt_regs regs);
-asmlinkage long sys_pipe(int *fildes);
-
+#ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
 #include <linux/linkage.h>
@@ -839,8 +762,8 @@
 				size_t sigsetsize);
 
 #endif  /* __ASSEMBLY__ */
-
-#endif /* __KERNEL_SYSCALLS__ */
+#endif	/* __KERNEL__ */
+#endif	/* __NO_STUBS */
 
 /*
  * "Conditional" syscalls
@@ -850,8 +773,4 @@
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 
-#endif /* __NO_STUBS */
-
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_X86_64_UNISTD_H_ */
diff --git a/include/asm-xtensa/a.out.h b/include/asm-xtensa/a.out.h
index 3be701d..ffc4dcf 100644
--- a/include/asm-xtensa/a.out.h
+++ b/include/asm-xtensa/a.out.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/addrspace.h
+ * include/asm-xtensa/a.out.h
  *
  * Dummy a.out file. Xtensa does not support the a.out format, but the kernel
  * seems to depend on it.
diff --git a/include/asm-xtensa/cache.h b/include/asm-xtensa/cache.h
index 5aae3f1..1e79c0e 100644
--- a/include/asm-xtensa/cache.h
+++ b/include/asm-xtensa/cache.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/cacheflush.h
+ * include/asm-xtensa/cache.h
  *
  * 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
diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h
index a91b96d..5093034 100644
--- a/include/asm-xtensa/coprocessor.h
+++ b/include/asm-xtensa/coprocessor.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/cpextra.h
+ * include/asm-xtensa/coprocessor.h
  *
  * 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
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index c425f10..c39c91d 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/dma_mapping.h
+ * include/asm-xtensa/dma-mapping.h
  *
  * 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
diff --git a/include/asm-xtensa/ioctls.h b/include/asm-xtensa/ioctls.h
index 3b89a77..39e6f23 100644
--- a/include/asm-xtensa/ioctls.h
+++ b/include/asm-xtensa/ioctls.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/ioctl.h
+ * include/asm-xtensa/ioctls.h
  *
  * 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
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
index a47cc73..b431893 100644
--- a/include/asm-xtensa/pgtable.h
+++ b/include/asm-xtensa/pgtable.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-xtensa/page.h
+ * linux/include/asm-xtensa/pgtable.h
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version2 as
diff --git a/include/asm-xtensa/siginfo.h b/include/asm-xtensa/siginfo.h
index 44f0ae7..6916248 100644
--- a/include/asm-xtensa/siginfo.h
+++ b/include/asm-xtensa/siginfo.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/processor.h
+ * include/asm-xtensa/siginfo.h
  *
  * 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
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h
index 5e1b99d..411f810 100644
--- a/include/asm-xtensa/unistd.h
+++ b/include/asm-xtensa/unistd.h
@@ -402,11 +402,6 @@
 __syscall_return(type,__res); \
 }
 
-
-#ifdef __KERNEL_SYSCALLS__
-static __inline__ _syscall3(int,execve,const char*,file,char**,argv,char**,envp)
-#endif
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 15667cc..ea005c0 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -158,12 +158,10 @@
 header-y += ultrasound.h
 header-y += un.h
 header-y += utime.h
-header-y += utsname.h
 header-y += video_decoder.h
 header-y += video_encoder.h
 header-y += videotext.h
 header-y += vt.h
-header-y += wavefront.h
 header-y += wireless.h
 header-y += xattr.h
 header-y += x25.h
@@ -337,6 +335,7 @@
 unifdef-y += usb_ch9.h
 unifdef-y += usbdevice_fs.h
 unifdef-y += user.h
+unifdef-y += utsname.h
 unifdef-y += videodev2.h
 unifdef-y += videodev.h
 unifdef-y += wait.h
diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h
index 2ed2fd8..22eb936 100644
--- a/include/linux/ac97_codec.h
+++ b/include/linux/ac97_codec.h
@@ -331,8 +331,6 @@
 extern int ac97_probe_codec(struct ac97_codec *);
 extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
 extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
-extern int ac97_save_state(struct ac97_codec *codec);
-extern int ac97_restore_state(struct ac97_codec *codec);
 
 extern struct ac97_codec *ac97_alloc_codec(void);
 extern void ac97_release_codec(struct ac97_codec *codec);
@@ -346,9 +344,6 @@
 	void (*remove) (struct ac97_codec *codec, struct ac97_driver *driver);
 };
 
-extern int ac97_register_driver(struct ac97_driver *driver);
-extern void ac97_unregister_driver(struct ac97_driver *driver);
-
 /* quirk types */
 enum {
 	AC97_TUNE_DEFAULT = -1, /* use default from quirk list (not valid in list) */
diff --git a/include/linux/aio_abi.h b/include/linux/aio_abi.h
index 3466b1d..e3ca0a4 100644
--- a/include/linux/aio_abi.h
+++ b/include/linux/aio_abi.h
@@ -1,4 +1,4 @@
-/* linux/aio_abi.h
+/* include/linux/aio_abi.h
  *
  * Copyright 2000,2001,2002 Red Hat.
  *
diff --git a/include/linux/audit.h b/include/linux/audit.h
index c3aa097..b2ca666 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -75,7 +75,7 @@
 #define AUDIT_DAEMON_CONFIG     1203    /* Daemon config change */
 
 #define AUDIT_SYSCALL		1300	/* Syscall event */
-#define AUDIT_FS_WATCH		1301	/* Filesystem watch event */
+/* #define AUDIT_FS_WATCH	1301	 * Deprecated */
 #define AUDIT_PATH		1302	/* Filename path information */
 #define AUDIT_IPC		1303	/* IPC record */
 #define AUDIT_SOCKETCALL	1304	/* sys_socketcall arguments */
@@ -88,6 +88,7 @@
 #define AUDIT_MQ_SENDRECV	1313	/* POSIX MQ send/receive record type */
 #define AUDIT_MQ_NOTIFY		1314	/* POSIX MQ notify record type */
 #define AUDIT_MQ_GETSETATTR	1315	/* POSIX MQ get/set attribute record type */
+#define AUDIT_KERNEL_OTHER	1316	/* For use by 3rd party modules */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
diff --git a/include/linux/awe_voice.h b/include/linux/awe_voice.h
index 4bf9f33..bf33f17 100644
--- a/include/linux/awe_voice.h
+++ b/include/linux/awe_voice.h
@@ -1,5 +1,5 @@
 /*
- * sound/awe_voice.h
+ * include/linux/awe_voice.h
  *
  * Voice information definitions for the low level driver for the 
  * AWE32/SB32/AWE64 wave table synth.
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 9760753..ef5cd19 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -13,6 +13,7 @@
 
 #include <asm/compat.h>
 #include <asm/siginfo.h>
+#include <asm/signal.h>
 
 #define compat_jiffies_to_clock_t(x)	\
 		(((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
@@ -227,6 +228,7 @@
 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
 
 extern int compat_printk(const char *fmt, ...);
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index d5b7abc..4e1663d 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -122,10 +122,10 @@
 ULONG_IOCTL(HOT_ADD_DISK)
 ULONG_IOCTL(SET_DISK_FAULTY)
 COMPATIBLE_IOCTL(RUN_ARRAY)
-ULONG_IOCTL(START_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY_RO)
 COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+ULONG_IOCTL(SET_BITMAP_FILE)
 /* DM */
 COMPATIBLE_IOCTL(DM_VERSION_32)
 COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
diff --git a/include/linux/console.h b/include/linux/console.h
index 76a1807..7d04202 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -129,6 +129,9 @@
 static inline void resume_console(void) {}
 #endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
 
+int mda_console_init(void);
+void prom_con_init(void);
+
 /* Some debug stub to catch some of the obvious races in the VT code */
 #if 1
 #define WARN_CONSOLE_UNLOCKED()	WARN_ON(!is_console_locked() && !oops_in_progress)
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 25423f7..ed6c0fe 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -54,7 +54,7 @@
 	struct tty_struct *vc_tty;		/* TTY we are attached to */
 	/* data for manual vt switching */
 	struct vt_mode	vt_mode;
-	int		vt_pid;
+	struct pid 	*vt_pid;
 	int		vt_newvt;
 	wait_queue_head_t paste_wait;
 	/* mode flags */
diff --git a/include/linux/consolemap.h b/include/linux/consolemap.h
index 65842ef..82c9a1f 100644
--- a/include/linux/consolemap.h
+++ b/include/linux/consolemap.h
@@ -13,3 +13,4 @@
 extern unsigned char inverse_translate(struct vc_data *conp, int glyph);
 extern unsigned short *set_translate(int m, struct vc_data *vc);
 extern int conv_uni_to_pc(struct vc_data *conp, long ucs);
+void console_map_init(void);
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h
index 88dafa2..952bee7 100644
--- a/include/linux/debug_locks.h
+++ b/include/linux/debug_locks.h
@@ -43,6 +43,8 @@
 # define locking_selftest()	do { } while (0)
 #endif
 
+struct task_struct;
+
 #ifdef CONFIG_LOCKDEP
 extern void debug_show_all_locks(void);
 extern void debug_show_held_locks(struct task_struct *task);
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index e3d1c33..03ef41c 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -55,8 +55,10 @@
 			    struct bio *bio, int error,
 			    union map_info *map_context);
 
+typedef void (*dm_flush_fn) (struct dm_target *ti);
 typedef void (*dm_presuspend_fn) (struct dm_target *ti);
 typedef void (*dm_postsuspend_fn) (struct dm_target *ti);
+typedef int (*dm_preresume_fn) (struct dm_target *ti);
 typedef void (*dm_resume_fn) (struct dm_target *ti);
 
 typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
@@ -64,9 +66,18 @@
 
 typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
 
+typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode,
+			    struct file *filp, unsigned int cmd,
+			    unsigned long arg);
+
 void dm_error(const char *message);
 
 /*
+ * Combine device limits.
+ */
+void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev);
+
+/*
  * Constructors should call these functions to ensure destination devices
  * are opened/closed correctly.
  * FIXME: too many arguments.
@@ -86,11 +97,14 @@
 	dm_dtr_fn dtr;
 	dm_map_fn map;
 	dm_endio_fn end_io;
+	dm_flush_fn flush;
 	dm_presuspend_fn presuspend;
 	dm_postsuspend_fn postsuspend;
+	dm_preresume_fn preresume;
 	dm_resume_fn resume;
 	dm_status_fn status;
 	dm_message_fn message;
+	dm_ioctl_fn ioctl;
 };
 
 struct io_restrictions {
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index 9623bb6..8853fc4 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -285,9 +285,9 @@
 #define DM_DEV_SET_GEOMETRY	_IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR	4
-#define DM_VERSION_MINOR	7
+#define DM_VERSION_MINOR	10
 #define DM_VERSION_PATCHLEVEL	0
-#define DM_VERSION_EXTRA	"-ioctl (2006-06-24)"
+#define DM_VERSION_EXTRA	"-ioctl (2006-09-14)"
 
 /* Status bits */
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2f335e9..3e69241 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -2,6 +2,7 @@
 #define _LINUX_FB_H
 
 #include <asm/types.h>
+#include <linux/i2c.h>
 
 /* Definitions of frame buffers						*/
 
@@ -775,6 +776,7 @@
 	struct fb_ops *fbops;
 	struct device *device;
 	struct class_device *class_device; /* sysfs per device attrs */
+	int class_flag;                    /* private sysfs flags */
 #ifdef CONFIG_FB_TILEBLITTING
 	struct fb_tile_ops *tileops;    /* Tile Blitting */
 #endif
@@ -940,6 +942,7 @@
 				struct fb_monspecs *specs);
 extern void fb_destroy_modedb(struct fb_videomode *modedb);
 extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
+extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
 
 /* drivers/video/modedb.c */
 #define VESA_MODEDB_SIZE 34
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bc0e645..34406ed 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -686,7 +686,8 @@
 
 struct fown_struct {
 	rwlock_t lock;          /* protects pid, uid, euid fields */
-	int pid;		/* pid or -pgrp where SIGIO should be sent */
+	struct pid *pid;	/* pid or -pgrp where SIGIO should be sent */
+	enum pid_type pid_type;	/* Kind of process group SIGIO should be sent to */
 	uid_t uid, euid;	/* uid/euid of process setting the owner */
 	int signum;		/* posix.1b rt signal to be delivered on IO */
 };
@@ -882,8 +883,10 @@
 /* only for net: no internal synchronization */
 extern void __kill_fasync(struct fasync_struct *, int, int);
 
+extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
 extern int f_setown(struct file *filp, unsigned long arg, int force);
 extern void f_delown(struct file *filp);
+extern pid_t f_getown(struct file *filp);
 extern int send_sigurg(struct fown_struct *fown);
 
 /*
@@ -1048,7 +1051,7 @@
  * This allows the kernel to read directories into kernel space or
  * to have different dirent layouts depending on the binary type.
  */
-typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned);
+typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
 
 struct block_device_operations {
 	int (*open) (struct inode *, struct file *);
@@ -1522,6 +1525,9 @@
 #ifdef CONFIG_BLOCK
 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
 extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
+extern int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+			       struct gendisk *disk, unsigned cmd,
+			       unsigned long arg);
 extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
 extern int blkdev_get(struct block_device *, mode_t, unsigned);
 extern int blkdev_put(struct block_device *);
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 74ed35a..543cd3c 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -55,6 +55,30 @@
 	return -1;
 }
 
+static inline int fs_fec_index2id(int index)
+{
+	int id = fsid_fec1 + index - 1;
+	if (id >= fsid_fec1 && id <= fsid_fec2)
+		return id;
+	return FS_MAX_INDEX;
+		}
+
+static inline int fs_fcc_index2id(int index)
+{
+	int id = fsid_fcc1 + index - 1;
+	if (id >= fsid_fcc1 && id <= fsid_fcc3)
+		return id;
+	return FS_MAX_INDEX;
+}
+
+static inline int fs_scc_index2id(int index)
+{
+	int id = fsid_scc1 + index - 1;
+	if (id >= fsid_scc1 && id <= fsid_scc4)
+		return id;
+	return FS_MAX_INDEX;
+}
+
 enum fs_mii_method {
 	fsmii_fixed,
 	fsmii_fec,
@@ -87,18 +111,21 @@
 };
 
 struct fs_platform_info {
-	
-	void(*init_ioports)(void);
+
+	void(*init_ioports)(struct fs_platform_info *);
 	/* device specific information */
 	int fs_no;		/* controller index            */
+	char fs_type[4];	/* controller type             */
 
 	u32 cp_page;		/* CPM page */
 	u32 cp_block;		/* CPM sblock */
-	
+
 	u32 clk_trx;		/* some stuff for pins & mux configuration*/
+	u32 clk_rx;
+	u32 clk_tx;
 	u32 clk_route;
 	u32 clk_mask;
-	
+
 	u32 mem_offset;
 	u32 dpram_offset;
 	u32 fcc_regs_c;
@@ -124,4 +151,16 @@
 	u32 irq[32];
 	u32 mii_speed;
 };
+
+static inline int fs_get_id(struct fs_platform_info *fpi)
+{
+	if(strstr(fpi->fs_type, "SCC"))
+		return fs_scc_index2id(fpi->fs_no);
+	if(strstr(fpi->fs_type, "FCC"))
+		return fs_fcc_index2id(fpi->fs_no);
+	if(strstr(fpi->fs_type, "FEC"))
+		return fs_fec_index2id(fpi->fs_no);
+	return fpi->fs_no;
+}
+
 #endif
diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h
index f597512..809bb9f 100644
--- a/include/linux/fs_uart_pd.h
+++ b/include/linux/fs_uart_pd.h
@@ -46,15 +46,27 @@
 }
 
 struct fs_uart_platform_info {
-        void(*init_ioports)(void);
+        void(*init_ioports)(struct fs_uart_platform_info *);
 	/* device specific information */
 	int fs_no;		/* controller index */
+	char fs_type[4];        /* controller type  */
 	u32 uart_clk;
 	u8 tx_num_fifo;
 	u8 tx_buf_size;
 	u8 rx_num_fifo;
 	u8 rx_buf_size;
 	u8 brg;
+	u8 clk_rx;
+	u8 clk_tx;
 };
 
+static inline int fs_uart_get_id(struct fs_uart_platform_info *fpi)
+{
+        if(strstr(fpi->fs_type, "SMC"))
+                return fs_uart_id_smc2fsid(fpi->fs_no);
+        if(strstr(fpi->fs_type, "SCC"))
+                return fs_uart_id_scc2fsid(fpi->fs_no);
+        return fpi->fs_no;
+}
+
 #endif
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 16fbe59..3da29e2 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -46,18 +46,17 @@
 
 struct gianfar_platform_data {
 	/* device specific information */
-	u32 device_flags;
-
+	u32	device_flags;
 	/* board specific information */
-	u32 board_flags;
-	u32 bus_id;
-	u32 phy_id;
-	u8 mac_addr[6];
+	u32	board_flags;
+	u32	bus_id;
+	u32	phy_id;
+	u8	mac_addr[6];
 };
 
 struct gianfar_mdio_data {
 	/* board specific information */
-	int irq[32];
+	int	irq[32];
 };
 
 /* Flags related to gianfar device features */
@@ -76,14 +75,13 @@
 
 struct fsl_i2c_platform_data {
 	/* device specific information */
-	u32 device_flags;
+	u32	device_flags;
 };
 
 /* Flags related to I2C device features */
 #define FSL_I2C_DEV_SEPARATE_DFSRR	0x00000001
 #define FSL_I2C_DEV_CLOCK_5200		0x00000002
 
-
 enum fsl_usb2_operating_modes {
 	FSL_USB2_MPH_HOST,
 	FSL_USB2_DR_HOST,
@@ -101,9 +99,9 @@
 
 struct fsl_usb2_platform_data {
 	/* board specific information */
-	enum fsl_usb2_operating_modes operating_mode;
-	enum fsl_usb2_phy_modes phy_mode;
-	unsigned int port_enables;
+	enum fsl_usb2_operating_modes	operating_mode;
+	enum fsl_usb2_phy_modes		phy_mode;
+	unsigned int			port_enables;
 };
 
 /* Flags in fsl_usb2_mph_platform_data */
@@ -121,5 +119,44 @@
 	u32	sysclk;
 };
 
-#endif				/* _FSL_DEVICE_H_ */
-#endif				/* __KERNEL__ */
+/* Ethernet interface (phy management and speed)
+*/
+enum enet_interface {
+	ENET_10_MII,		/* 10 Base T,   MII interface */
+	ENET_10_RMII,		/* 10 Base T,  RMII interface */
+	ENET_10_RGMII,		/* 10 Base T, RGMII interface */
+	ENET_100_MII,		/* 100 Base T,   MII interface */
+	ENET_100_RMII,		/* 100 Base T,  RMII interface */
+	ENET_100_RGMII,		/* 100 Base T, RGMII interface */
+	ENET_1000_GMII,		/* 1000 Base T,  GMII interface */
+	ENET_1000_RGMII,	/* 1000 Base T, RGMII interface */
+	ENET_1000_TBI,		/* 1000 Base T,   TBI interface */
+	ENET_1000_RTBI		/* 1000 Base T,  RTBI interface */
+};
+
+struct ucc_geth_platform_data {
+	/* device specific information */
+	u32			device_flags;
+	u32			phy_reg_addr;
+
+	/* board specific information */
+	u32			board_flags;
+	u8			rx_clock;
+	u8			tx_clock;
+	u32			phy_id;
+	enum enet_interface	phy_interface;
+	u32			phy_interrupt;
+	u8			mac_addr[6];
+};
+
+/* Flags related to UCC Gigabit Ethernet device features */
+#define FSL_UGETH_DEV_HAS_GIGABIT		0x00000001
+#define FSL_UGETH_DEV_HAS_COALESCE		0x00000002
+#define FSL_UGETH_DEV_HAS_RMON			0x00000004
+
+/* Flags in ucc_geth_platform_data */
+#define FSL_UGETH_BRD_HAS_PHY_INTR		0x00000001
+				/* if not set use a timer */
+
+#endif /* _FSL_DEVICE_H_ */
+#endif /* __KERNEL__ */
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
index 690c428..9869ef3 100644
--- a/include/linux/genalloc.h
+++ b/include/linux/genalloc.h
@@ -31,5 +31,6 @@
 
 extern struct gen_pool *gen_pool_create(int, int);
 extern int gen_pool_add(struct gen_pool *, unsigned long, size_t, int);
+extern void gen_pool_destroy(struct gen_pool *);
 extern unsigned long gen_pool_alloc(struct gen_pool *, size_t);
 extern void gen_pool_free(struct gen_pool *, unsigned long, size_t);
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 50d8b57..612472a 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -28,11 +28,16 @@
 
 #ifndef HARDIRQ_BITS
 #define HARDIRQ_BITS	12
+
+#ifndef MAX_HARDIRQS_PER_CPU
+#define MAX_HARDIRQS_PER_CPU NR_IRQS
+#endif
+
 /*
  * The hardirq mask has to be large enough to have space for potentially
  * all IRQ sources in the system nesting on a single CPU.
  */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
+#if (1 << HARDIRQ_BITS) < MAX_HARDIRQS_PER_CPU
 # error HARDIRQ_BITS is too low!
 #endif
 #endif
diff --git a/include/linux/harrier_defs.h b/include/linux/harrier_defs.h
index 685b252..efef11d 100644
--- a/include/linux/harrier_defs.h
+++ b/include/linux/harrier_defs.h
@@ -1,5 +1,5 @@
 /*
- * asm-ppc/harrier_defs.h
+ * include/linux/harrier_defs.h
  *
  * Definitions for Motorola MCG Harrier North Bridge & Memory controller
  *
diff --git a/include/linux/htirq.h b/include/linux/htirq.h
new file mode 100644
index 0000000..1f15ce2
--- /dev/null
+++ b/include/linux/htirq.h
@@ -0,0 +1,15 @@
+#ifndef LINUX_HTIRQ_H
+#define LINUX_HTIRQ_H
+
+/* Helper functions.. */
+void write_ht_irq_low(unsigned int irq, u32 data);
+void write_ht_irq_high(unsigned int irq, u32 data);
+u32  read_ht_irq_low(unsigned int irq);
+u32  read_ht_irq_high(unsigned int irq);
+void mask_ht_irq(unsigned int irq);
+void unmask_ht_irq(unsigned int irq);
+
+/* The arch hook for getting things started */
+int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);
+
+#endif /* LINUX_HTIRQ_H */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 9962045..07d8d72 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -251,7 +251,8 @@
 
 #include <asm/ide.h>
 
-#ifndef MAX_HWIFS
+#if !defined(MAX_HWIFS) || defined(CONFIG_EMBEDDED)
+#undef MAX_HWIFS
 #define MAX_HWIFS	CONFIG_IDE_MAX_HWIFS
 #endif
 
@@ -773,12 +774,13 @@
 	unsigned long	dma_status;	/* dma status register */
 	unsigned long	dma_vendor3;	/* dma vendor 3 register */
 	unsigned long	dma_prdtable;	/* actual prd table address */
-	unsigned long	dma_base2;	/* extended base addr for dma ports */
 
-	unsigned	dma_extra;	/* extra addr for dma ports */
 	unsigned long	config_data;	/* for use by chipset-specific code */
 	unsigned long	select_data;	/* for use by chipset-specific code */
 
+	unsigned long	extra_base;	/* extra addr for dma ports */
+	unsigned	extra_ports;	/* number of extra dma ports */
+
 	unsigned	noprobe    : 1;	/* don't probe for this interface */
 	unsigned	present    : 1;	/* this interface exists */
 	unsigned	hold       : 1; /* this interface is always present */
@@ -823,6 +825,9 @@
 	unsigned int sleeping	: 1;
 		/* BOOL: polling active & poll_timeout field valid */
 	unsigned int polling	: 1;
+	 	/* BOOL: in a polling reset situation. Must not trigger another reset yet */
+	unsigned int resetting  : 1;
+
 		/* current drive */
 	ide_drive_t *drive;
 		/* ptr to current hwif in linked-list */
@@ -1190,7 +1195,6 @@
 extern void ide_scan_pcibus(int scan_direction) __init;
 extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner);
 #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE)
-extern void ide_pci_unregister_driver(struct pci_driver *driver);
 void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
 extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
 
diff --git a/include/linux/in.h b/include/linux/in.h
index d79fc75..2619859 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -40,6 +40,7 @@
 
   IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */
   IPPROTO_AH = 51,             /* Authentication Header protocol       */
+  IPPROTO_BEETPH = 94,	       /* IP option pseudo header for BEET */
   IPPROTO_PIM    = 103,		/* Protocol Independent Multicast	*/
 
   IPPROTO_COMP   = 108,                /* Compression Header protocol */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 60aac2c..33c5daa 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -4,7 +4,9 @@
 #include <linux/file.h>
 #include <linux/rcupdate.h>
 #include <linux/irqflags.h>
+#include <linux/utsname.h>
 #include <linux/lockdep.h>
+#include <linux/ipc.h>
 
 #define INIT_FDTABLE \
 {							\
@@ -68,6 +70,15 @@
 	.session	= 1,						\
 }
 
+extern struct nsproxy init_nsproxy;
+#define INIT_NSPROXY(nsproxy) {						\
+	.count		= ATOMIC_INIT(1),				\
+	.nslock		= SPIN_LOCK_UNLOCKED,				\
+	.uts_ns		= &init_uts_ns,					\
+	.namespace	= NULL,						\
+	INIT_IPC_NS(ipc_ns)						\
+}
+
 #define INIT_SIGHAND(sighand) {						\
 	.count		= ATOMIC_INIT(1), 				\
 	.action		= { { { .sa_handler = NULL, } }, },		\
@@ -117,6 +128,7 @@
 	.files		= &init_files,					\
 	.signal		= &init_signals,				\
 	.sighand	= &init_sighand,				\
+	.nsproxy	= &init_nsproxy,				\
 	.pending	= {						\
 		.list = LIST_HEAD_INIT(tsk.pending.list),		\
 		.signal = {{0}}},					\
diff --git a/include/linux/input.h b/include/linux/input.h
index b3253ab..5770105 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -349,6 +349,9 @@
 
 #define KEY_BATTERY		236
 
+#define KEY_BLUETOOTH		237
+#define KEY_WLAN		238
+
 #define KEY_UNKNOWN		240
 
 #define BTN_MISC		0x100
@@ -645,6 +648,7 @@
 #define BUS_USB			0x03
 #define BUS_HIL			0x04
 #define BUS_BLUETOOTH		0x05
+#define BUS_VIRTUAL		0x06
 
 #define BUS_ISA			0x10
 #define BUS_I8042		0x11
@@ -667,98 +671,167 @@
 
 /*
  * Structures used in ioctls to upload effects to a device
- * The first structures are not passed directly by using ioctls.
- * They are sub-structures of the actually sent structure (called ff_effect)
+ * They are pieces of a bigger structure (called ff_effect)
  */
 
+/*
+ * All duration values are expressed in ms. Values above 32767 ms (0x7fff)
+ * should not be used and have unspecified results.
+ */
+
+/**
+ * struct ff_replay - defines scheduling of the effect
+ * @length: duration of the effect
+ * @delay: delay before effect should start playing
+ */
 struct ff_replay {
-	__u16 length; /* Duration of an effect in ms. All other times are also expressed in ms */
-	__u16 delay;  /* Time to wait before to start playing an effect */
+	__u16 length;
+	__u16 delay;
 };
 
+/**
+ * struct ff_trigger - defines what triggers the effect
+ * @button: number of the button triggering the effect
+ * @interval: controls how soon the effect can be re-triggered
+ */
 struct ff_trigger {
-	__u16 button;   /* Number of button triggering an effect */
-	__u16 interval; /* Time to wait before an effect can be re-triggered (ms) */
+	__u16 button;
+	__u16 interval;
 };
 
+/**
+ * struct ff_envelope - generic effect envelope
+ * @attack_length: duration of the attack (ms)
+ * @attack_level: level at the beginning of the attack
+ * @fade_length: duration of fade (ms)
+ * @fade_level: level at the end of fade
+ *
+ * The @attack_level and @fade_level are absolute values; when applying
+ * envelope force-feedback core will convert to positive/negative
+ * value based on polarity of the default level of the effect.
+ * Valid range for the attack and fade levels is 0x0000 - 0x7fff
+ */
 struct ff_envelope {
-	__u16 attack_length;	/* Duration of attack (ms) */
-	__u16 attack_level;	/* Level at beginning of attack */
-	__u16 fade_length;	/* Duration of fade (ms) */
-	__u16 fade_level;	/* Level at end of fade */
+	__u16 attack_length;
+	__u16 attack_level;
+	__u16 fade_length;
+	__u16 fade_level;
 };
 
-/* FF_CONSTANT */
+/**
+ * struct ff_constant_effect - defines parameters of a constant effect
+ * @level: strength of the effect; may be negative
+ * @envelope: envelope data
+ */
 struct ff_constant_effect {
-	__s16 level;	    /* Strength of effect. Negative values are OK */
+	__s16 level;
 	struct ff_envelope envelope;
 };
 
-/* FF_RAMP */
+/**
+ * struct ff_ramp_effect - defines parameters of a ramp effect
+ * @start_level: beginning strength of the effect; may be negative
+ * @end_level: final strength of the effect; may be negative
+ * @envelope: envelope data
+ */
 struct ff_ramp_effect {
 	__s16 start_level;
 	__s16 end_level;
 	struct ff_envelope envelope;
 };
 
-/* FF_SPRING of FF_FRICTION */
+/**
+ * struct ff_condition_effect - defines a spring or friction effect
+ * @right_saturation: maximum level when joystick moved all way to the right
+ * @left_saturation: same for the left side
+ * @right_coeff: controls how fast the force grows when the joystick moves
+ *	to the right
+ * @left_coeff: same for the left side
+ * @deadband: size of the dead zone, where no force is produced
+ * @center: position of the dead zone
+ */
 struct ff_condition_effect {
-	__u16 right_saturation; /* Max level when joystick is on the right */
-	__u16 left_saturation;  /* Max level when joystick in on the left */
+	__u16 right_saturation;
+	__u16 left_saturation;
 
-	__s16 right_coeff;	/* Indicates how fast the force grows when the
-				   joystick moves to the right */
-	__s16 left_coeff;	/* Same for left side */
+	__s16 right_coeff;
+	__s16 left_coeff;
 
-	__u16 deadband;	/* Size of area where no force is produced */
-	__s16 center;	/* Position of dead zone */
-
+	__u16 deadband;
+	__s16 center;
 };
 
-/* FF_PERIODIC */
+/**
+ * struct ff_periodic_effect - defines parameters of a periodic effect
+ * @waveform: kind of the effect (wave)
+ * @period: period of the wave (ms)
+ * @magnitude: peak value
+ * @offset: mean value of the wave (roughly)
+ * @phase: 'horizontal' shift
+ * @envelope: envelope data
+ * @custom_len: number of samples (FF_CUSTOM only)
+ * @custom_data: buffer of samples (FF_CUSTOM only)
+ *
+ * Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
+ * FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
+ * for the time being as no driver supports it yet.
+ *
+ * Note: the data pointed by custom_data is copied by the driver.
+ * You can therefore dispose of the memory after the upload/update.
+ */
 struct ff_periodic_effect {
-	__u16 waveform;	/* Kind of wave (sine, square...) */
-	__u16 period;	/* in ms */
-	__s16 magnitude;	/* Peak value */
-	__s16 offset;	/* Mean value of wave (roughly) */
-	__u16 phase;		/* 'Horizontal' shift */
+	__u16 waveform;
+	__u16 period;
+	__s16 magnitude;
+	__s16 offset;
+	__u16 phase;
 
 	struct ff_envelope envelope;
 
-/* Only used if waveform == FF_CUSTOM */
-	__u32 custom_len;	/* Number of samples */
-	__s16 *custom_data;	/* Buffer of samples */
-/* Note: the data pointed by custom_data is copied by the driver. You can
- * therefore dispose of the memory after the upload/update */
+	__u32 custom_len;
+	__s16 *custom_data;
 };
 
-/* FF_RUMBLE */
-/* Some rumble pads have two motors of different weight.
-   strong_magnitude represents the magnitude of the vibration generated
-   by the heavy motor.
-*/
+/**
+ * struct ff_rumble_effect - defines parameters of a periodic effect
+ * @strong_magnitude: magnitude of the heavy motor
+ * @weak_magnitude: magnitude of the light one
+ *
+ * Some rumble pads have two motors of different weight. Strong_magnitude
+ * represents the magnitude of the vibration generated by the heavy one.
+ */
 struct ff_rumble_effect {
-	__u16 strong_magnitude;  /* Magnitude of the heavy motor */
-	__u16 weak_magnitude;    /* Magnitude of the light one */
+	__u16 strong_magnitude;
+	__u16 weak_magnitude;
 };
 
-/*
- * Structure sent through ioctl from the application to the driver
+/**
+ * struct ff_effect - defines force feedback effect
+ * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
+ *	FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
+ * @id: an unique id assigned to an effect
+ * @direction: direction of the effect
+ * @trigger: trigger conditions (struct ff_trigger)
+ * @replay: scheduling of the effect (struct ff_replay)
+ * @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
+ *	ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
+ *	defining effect parameters
+ *
+ * This structure is sent through ioctl from the application to the driver.
+ * To create a new effect aplication should set its @id to -1; the kernel
+ * will return assigned @id which can later be used to update or delete
+ * this effect.
+ *
+ * Direction of the effect is encoded as follows:
+ *	0 deg -> 0x0000 (down)
+ *	90 deg -> 0x4000 (left)
+ *	180 deg -> 0x8000 (up)
+ *	270 deg -> 0xC000 (right)
  */
 struct ff_effect {
 	__u16 type;
-/* Following field denotes the unique id assigned to an effect.
- * If user sets if to -1, a new effect is created, and its id is returned in the same field
- * Else, the user sets it to the effect id it wants to update.
- */
 	__s16 id;
-
-	__u16 direction;	/* Direction. 0 deg -> 0x0000 (down)
-					     90 deg -> 0x4000 (left)
-					    180 deg -> 0x8000 (up)
-					    270 deg -> 0xC000 (right)
-				*/
-
+	__u16 direction;
 	struct ff_trigger trigger;
 	struct ff_replay replay;
 
@@ -784,6 +857,9 @@
 #define FF_INERTIA	0x56
 #define FF_RAMP		0x57
 
+#define FF_EFFECT_MIN	FF_RUMBLE
+#define FF_EFFECT_MAX	FF_RAMP
+
 /*
  * Force feedback periodic effect types
  */
@@ -795,6 +871,9 @@
 #define FF_SAW_DOWN	0x5c
 #define FF_CUSTOM	0x5d
 
+#define FF_WAVEFORM_MIN	FF_SQUARE
+#define FF_WAVEFORM_MAX	FF_CUSTOM
+
 /*
  * Set ff device properties
  */
@@ -864,12 +943,13 @@
 	unsigned long sndbit[NBITS(SND_MAX)];
 	unsigned long ffbit[NBITS(FF_MAX)];
 	unsigned long swbit[NBITS(SW_MAX)];
-	int ff_effects_max;
 
 	unsigned int keycodemax;
 	unsigned int keycodesize;
 	void *keycode;
 
+	struct ff_device *ff;
+
 	unsigned int repeat_key;
 	struct timer_list timer;
 
@@ -895,8 +975,6 @@
 	void (*close)(struct input_dev *dev);
 	int (*flush)(struct input_dev *dev, struct file *file);
 	int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
-	int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);
-	int (*erase_effect)(struct input_dev *dev, int effect_id);
 
 	struct input_handle *grab;
 
@@ -904,9 +982,6 @@
 	unsigned int users;
 
 	struct class_device cdev;
-	struct device *dev;	/* will be removed soon */
-
-	int dynalloc;	/* temporarily */
 
 	struct list_head	h_list;
 	struct list_head	node;
@@ -985,16 +1060,16 @@
 	void *private;
 
 	void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
-	struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id);
+	struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
 	void (*disconnect)(struct input_handle *handle);
 	void (*start)(struct input_handle *handle);
 
 	const struct file_operations *fops;
 	int minor;
-	char *name;
+	const char *name;
 
-	struct input_device_id *id_table;
-	struct input_device_id *blacklist;
+	const struct input_device_id *id_table;
+	const struct input_device_id *blacklist;
 
 	struct list_head	h_list;
 	struct list_head	node;
@@ -1005,7 +1080,7 @@
 	void *private;
 
 	int open;
-	char *name;
+	const char *name;
 
 	struct input_dev *dev;
 	struct input_handler *handler;
@@ -1019,12 +1094,6 @@
 #define to_handle(n) container_of(n,struct input_handle,d_node)
 #define to_handle_h(n) container_of(n,struct input_handle,h_node)
 
-static inline void init_input_dev(struct input_dev *dev)
-{
-	INIT_LIST_HEAD(&dev->h_list);
-	INIT_LIST_HEAD(&dev->node);
-}
-
 struct input_dev *input_allocate_device(void);
 void input_free_device(struct input_dev *dev);
 
@@ -1041,7 +1110,7 @@
 int input_register_device(struct input_dev *);
 void input_unregister_device(struct input_dev *);
 
-void input_register_handler(struct input_handler *);
+int input_register_handler(struct input_handler *);
 void input_unregister_handler(struct input_handler *);
 
 int input_grab_device(struct input_handle *);
@@ -1070,11 +1139,6 @@
 	input_event(dev, EV_ABS, code, value);
 }
 
-static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value)
-{
-	input_event(dev, EV_FF, code, value);
-}
-
 static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
 {
 	input_event(dev, EV_FF_STATUS, code, value);
@@ -1108,5 +1172,61 @@
 
 extern struct class input_class;
 
+/**
+ * struct ff_device - force-feedback part of an input device
+ * @upload: Called to upload an new effect into device
+ * @erase: Called to erase an effect from device
+ * @playback: Called to request device to start playing specified effect
+ * @set_gain: Called to set specified gain
+ * @set_autocenter: Called to auto-center device
+ * @destroy: called by input core when parent input device is being
+ *	destroyed
+ * @private: driver-specific data, will be freed automatically
+ * @ffbit: bitmap of force feedback capabilities truly supported by
+ *	device (not emulated like ones in input_dev->ffbit)
+ * @mutex: mutex for serializing access to the device
+ * @max_effects: maximum number of effects supported by device
+ * @effects: pointer to an array of effects currently loaded into device
+ * @effect_owners: array of effect owners; when file handle owning
+ *	an effect gets closed the effcet is automatically erased
+ *
+ * Every force-feedback device must implement upload() and playback()
+ * methods; erase() is optional. set_gain() and set_autocenter() need
+ * only be implemented if driver sets up FF_GAIN and FF_AUTOCENTER
+ * bits.
+ */
+struct ff_device {
+	int (*upload)(struct input_dev *dev, struct ff_effect *effect,
+		      struct ff_effect *old);
+	int (*erase)(struct input_dev *dev, int effect_id);
+
+	int (*playback)(struct input_dev *dev, int effect_id, int value);
+	void (*set_gain)(struct input_dev *dev, u16 gain);
+	void (*set_autocenter)(struct input_dev *dev, u16 magnitude);
+
+	void (*destroy)(struct ff_device *);
+
+	void *private;
+
+	unsigned long ffbit[NBITS(FF_MAX)];
+
+	struct mutex mutex;
+
+	int max_effects;
+	struct ff_effect *effects;
+	struct file *effect_owners[];
+};
+
+int input_ff_create(struct input_dev *dev, int max_effects);
+void input_ff_destroy(struct input_dev *dev);
+
+int input_ff_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
+
+int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file);
+int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
+
+int input_ff_create_memless(struct input_dev *dev, void *data,
+		int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
+
 #endif
 #endif
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 6b25d36..ecee9bb 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -80,6 +80,8 @@
 #define	IPOPT_TS_TSANDADDR	1		/* timestamps and addresses */
 #define	IPOPT_TS_PRESPEC	3		/* specified modules only */
 
+#define IPV4_BEET_PHMAXLEN 8
+
 struct iphdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
 	__u8	ihl:4,
@@ -123,4 +125,11 @@
 	__be16 cpi;
 };
 
+struct ip_beet_phdr {
+	__u8 nexthdr;
+	__u8 hdrlen;
+	__u8 padlen;
+	__u8 reserved;
+};
+
 #endif	/* _LINUX_IP_H */
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index b291189..636094c 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -51,6 +51,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/kref.h>
+
 #define IPCMNI 32768  /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
 
 /* used by in-kernel data structures */
@@ -68,6 +70,59 @@
 	void		*security;
 };
 
+struct ipc_ids;
+struct ipc_namespace {
+	struct kref	kref;
+	struct ipc_ids	*ids[3];
+
+	int		sem_ctls[4];
+	int		used_sems;
+
+	int		msg_ctlmax;
+	int		msg_ctlmnb;
+	int		msg_ctlmni;
+
+	size_t		shm_ctlmax;
+	size_t		shm_ctlall;
+	int		shm_ctlmni;
+	int		shm_tot;
+};
+
+extern struct ipc_namespace init_ipc_ns;
+
+#ifdef CONFIG_SYSVIPC
+#define INIT_IPC_NS(ns)		.ns		= &init_ipc_ns,
+#else
+#define INIT_IPC_NS(ns)
+#endif
+
+#ifdef CONFIG_IPC_NS
+extern void free_ipc_ns(struct kref *kref);
+extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
+extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns);
+#else
+static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+	return 0;
+}
+#endif
+
+static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
+{
+#ifdef CONFIG_IPC_NS
+	if (ns)
+		kref_get(&ns->kref);
+#endif
+	return ns;
+}
+
+static inline void put_ipc_ns(struct ipc_namespace *ns)
+{
+#ifdef CONFIG_IPC_NS
+	kref_put(&ns->kref, free_ipc_ns);
+#endif
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_IPC_H */
diff --git a/include/linux/ipsec.h b/include/linux/ipsec.h
index d3c5276..d17a630 100644
--- a/include/linux/ipsec.h
+++ b/include/linux/ipsec.h
@@ -12,7 +12,8 @@
 enum {
 	IPSEC_MODE_ANY		= 0,	/* We do not support this for SA */
 	IPSEC_MODE_TRANSPORT	= 1,
-	IPSEC_MODE_TUNNEL	= 2
+	IPSEC_MODE_TUNNEL	= 2,
+	IPSEC_MODE_BEET         = 3
 };
 
 enum {
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 48d3cb3..6f46360 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -59,6 +59,7 @@
 #define IRQ_NOAUTOEN		0x08000000	/* IRQ will not be enabled on request irq */
 #define IRQ_DELAYED_DISABLE	0x10000000	/* IRQ disable (masking) happens delayed. */
 #define IRQ_WAKEUP		0x20000000	/* IRQ triggers system wakeup */
+#define IRQ_MOVE_PENDING	0x40000000	/* need to re-target IRQ destination */
 
 struct proc_dir_entry;
 
@@ -132,7 +133,6 @@
  * @affinity:		IRQ affinity on SMP
  * @cpu:		cpu index useful for balancing
  * @pending_mask:	pending rebalanced interrupts
- * @move_irq:		need to re-target IRQ destination
  * @dir:		/proc/irq/ procfs entry
  * @affinity_entry:	/proc/irq/smp_affinity procfs entry on SMP
  *
@@ -159,7 +159,6 @@
 #endif
 #if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
 	cpumask_t		pending_mask;
-	unsigned int		move_irq;	/* need to re-target IRQ dest */
 #endif
 #ifdef CONFIG_PROC_FS
 	struct proc_dir_entry *dir;
@@ -206,36 +205,7 @@
 
 void set_pending_irq(unsigned int irq, cpumask_t mask);
 void move_native_irq(int irq);
-
-#ifdef CONFIG_PCI_MSI
-/*
- * Wonder why these are dummies?
- * For e.g the set_ioapic_affinity_vector() calls the set_ioapic_affinity_irq()
- * counter part after translating the vector to irq info. We need to perform
- * this operation on the real irq, when we dont use vector, i.e when
- * pci_use_vector() is false.
- */
-static inline void move_irq(int irq)
-{
-}
-
-static inline void set_irq_info(int irq, cpumask_t mask)
-{
-}
-
-#else /* CONFIG_PCI_MSI */
-
-static inline void move_irq(int irq)
-{
-	move_native_irq(irq);
-}
-
-static inline void set_irq_info(int irq, cpumask_t mask)
-{
-	set_native_irq_info(irq, mask);
-}
-
-#endif /* CONFIG_PCI_MSI */
+void move_masked_irq(int irq);
 
 #else /* CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE */
 
@@ -247,21 +217,20 @@
 {
 }
 
-static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
+static inline void move_masked_irq(int irq)
 {
 }
 
-static inline void set_irq_info(int irq, cpumask_t mask)
+static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
 {
-	set_native_irq_info(irq, mask);
 }
 
 #endif /* CONFIG_GENERIC_PENDING_IRQ */
 
 #else /* CONFIG_SMP */
 
-#define move_irq(x)
 #define move_native_irq(x)
+#define move_masked_irq(x)
 
 #endif /* CONFIG_SMP */
 
@@ -399,8 +368,22 @@
 	__set_irq_handler(irq, handle, 1);
 }
 
-/* Set/get chip/data for an IRQ: */
+/* Handle dynamic irq creation and destruction */
+extern int create_irq(void);
+extern void destroy_irq(unsigned int irq);
 
+/* Test to see if a driver has successfully requested an irq */
+static inline int irq_has_action(unsigned int irq)
+{
+	struct irq_desc *desc = irq_desc + irq;
+	return desc->action != NULL;
+}
+
+/* Dynamic irq helper functions */
+extern void dynamic_irq_init(unsigned int irq);
+extern void dynamic_irq_cleanup(unsigned int irq);
+
+/* Set/get chip/data for an IRQ: */
 extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
 extern int set_irq_data(unsigned int irq, void *data);
 extern int set_irq_chip_data(unsigned int irq, void *data);
diff --git a/include/linux/ite_gpio.h b/include/linux/ite_gpio.h
deleted file mode 100644
index b123a14..0000000
--- a/include/linux/ite_gpio.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * FILE NAME ite_gpio.h
- *
- * BRIEF MODULE DESCRIPTION
- *	Generic gpio.
- *
- *  Author: MontaVista Software, Inc.  <source@mvista.com>
- *          Hai-Pao Fan <haipao@mvista.com>
- *
- * Copyright 2001 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ITE_GPIO_H
-#define __ITE_GPIO_H
-
-#include <linux/ioctl.h>
-
-struct ite_gpio_ioctl_data {
-	__u32 device;
-	__u32 mask;
-	__u32 data;
-};
-
-#define ITE_GPIO_IOCTL_BASE	'Z'
-
-#define ITE_GPIO_IN		_IOWR(ITE_GPIO_IOCTL_BASE, 0, struct ite_gpio_ioctl_data)
-#define ITE_GPIO_OUT		_IOW (ITE_GPIO_IOCTL_BASE, 1, struct ite_gpio_ioctl_data)
-#define	ITE_GPIO_INT_CTRL	_IOW (ITE_GPIO_IOCTL_BASE, 2, struct ite_gpio_ioctl_data)
-#define	ITE_GPIO_IN_STATUS	_IOW (ITE_GPIO_IOCTL_BASE, 3, struct ite_gpio_ioctl_data)
-#define	ITE_GPIO_OUT_STATUS	_IOW (ITE_GPIO_IOCTL_BASE, 4, struct ite_gpio_ioctl_data)
-#define ITE_GPIO_GEN_CTRL	_IOW (ITE_GPIO_IOCTL_BASE, 5, struct ite_gpio_ioctl_data)
-#define ITE_GPIO_INT_WAIT	_IOW (ITE_GPIO_IOCTL_BASE, 6, struct ite_gpio_ioctl_data)
-
-#define	ITE_GPIO_PORTA	0x01
-#define	ITE_GPIO_PORTB	0x02
-#define	ITE_GPIO_PORTC	0x04
-
-extern int ite_gpio_in(__u32 device, __u32 mask, volatile __u32 *data);
-extern int ite_gpio_out(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_int_ctrl(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_in_status(__u32 device, __u32 mask, volatile __u32 *data);
-extern int ite_gpio_out_status(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_gen_ctrl(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_int_wait(__u32 device, __u32 mask, __u32 data);
-
-#endif
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 849043c..1cebcbc 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -12,6 +12,10 @@
 /* Lookup the address for a symbol. Returns 0 if not found. */
 unsigned long kallsyms_lookup_name(const char *name);
 
+extern int kallsyms_lookup_size_offset(unsigned long addr,
+				  unsigned long *symbolsize,
+				  unsigned long *offset);
+
 /* Lookup an address.  modname is set to NULL if it's in the kernel. */
 const char *kallsyms_lookup(unsigned long addr,
 			    unsigned long *symbolsize,
@@ -28,6 +32,13 @@
 	return 0;
 }
 
+static inline int kallsyms_lookup_size_offset(unsigned long addr,
+					      unsigned long *symbolsize,
+					      unsigned long *offset)
+{
+	return 0;
+}
+
 static inline const char *kallsyms_lookup(unsigned long addr,
 					  unsigned long *symbolsize,
 					  unsigned long *offset,
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4d00988..80f39ca 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -216,8 +216,10 @@
 #define pr_debug(fmt,arg...) \
 	printk(KERN_DEBUG fmt,##arg)
 #else
-#define pr_debug(fmt,arg...) \
-	do { } while (0)
+static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * fmt, ...)
+{
+	return 0;
+}
 #endif
 
 #define pr_info(fmt,arg...) \
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 8bf6702..ac4c055 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -77,6 +77,12 @@
 	/* location of the probe point */
 	kprobe_opcode_t *addr;
 
+	/* Allow user to indicate symbol name of the probe point */
+	char *symbol_name;
+
+	/* Offset into the symbol */
+	unsigned int offset;
+
 	/* Called before addr is executed. */
 	kprobe_pre_handler_t pre_handler;
 
@@ -196,7 +202,7 @@
 struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
 void add_rp_inst(struct kretprobe_instance *ri);
 void kprobe_flush_task(struct task_struct *tk);
-void recycle_rp_inst(struct kretprobe_instance *ri);
+void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
 #else /* CONFIG_KPROBES */
 
 #define __kprobes	/**/
diff --git a/include/linux/libata.h b/include/linux/libata.h
index d6a3d4b..d1af1dbe 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -109,6 +109,10 @@
 #define ATA_TAG_POISON		0xfafbfcfdU
 
 /* move to PCI layer? */
+#define PCI_VDEVICE(vendor, device)		\
+	PCI_VENDOR_ID_##vendor, (device),	\
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0
+
 static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
 {
 	return &pdev->dev;
@@ -138,8 +142,9 @@
 	ATA_DFLAG_NCQ		= (1 << 3), /* device supports NCQ */
 	ATA_DFLAG_CFG_MASK	= (1 << 8) - 1,
 
-	ATA_DFLAG_PIO		= (1 << 8), /* device currently in PIO mode */
-	ATA_DFLAG_SUSPENDED	= (1 << 9), /* device suspended */
+	ATA_DFLAG_PIO		= (1 << 8), /* device limited to PIO mode */
+	ATA_DFLAG_NCQ_OFF	= (1 << 9), /* devied limited to non-NCQ mode */
+	ATA_DFLAG_SUSPENDED	= (1 << 10), /* device suspended */
 	ATA_DFLAG_INIT_MASK	= (1 << 16) - 1,
 
 	ATA_DFLAG_DETACH	= (1 << 16),
diff --git a/include/linux/libps2.h b/include/linux/libps2.h
index 08a450a..f6f301e 100644
--- a/include/linux/libps2.h
+++ b/include/linux/libps2.h
@@ -47,5 +47,6 @@
 int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
 int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
 void ps2_cmd_aborted(struct ps2dev *ps2dev);
+int ps2_is_keyboard_id(char id);
 
 #endif /* _LIBPS2_H */
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index b054deb..81e3a18 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -30,7 +30,7 @@
  * Functions exported by the lockd module
  */
 extern int	nlmclnt_proc(struct inode *, int, struct file_lock *);
-extern int	lockd_up(void);
+extern int	lockd_up(int proto);
 extern void	lockd_down(void);
 
 #endif /* LINUX_LOCKD_BIND_H */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 0d92c46..2909619 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -37,17 +37,15 @@
  * Lockd host handle (used both by the client and server personality).
  */
 struct nlm_host {
-	struct nlm_host *	h_next;		/* linked list (hash table) */
+	struct hlist_node	h_hash;		/* doubly linked list */
 	struct sockaddr_in	h_addr;		/* peer address */
 	struct rpc_clnt	*	h_rpcclnt;	/* RPC client to talk to peer */
-	char			h_name[20];	/* remote hostname */
+	char *			h_name;		/* remote hostname */
 	u32			h_version;	/* interface version */
 	unsigned short		h_proto;	/* transport proto */
 	unsigned short		h_reclaiming : 1,
 				h_server     : 1, /* server side, not client side */
-				h_inuse      : 1,
-				h_killed     : 1,
-				h_monitored  : 1;
+				h_inuse      : 1;
 	wait_queue_head_t	h_gracewait;	/* wait while reclaiming */
 	struct rw_semaphore	h_rwsem;	/* Reboot recovery lock */
 	u32			h_state;	/* pseudo-state counter */
@@ -61,6 +59,16 @@
 	spinlock_t		h_lock;
 	struct list_head	h_granted;	/* Locks in GRANTED state */
 	struct list_head	h_reclaim;	/* Locks in RECLAIM state */
+	struct nsm_handle *	h_nsmhandle;	/* NSM status handle */
+};
+
+struct nsm_handle {
+	struct list_head	sm_link;
+	atomic_t		sm_count;
+	char *			sm_name;
+	struct sockaddr_in	sm_addr;
+	unsigned int		sm_monitored : 1,
+				sm_sticky : 1;	/* don't unmonitor */
 };
 
 /*
@@ -80,7 +88,7 @@
 /*
  * Memory chunk for NLM client RPC request.
  */
-#define NLMCLNT_OHSIZE		(sizeof(system_utsname.nodename)+10)
+#define NLMCLNT_OHSIZE		(sizeof(utsname()->nodename)+10)
 struct nlm_rqst {
 	unsigned int		a_flags;	/* initial RPC task flags */
 	struct nlm_host *	a_host;		/* host handle */
@@ -96,15 +104,14 @@
  * an NFS client.
  */
 struct nlm_file {
-	struct nlm_file *	f_next;		/* linked list */
+	struct hlist_node	f_list;		/* linked list */
 	struct nfs_fh		f_handle;	/* NFS file handle */
 	struct file *		f_file;		/* VFS file pointer */
 	struct nlm_share *	f_shares;	/* DOS shares */
-	struct nlm_block *	f_blocks;	/* blocked locks */
+	struct list_head	f_blocks;	/* blocked locks */
 	unsigned int		f_locks;	/* guesstimate # of locks */
 	unsigned int		f_count;	/* reference count */
-	struct semaphore	f_sema;		/* avoid concurrent access */
-	int		       	f_hash;		/* hash of f_handle */
+	struct mutex		f_mutex;	/* avoid concurrent access */
 };
 
 /*
@@ -114,26 +121,18 @@
 #define NLM_NEVER		(~(unsigned long) 0)
 struct nlm_block {
 	struct kref		b_count;	/* Reference count */
-	struct nlm_block *	b_next;		/* linked list (all blocks) */
-	struct nlm_block *	b_fnext;	/* linked list (per file) */
+	struct list_head	b_list;		/* linked list of all blocks */
+	struct list_head	b_flist;	/* linked list (per file) */
 	struct nlm_rqst	*	b_call;		/* RPC args & callback info */
 	struct svc_serv *	b_daemon;	/* NLM service */
 	struct nlm_host *	b_host;		/* host handle for RPC clnt */
 	unsigned long		b_when;		/* next re-xmit */
 	unsigned int		b_id;		/* block id */
-	unsigned char		b_queued;	/* re-queued */
 	unsigned char		b_granted;	/* VFS granted lock */
 	struct nlm_file *	b_file;		/* file in question */
 };
 
 /*
- * Valid actions for nlmsvc_traverse_files
- */
-#define NLM_ACT_CHECK		0		/* check for locks */
-#define NLM_ACT_MARK		1		/* mark & sweep */
-#define NLM_ACT_UNLOCK		2		/* release all locks */
-
-/*
  * Global variables
  */
 extern struct rpc_program	nlm_program;
@@ -143,6 +142,7 @@
 #endif
 extern int			nlmsvc_grace_period;
 extern unsigned long		nlmsvc_timeout;
+extern int			nsm_use_hostnames;
 
 /*
  * Lockd client functions
@@ -155,24 +155,33 @@
 void		  nlmclnt_finish_block(struct nlm_wait *block);
 int		  nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
 u32		  nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *);
-void		  nlmclnt_recovery(struct nlm_host *, u32);
+void		  nlmclnt_recovery(struct nlm_host *);
 int		  nlmclnt_reclaim(struct nlm_host *, struct file_lock *);
+void		  nlmclnt_next_cookie(struct nlm_cookie *);
 
 /*
  * Host cache
  */
-struct nlm_host * nlmclnt_lookup_host(struct sockaddr_in *, int, int);
-struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *);
-struct nlm_host * nlm_lookup_host(int server, struct sockaddr_in *, int, int);
+struct nlm_host * nlmclnt_lookup_host(const struct sockaddr_in *, int, int, const char *, int);
+struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *, const char *, int);
+struct nlm_host * nlm_lookup_host(int server, const struct sockaddr_in *, int, int, const char *, int);
 struct rpc_clnt * nlm_bind_host(struct nlm_host *);
 void		  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void		  nlm_release_host(struct nlm_host *);
 void		  nlm_shutdown_hosts(void);
-extern struct nlm_host *nlm_find_client(void);
+extern void	  nlm_host_rebooted(const struct sockaddr_in *, const char *, int, u32);
+struct nsm_handle *nsm_find(const struct sockaddr_in *, const char *, int);
+void		  nsm_release(struct nsm_handle *);
 
 
 /*
+ * This is used in garbage collection and resource reclaim
+ * A return value != 0 means destroy the lock/block/share
+ */
+typedef int	  (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref);
+
+/*
  * Server-side lock handling
  */
 u32		  nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
@@ -183,8 +192,8 @@
 u32		  nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
 unsigned long	  nlmsvc_retry_blocked(void);
 void		  nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
-					int action);
-void	  nlmsvc_grant_reply(struct svc_rqst *, struct nlm_cookie *, u32);
+					nlm_host_match_fn_t match);
+void		  nlmsvc_grant_reply(struct nlm_cookie *, u32);
 
 /*
  * File handling for the server personality
diff --git a/include/linux/lockd/share.h b/include/linux/lockd/share.h
index c75a424..cd7816e 100644
--- a/include/linux/lockd/share.h
+++ b/include/linux/lockd/share.h
@@ -25,6 +25,7 @@
 					       struct nlm_args *);
 u32	nlmsvc_unshare_file(struct nlm_host *, struct nlm_file *,
 					       struct nlm_args *);
-void	nlmsvc_traverse_shares(struct nlm_host *, struct nlm_file *, int);
+void	nlmsvc_traverse_shares(struct nlm_host *, struct nlm_file *,
+					       nlm_host_match_fn_t);
 
 #endif /* LINUX_LOCKD_SHARE_H */
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index 1080bb6..fc61d40 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -28,7 +28,8 @@
 	u32		prog;		/* RPC callback info */
 	u32		vers;
 	u32		proc;
-	u32		proto;		/* protocol (udp/tcp) plus server/client flag */
+
+	char *		mon_name;
 };
 
 /*
@@ -41,6 +42,6 @@
 
 int		nsm_monitor(struct nlm_host *);
 int		nsm_unmonitor(struct nlm_host *);
-extern u32	nsm_local_state;
+extern int	nsm_local_state;
 
 #endif /* LINUX_LOCKD_SM_INTER_H */
diff --git a/include/linux/lockd/xdr4.h b/include/linux/lockd/xdr4.h
index cee36e7..3cc1ae2 100644
--- a/include/linux/lockd/xdr4.h
+++ b/include/linux/lockd/xdr4.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/lockd/xdr.h
+ * linux/include/linux/lockd/xdr4.h
  *
  * XDR types for the NLM protocol
  *
diff --git a/include/linux/module.h b/include/linux/module.h
index 2c59917..4b2d809 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -320,6 +320,8 @@
 	/* Am I GPL-compatible */
 	int license_gplok;
 
+	unsigned int taints;	/* same bits as kernel:tainted */
+
 #ifdef CONFIG_MODULE_UNLOAD
 	/* Reference counts */
 	struct module_ref ref[NR_CPUS];
diff --git a/include/linux/msi.h b/include/linux/msi.h
new file mode 100644
index 0000000..c7ef943
--- /dev/null
+++ b/include/linux/msi.h
@@ -0,0 +1,49 @@
+#ifndef LINUX_MSI_H
+#define LINUX_MSI_H
+
+struct msi_msg {
+	u32	address_lo;	/* low 32 bits of msi message address */
+	u32	address_hi;	/* high 32 bits of msi message address */
+	u32	data;		/* 16 bits of msi message data */
+};
+
+/* Heper functions */
+extern void mask_msi_irq(unsigned int irq);
+extern void unmask_msi_irq(unsigned int irq);
+extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
+
+extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+
+struct msi_desc {
+	struct {
+		__u8	type	: 5; 	/* {0: unused, 5h:MSI, 11h:MSI-X} */
+		__u8	maskbit	: 1; 	/* mask-pending bit supported ?   */
+		__u8	unused	: 1;
+		__u8	is_64	: 1;	/* Address size: 0=32bit 1=64bit  */
+		__u8	pos;	 	/* Location of the msi capability */
+		__u16	entry_nr;    	/* specific enabled entry 	  */
+		unsigned default_irq;	/* default pre-assigned irq	  */
+	}msi_attrib;
+
+	struct {
+		__u16	head;
+		__u16	tail;
+	}link;
+
+	void __iomem *mask_base;
+	struct pci_dev *dev;
+
+#ifdef CONFIG_PM
+	/* PM save area for MSIX address/data */
+	struct msi_msg msg_save;
+#endif
+};
+
+/*
+ * The arch hook for setup up msi irqs
+ */
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev);
+void arch_teardown_msi_irq(unsigned int irq);
+
+
+#endif /* LINUX_MSI_H */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 0b4cd2f..70420bb 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -27,9 +27,17 @@
 struct mtd_info;
 /* Scan and identify a NAND device */
 extern int nand_scan (struct mtd_info *mtd, int max_chips);
+/* Separate phases of nand_scan(), allowing board driver to intervene
+ * and override command or ECC setup according to flash type */
+extern int nand_scan_ident(struct mtd_info *mtd, int max_chips);
+extern int nand_scan_tail(struct mtd_info *mtd);
+
 /* Free resources held by the NAND device */
 extern void nand_release (struct mtd_info *mtd);
 
+/* Internal helper for board drivers which need to override command function */
+extern void nand_wait_ready(struct mtd_info *mtd);
+
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS		8
 
@@ -178,7 +186,9 @@
 #define NAND_USE_FLASH_BBT	0x00010000
 /* This option skips the bbt scan during initialization. */
 #define NAND_SKIP_BBTSCAN	0x00020000
-
+/* This option is defined if the board driver allocates its own buffers
+   (e.g. because it needs them DMA-coherent */
+#define NAND_OWN_BUFFERS	0x00040000
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
 #define NAND_CONTROLLER_ALLOC	0x80000000
@@ -228,6 +238,8 @@
  *		be provided if an hardware ECC is available
  * @calculate:	function for ecc calculation or readback from ecc hardware
  * @correct:	function for ecc correction, matching to ecc generator (sw/hw)
+ * @read_page_raw:	function to read a raw page without ECC
+ * @write_page_raw:	function to write a raw page without ECC
  * @read_page:	function to read a page according to the ecc generator requirements
  * @write_page:	function to write a page according to the ecc generator requirements
  * @read_oob:	function to read chip OOB data
@@ -249,6 +261,12 @@
 	int			(*correct)(struct mtd_info *mtd, uint8_t *dat,
 					   uint8_t *read_ecc,
 					   uint8_t *calc_ecc);
+	int			(*read_page_raw)(struct mtd_info *mtd,
+						 struct nand_chip *chip,
+						 uint8_t *buf);
+	void			(*write_page_raw)(struct mtd_info *mtd,
+						  struct nand_chip *chip,
+						  const uint8_t *buf);
 	int			(*read_page)(struct mtd_info *mtd,
 					     struct nand_chip *chip,
 					     uint8_t *buf);
@@ -337,6 +355,7 @@
  * @priv:		[OPTIONAL] pointer to private chip date
  * @errstat:		[OPTIONAL] hardware specific function to perform additional error status checks
  *			(determine if errors are correctable)
+ * @write_page		[REPLACEABLE] High-level page write function
  */
 
 struct nand_chip {
@@ -359,6 +378,8 @@
 	void		(*erase_cmd)(struct mtd_info *mtd, int page);
 	int		(*scan_bbt)(struct mtd_info *mtd);
 	int		(*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
+	int		(*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+				      const uint8_t *buf, int page, int cached, int raw);
 
 	int		chip_delay;
 	unsigned int	options;
@@ -380,7 +401,7 @@
 	struct nand_ecclayout	*ecclayout;
 
 	struct nand_ecc_ctrl ecc;
-	struct nand_buffers buffers;
+	struct nand_buffers *buffers;
 	struct nand_hw_control hwcontrol;
 
 	struct mtd_oob_ops ops;
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 1f49721..6f045b5 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -1,7 +1,7 @@
 /*
  *  linux/include/linux/mtd/onenand.h
  *
- *  Copyright (C) 2005 Samsung Electronics
+ *  Copyright (C) 2005-2006 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -96,6 +96,7 @@
 	void __iomem		*base;
 	unsigned int		chipsize;
 	unsigned int		device_id;
+	unsigned int		version_id;
 	unsigned int		density_mask;
 	unsigned int		options;
 
@@ -149,7 +150,8 @@
 /*
  * Options bits
  */
-#define ONENAND_CONT_LOCK		(0x0001)
+#define ONENAND_HAS_CONT_LOCK		(0x0001)
+#define ONENAND_HAS_UNLOCK_ALL		(0x0002)
 #define ONENAND_PAGEBUF_ALLOC		(0x1000)
 
 /*
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index 4a72818..9e409fe 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -3,7 +3,7 @@
  *
  *  OneNAND Register header file
  *
- *  Copyright (C) 2005 Samsung Electronics
+ *  Copyright (C) 2005-2006 Samsung Electronics
  *
  * 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
@@ -72,6 +72,7 @@
 #define ONENAND_DEVICE_VCC_MASK		(0x3)
 
 #define ONENAND_DEVICE_DENSITY_512Mb	(0x002)
+#define ONENAND_DEVICE_DENSITY_1Gb	(0x003)
 
 /*
  * Version ID Register F002h (R)
@@ -110,6 +111,7 @@
 #define ONENAND_CMD_UNLOCK		(0x23)
 #define ONENAND_CMD_LOCK		(0x2A)
 #define ONENAND_CMD_LOCK_TIGHT		(0x2C)
+#define ONENAND_CMD_UNLOCK_ALL		(0x27)
 #define ONENAND_CMD_ERASE		(0x94)
 #define ONENAND_CMD_RESET		(0xF0)
 #define ONENAND_CMD_OTP_ACCESS		(0x65)
diff --git a/include/linux/mtd/plat-ram.h b/include/linux/mtd/plat-ram.h
index 2332eda..9667863 100644
--- a/include/linux/mtd/plat-ram.h
+++ b/include/linux/mtd/plat-ram.h
@@ -1,4 +1,4 @@
-/* linux/include/mtd/plat-ram.h
+/* linux/include/linux/mtd/plat-ram.h
  *
  * (c) 2004 Simtec Electronics
  *	http://www.simtec.co.uk/products/SWLINUX/
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 3abc8e3..d137009 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -4,6 +4,7 @@
 
 #include <linux/mount.h>
 #include <linux/sched.h>
+#include <linux/nsproxy.h>
 
 struct namespace {
 	atomic_t		count;
@@ -26,11 +27,8 @@
 
 static inline void exit_namespace(struct task_struct *p)
 {
-	struct namespace *namespace = p->namespace;
+	struct namespace *namespace = p->nsproxy->namespace;
 	if (namespace) {
-		task_lock(p);
-		p->namespace = NULL;
-		task_unlock(p);
 		put_namespace(namespace);
 	}
 }
diff --git a/include/linux/netfilter_bridge/ebt_mark_t.h b/include/linux/netfilter_bridge/ebt_mark_t.h
index 110fec6..6270f6f 100644
--- a/include/linux/netfilter_bridge/ebt_mark_t.h
+++ b/include/linux/netfilter_bridge/ebt_mark_t.h
@@ -1,6 +1,18 @@
 #ifndef __LINUX_BRIDGE_EBT_MARK_T_H
 #define __LINUX_BRIDGE_EBT_MARK_T_H
 
+/* The target member is reused for adding new actions, the
+ * value of the real target is -1 to -NUM_STANDARD_TARGETS.
+ * For backward compatibility, the 4 lsb (2 would be enough,
+ * but let's play it safe) are kept to designate this target.
+ * The remaining bits designate the action. By making the set
+ * action 0xfffffff0, the result will look ok for older
+ * versions. [September 2006] */
+#define MARK_SET_VALUE (0xfffffff0)
+#define MARK_OR_VALUE  (0xffffffe0)
+#define MARK_AND_VALUE (0xffffffd0)
+#define MARK_XOR_VALUE (0xffffffc0)
+
 struct ebt_mark_t_info
 {
 	unsigned long mark;
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index ce02c98..5b63a23 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -77,7 +77,7 @@
 #define SO_ORIGINAL_DST 80
 
 #ifdef __KERNEL__
-extern int ip_route_me_harder(struct sk_buff **pskb);
+extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
 extern int ip_xfrm_me_harder(struct sk_buff **pskb);
 extern unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
 				   unsigned int dataoff, u_int8_t protocol);
diff --git a/include/linux/nfsd/const.h b/include/linux/nfsd/const.h
index b75bb1b3..f0cc777 100644
--- a/include/linux/nfsd/const.h
+++ b/include/linux/nfsd/const.h
@@ -20,17 +20,31 @@
 #define NFSSVC_MAXVERS		3
 
 /*
- * Maximum blocksize supported by daemon currently at 32K
+ * Maximum blocksizes supported by daemon under various circumstances.
  */
-#define NFSSVC_MAXBLKSIZE	(32*1024)
+#define NFSSVC_MAXBLKSIZE	RPCSVC_MAXPAYLOAD
+/* NFSv2 is limited by the protocol specification, see RFC 1094 */
+#define NFSSVC_MAXBLKSIZE_V2	(8*1024)
 
 #ifdef __KERNEL__
 
+#include <linux/sunrpc/msg_prot.h>
+
 #ifndef NFS_SUPER_MAGIC
 # define NFS_SUPER_MAGIC	0x6969
 #endif
 
-#define NFSD_BUFSIZE		(1024 + NFSSVC_MAXBLKSIZE)
+/*
+ * Largest number of bytes we need to allocate for an NFS
+ * call or reply.  Used to control buffer sizes.  We use
+ * the length of v3 WRITE, READDIR and READDIR replies
+ * which are an RPC header, up to 26 XDR units of reply
+ * data, and some page data.
+ *
+ * Note that accuracy here doesn't matter too much as the
+ * size is rounded up to a page size when allocating space.
+ */
+#define NFSD_BUFSIZE		((RPC_MAX_HEADER_WITH_AUTH+26)*XDR_UNIT + NFSSVC_MAXBLKSIZE)
 
 #ifdef CONFIG_NFSD_V4
 # define NFSSVC_XDRSIZE		NFS4_SVC_XDRSIZE
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index d2a8abb..6e78ea9 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -45,15 +45,36 @@
 
 #ifdef __KERNEL__
 
+/*
+ * FS Locations
+ */
+
+#define MAX_FS_LOCATIONS	128
+
+struct nfsd4_fs_location {
+	char *hosts; /* colon separated list of hosts */
+	char *path;  /* slash separated list of path components */
+};
+
+struct nfsd4_fs_locations {
+	uint32_t locations_count;
+	struct nfsd4_fs_location *locations;
+/* If we're not actually serving this data ourselves (only providing a
+ * list of replicas that do serve it) then we set "migrated": */
+	int migrated;
+};
+
 struct svc_export {
 	struct cache_head	h;
 	struct auth_domain *	ex_client;
 	int			ex_flags;
 	struct vfsmount *	ex_mnt;
 	struct dentry *		ex_dentry;
+	char *			ex_path;
 	uid_t			ex_anon_uid;
 	gid_t			ex_anon_gid;
 	int			ex_fsid;
+	struct nfsd4_fs_locations ex_fslocs;
 };
 
 /* an "export key" (expkey) maps a filehandlefragement to an
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 2dcad29..d0d4aae 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -140,6 +140,12 @@
 int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
 #endif
 
+enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
+int nfsd_vers(int vers, enum vers_op change);
+void nfsd_reset_versions(void);
+int nfsd_create_serv(void);
+
+extern int nfsd_max_blksize;
 
 /* 
  * NFSv4 State
@@ -210,6 +216,7 @@
 #define	nfserr_clid_inuse	__constant_htonl(NFSERR_CLID_INUSE)
 #define	nfserr_stale_clientid	__constant_htonl(NFSERR_STALE_CLIENTID)
 #define	nfserr_resource		__constant_htonl(NFSERR_RESOURCE)
+#define	nfserr_moved		__constant_htonl(NFSERR_MOVED)
 #define	nfserr_nofilehandle	__constant_htonl(NFSERR_NOFILEHANDLE)
 #define	nfserr_minor_vers_mismatch	__constant_htonl(NFSERR_MINOR_VERS_MISMATCH)
 #define nfserr_share_denied	__constant_htonl(NFSERR_SHARE_DENIED)
@@ -286,7 +293,6 @@
 /*
  * The following attributes are currently not supported by the NFSv4 server:
  *    ARCHIVE       (deprecated anyway)
- *    FS_LOCATIONS  (will be supported eventually)
  *    HIDDEN        (unlikely to be supported any time soon)
  *    MIMETYPE      (unlikely to be supported any time soon)
  *    QUOTA_*       (will be supported in a forthcoming patch)
@@ -302,7 +308,7 @@
  | FATTR4_WORD0_ACLSUPPORT      | FATTR4_WORD0_CANSETTIME   | FATTR4_WORD0_CASE_INSENSITIVE \
  | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED                             \
  | FATTR4_WORD0_FILEHANDLE      | FATTR4_WORD0_FILEID       | FATTR4_WORD0_FILES_AVAIL      \
- | FATTR4_WORD0_FILES_FREE      | FATTR4_WORD0_FILES_TOTAL  | FATTR4_WORD0_HOMOGENEOUS      \
+ | FATTR4_WORD0_FILES_FREE      | FATTR4_WORD0_FILES_TOTAL  | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS      \
  | FATTR4_WORD0_MAXFILESIZE     | FATTR4_WORD0_MAXLINK      | FATTR4_WORD0_MAXNAME          \
  | FATTR4_WORD0_MAXREAD         | FATTR4_WORD0_MAXWRITE     | FATTR4_WORD0_ACL)
 
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index 31a3cb6..069257e 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -290,8 +290,9 @@
  * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
  * so, any changes here should be reflected there.
  */
+
 static inline void
-fh_lock(struct svc_fh *fhp)
+fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
 {
 	struct dentry	*dentry = fhp->fh_dentry;
 	struct inode	*inode;
@@ -310,11 +311,17 @@
 	}
 
 	inode = dentry->d_inode;
-	mutex_lock(&inode->i_mutex);
+	mutex_lock_nested(&inode->i_mutex, subclass);
 	fill_pre_wcc(fhp);
 	fhp->fh_locked = 1;
 }
 
+static inline void
+fh_lock(struct svc_fh *fhp)
+{
+	fh_lock_nested(fhp, I_MUTEX_NORMAL);
+}
+
 /*
  * Unlock a file handle/inode
  */
diff --git a/include/linux/nfsd/stats.h b/include/linux/nfsd/stats.h
index 28a82fd..7678cfb 100644
--- a/include/linux/nfsd/stats.h
+++ b/include/linux/nfsd/stats.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/nfsd/stats.h
+ * linux/include/linux/nfsd/stats.h
  *
  * Statistics for NFS server.
  *
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
index dae0fae..8bcddcc 100644
--- a/include/linux/nfsd/syscall.h
+++ b/include/linux/nfsd/syscall.h
@@ -38,21 +38,6 @@
 #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;
@@ -134,8 +119,6 @@
 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/xdr.h b/include/linux/nfsd/xdr.h
index 3f4f714..0e53de8 100644
--- a/include/linux/nfsd/xdr.h
+++ b/include/linux/nfsd/xdr.h
@@ -1,5 +1,5 @@
 /*
- * linux/inxlude/linux/nfsd/xdr.h
+ * linux/include/linux/nfsd/xdr.h
  *
  * XDR types for nfsd. This is mainly a typing exercise.
  */
@@ -30,7 +30,6 @@
 	struct svc_fh		fh;
 	__u32			offset;
 	__u32			count;
-	struct kvec		vec[RPCSVC_MAXPAGES];
 	int			vlen;
 };
 
@@ -38,7 +37,6 @@
 	svc_fh			fh;
 	__u32			offset;
 	int			len;
-	struct kvec		vec[RPCSVC_MAXPAGES];
 	int			vlen;
 };
 
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
index a432274..474d882 100644
--- a/include/linux/nfsd/xdr3.h
+++ b/include/linux/nfsd/xdr3.h
@@ -33,7 +33,6 @@
 	struct svc_fh		fh;
 	__u64			offset;
 	__u32			count;
-	struct kvec		vec[RPCSVC_MAXPAGES];
 	int			vlen;
 };
 
@@ -43,7 +42,6 @@
 	__u32			count;
 	int			stable;
 	__u32			len;
-	struct kvec		vec[RPCSVC_MAXPAGES];
 	int			vlen;
 };
 
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 77adba7..66e6427 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -241,7 +241,6 @@
 	stateid_t	rd_stateid;         /* request */
 	u64		rd_offset;          /* request */
 	u32		rd_length;          /* request */
-	struct kvec	rd_iov[RPCSVC_MAXPAGES];
 	int		rd_vlen;
 	struct file     *rd_filp;
 	
@@ -326,7 +325,6 @@
 	u64		wr_offset;          /* request */
 	u32		wr_stable_how;      /* request */
 	u32		wr_buflen;          /* request */
-	struct kvec	wr_vec[RPCSVC_MAXPAGES]; /* request */
 	int		wr_vlen;
 
 	u32		wr_bytes_written;   /* response */
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 1a9ef3e..5dce5c2 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -352,6 +352,7 @@
 #define node_possible(node)	node_isset((node), node_possible_map)
 #define first_online_node	first_node(node_online_map)
 #define next_online_node(nid)	next_node((nid), node_online_map)
+int highest_possible_node_id(void);
 #else
 #define num_online_nodes()	1
 #define num_possible_nodes()	1
@@ -359,6 +360,7 @@
 #define node_possible(node)	((node) == 0)
 #define first_online_node	0
 #define next_online_node(nid)	(MAX_NUMNODES)
+#define highest_possible_node_id()	0
 #endif
 
 #define any_online_node(mask)			\
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 7ff386a..10a43ed 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -12,9 +12,10 @@
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/rwsem.h>
+#include <linux/srcu.h>
 
 /*
- * Notifier chains are of three types:
+ * Notifier chains are of four types:
  *
  *	Atomic notifier chains: Chain callbacks run in interrupt/atomic
  *		context. Callouts are not allowed to block.
@@ -23,13 +24,27 @@
  *	Raw notifier chains: There are no restrictions on callbacks,
  *		registration, or unregistration.  All locking and protection
  *		must be provided by the caller.
+ *	SRCU notifier chains: A variant of blocking notifier chains, with
+ *		the same restrictions.
  *
  * atomic_notifier_chain_register() may be called from an atomic context,
- * but blocking_notifier_chain_register() must be called from a process
- * context.  Ditto for the corresponding _unregister() routines.
+ * but blocking_notifier_chain_register() and srcu_notifier_chain_register()
+ * must be called from a process context.  Ditto for the corresponding
+ * _unregister() routines.
  *
- * atomic_notifier_chain_unregister() and blocking_notifier_chain_unregister()
- * _must not_ be called from within the call chain.
+ * atomic_notifier_chain_unregister(), blocking_notifier_chain_unregister(),
+ * and srcu_notifier_chain_unregister() _must not_ be called from within
+ * the call chain.
+ *
+ * SRCU notifier chains are an alternative form of blocking notifier chains.
+ * They use SRCU (Sleepable Read-Copy Update) instead of rw-semaphores for
+ * protection of the chain links.  This means there is _very_ low overhead
+ * in srcu_notifier_call_chain(): no cache bounces and no memory barriers.
+ * As compensation, srcu_notifier_chain_unregister() is rather expensive.
+ * SRCU notifier chains should be used when the chain will be called very
+ * often but notifier_blocks will seldom be removed.  Also, SRCU notifier
+ * chains are slightly more difficult to use because they require special
+ * runtime initialization.
  */
 
 struct notifier_block {
@@ -52,6 +67,12 @@
 	struct notifier_block *head;
 };
 
+struct srcu_notifier_head {
+	struct mutex mutex;
+	struct srcu_struct srcu;
+	struct notifier_block *head;
+};
+
 #define ATOMIC_INIT_NOTIFIER_HEAD(name) do {	\
 		spin_lock_init(&(name)->lock);	\
 		(name)->head = NULL;		\
@@ -64,6 +85,11 @@
 		(name)->head = NULL;		\
 	} while (0)
 
+/* srcu_notifier_heads must be initialized and cleaned up dynamically */
+extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
+#define srcu_cleanup_notifier_head(name)	\
+		cleanup_srcu_struct(&(name)->srcu);
+
 #define ATOMIC_NOTIFIER_INIT(name) {				\
 		.lock = __SPIN_LOCK_UNLOCKED(name.lock),	\
 		.head = NULL }
@@ -72,6 +98,7 @@
 		.head = NULL }
 #define RAW_NOTIFIER_INIT(name)	{				\
 		.head = NULL }
+/* srcu_notifier_heads cannot be initialized statically */
 
 #define ATOMIC_NOTIFIER_HEAD(name)				\
 	struct atomic_notifier_head name =			\
@@ -91,6 +118,8 @@
 		struct notifier_block *);
 extern int raw_notifier_chain_register(struct raw_notifier_head *,
 		struct notifier_block *);
+extern int srcu_notifier_chain_register(struct srcu_notifier_head *,
+		struct notifier_block *);
 
 extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *,
 		struct notifier_block *);
@@ -98,6 +127,8 @@
 		struct notifier_block *);
 extern int raw_notifier_chain_unregister(struct raw_notifier_head *,
 		struct notifier_block *);
+extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *,
+		struct notifier_block *);
 
 extern int atomic_notifier_call_chain(struct atomic_notifier_head *,
 		unsigned long val, void *v);
@@ -105,6 +136,8 @@
 		unsigned long val, void *v);
 extern int raw_notifier_call_chain(struct raw_notifier_head *,
 		unsigned long val, void *v);
+extern int srcu_notifier_call_chain(struct srcu_notifier_head *,
+		unsigned long val, void *v);
 
 #define NOTIFY_DONE		0x0000		/* Don't care */
 #define NOTIFY_OK		0x0001		/* Suits me */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
new file mode 100644
index 0000000..f6baecd
--- /dev/null
+++ b/include/linux/nsproxy.h
@@ -0,0 +1,52 @@
+#ifndef _LINUX_NSPROXY_H
+#define _LINUX_NSPROXY_H
+
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+
+struct namespace;
+struct uts_namespace;
+struct ipc_namespace;
+
+/*
+ * A structure to contain pointers to all per-process
+ * namespaces - fs (mount), uts, network, sysvipc, etc.
+ *
+ * 'count' is the number of tasks holding a reference.
+ * The count for each namespace, then, will be the number
+ * of nsproxies pointing to it, not the number of tasks.
+ *
+ * The nsproxy is shared by tasks which share all namespaces.
+ * As soon as a single namespace is cloned or unshared, the
+ * nsproxy is copied.
+ */
+struct nsproxy {
+	atomic_t count;
+	spinlock_t nslock;
+	struct uts_namespace *uts_ns;
+	struct ipc_namespace *ipc_ns;
+	struct namespace *namespace;
+};
+extern struct nsproxy init_nsproxy;
+
+struct nsproxy *dup_namespaces(struct nsproxy *orig);
+int copy_namespaces(int flags, struct task_struct *tsk);
+void get_task_namespaces(struct task_struct *tsk);
+void free_nsproxy(struct nsproxy *ns);
+
+static inline void put_nsproxy(struct nsproxy *ns)
+{
+	if (atomic_dec_and_test(&ns->count)) {
+		free_nsproxy(ns);
+	}
+}
+
+static inline void exit_task_namespaces(struct task_struct *p)
+{
+	struct nsproxy *ns = p->nsproxy;
+	if (ns) {
+		put_nsproxy(ns);
+		p->nsproxy = NULL;
+	}
+}
+#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 4431ce4..5c604f5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -595,6 +595,7 @@
 	u16	entry;	/* driver uses to specify entry, OS writes */
 };
 
+
 #ifndef CONFIG_PCI_MSI
 static inline void pci_scan_msi_device(struct pci_dev *dev) {}
 static inline int pci_enable_msi(struct pci_dev *dev) {return -1;}
@@ -613,6 +614,12 @@
 extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
 #endif
 
+#ifdef CONFIG_HT_IRQ
+/* The functions a driver should call */
+int  ht_create_irq(struct pci_dev *dev, int idx);
+void ht_destroy_irq(unsigned int irq);
+#endif /* CONFIG_HT_IRQ */
+
 extern void pci_block_user_cfg_access(struct pci_dev *dev);
 extern void pci_unblock_user_cfg_access(struct pci_dev *dev);
 
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index c9ffbc3..f069df2 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1615,8 +1615,6 @@
 #define PCI_VENDOR_ID_ROCKWELL		0x127A
 
 #define PCI_VENDOR_ID_ITE		0x1283
-#define PCI_DEVICE_ID_ITE_IT8172G	0x8172
-#define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
 #define PCI_DEVICE_ID_ITE_8211		0x8211
 #define PCI_DEVICE_ID_ITE_8212		0x8212
 #define PCI_DEVICE_ID_ITE_8872		0x8872
@@ -1883,6 +1881,8 @@
 #define PCI_DEVICE_ID_PANACOM_QUADMODEM	0x0400
 #define PCI_DEVICE_ID_PANACOM_DUALMODEM	0x0402
 
+#define PCI_VENDOR_ID_SIPACKETS		0x14d9
+#define PCI_DEVICE_ID_SP1011		0x0010
 
 #define PCI_VENDOR_ID_AFAVLAB		0x14db
 #define PCI_DEVICE_ID_AFAVLAB_P028	0x2180
@@ -1997,6 +1997,7 @@
 #define PCI_DEVICE_ID_FARSITE_TE1C      0x1612
 
 #define PCI_VENDOR_ID_SIBYTE		0x166d
+#define PCI_DEVICE_ID_BCM1250_PCI	0x0001
 #define PCI_DEVICE_ID_BCM1250_HT	0x0002
 
 #define PCI_VENDOR_ID_NETCELL		0x169c
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 7d0e26c..c312a12 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -12,6 +12,11 @@
  *	PCI Local Bus Specification
  *	PCI to PCI Bridge Specification
  *	PCI System Design Guide
+ *
+ * 	For hypertransport information, please consult the following manuals
+ * 	from http://www.hypertransport.org
+ *
+ *	The Hypertransport I/O Link Specification
  */
 
 #ifndef LINUX_PCI_REGS_H
@@ -463,4 +468,20 @@
 #define PCI_PWR_CAP		12	/* Capability */
 #define  PCI_PWR_CAP_BUDGET(x)	((x) & 1)	/* Included in system budget */
 
+/* Hypertransport sub capability types */
+#define HT_CAPTYPE_SLAVE	0x00	/* Slave/Primary link configuration */
+#define HT_CAPTYPE_HOST		0x20	/* Host/Secondary link configuration */
+#define HT_CAPTYPE_IRQ		0x80	/* IRQ Configuration */
+#define HT_CAPTYPE_REMAPPING_40	0xA0	/* 40 bit address remapping */
+#define HT_CAPTYPE_REMAPPING_64 0xA2	/* 64 bit address remapping */
+#define HT_CAPTYPE_UNITID_CLUMP	0x90	/* Unit ID clumping */
+#define HT_CAPTYPE_EXTCONF	0x98	/* Extended Configuration Space Access */
+#define HT_CAPTYPE_MSI_MAPPING	0xA8	/* MSI Mapping Capability */
+#define HT_CAPTYPE_DIRECT_ROUTE	0xB0	/* Direct routing configuration */
+#define HT_CAPTYPE_VCSET	0xB8	/* Virtual Channel configuration */
+#define HT_CAPTYPE_ERROR_RETRY	0xC0	/* Retry on error configuration */
+#define HT_CAPTYPE_GEN3		0xD0	/* Generation 3 hypertransport configuration */
+#define HT_CAPTYPE_PM		0xE0	/* Hypertransport powermanagement configuration */
+
+
 #endif /* LINUX_PCI_REGS_H */
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 93da7e2..2c0007d 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -68,6 +68,8 @@
 extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
 						enum pid_type));
 
+extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type);
+
 /*
  * attach_pid() and detach_pid() must be called with the tasklist_lock
  * write-held.
@@ -89,33 +91,42 @@
  * Lookup a PID in the hash table, and return with it's count elevated.
  */
 extern struct pid *find_get_pid(int nr);
+extern struct pid *find_ge_pid(int nr);
 
 extern struct pid *alloc_pid(void);
 extern void FASTCALL(free_pid(struct pid *pid));
 
-#define pid_next(task, type)					\
-	((task)->pids[(type)].node.next)
-
-#define pid_next_task(task, type) 				\
-	hlist_entry(pid_next(task, type), struct task_struct,	\
-			pids[(type)].node)
+static inline pid_t pid_nr(struct pid *pid)
+{
+	pid_t nr = 0;
+	if (pid)
+		nr = pid->nr;
+	return nr;
+}
 
 
-/* We could use hlist_for_each_entry_rcu here but it takes more arguments
- * than the do_each_task_pid/while_each_task_pid.  So we roll our own
- * to preserve the existing interface.
- */
 #define do_each_task_pid(who, type, task)				\
-	if ((task = find_task_by_pid_type(type, who))) {		\
-		prefetch(pid_next(task, type));				\
-		do {
+	do {								\
+		struct hlist_node *pos___;				\
+		struct pid *pid___ = find_pid(who);			\
+		if (pid___ != NULL)					\
+			hlist_for_each_entry_rcu((task), pos___,	\
+				&pid___->tasks[type], pids[type].node) {
 
 #define while_each_task_pid(who, type, task)				\
-		} while (pid_next(task, type) &&  ({			\
-				task = pid_next_task(task, type);	\
-				rcu_dereference(task);			\
-				prefetch(pid_next(task, type));		\
-				1; }) );				\
-	}
+			}						\
+	} while (0)
+
+
+#define do_each_pid_task(pid, type, task)				\
+	do {								\
+		struct hlist_node *pos___;				\
+		if (pid != NULL)					\
+			hlist_for_each_entry_rcu((task), pos___,	\
+				&pid->tasks[type], pids[type].node) {
+
+#define while_each_pid_task(pid, type, task)				\
+			}						\
+	} while (0)
 
 #endif /* _LINUX_PID_H */
diff --git a/include/linux/ppdev.h b/include/linux/ppdev.h
index f376a75..dc18c5d 100644
--- a/include/linux/ppdev.h
+++ b/include/linux/ppdev.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/char/ppdev.h
+ * linux/include/linux/ppdev.h
  *
  * User-space parallel port device driver (header file).
  *
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 57f70bc..87dec8f 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -244,13 +244,15 @@
 extern void kclist_add(struct kcore_list *, void *, size_t);
 #endif
 
+union proc_op {
+	int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
+	int (*proc_read)(struct task_struct *task, char *page);
+};
+
 struct proc_inode {
 	struct pid *pid;
 	int fd;
-	union {
-		int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
-		int (*proc_read)(struct task_struct *task, char *page);
-	} op;
+	union proc_op op;
 	struct proc_dir_entry *pde;
 	struct inode vfs_inode;
 };
diff --git a/include/linux/pspace.h b/include/linux/pspace.h
new file mode 100644
index 0000000..91d48b8
--- /dev/null
+++ b/include/linux/pspace.h
@@ -0,0 +1,23 @@
+#ifndef _LINUX_PSPACE_H
+#define _LINUX_PSPACE_H
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <linux/pid.h>
+
+struct pidmap {
+       atomic_t nr_free;
+       void *page;
+};
+
+#define PIDMAP_ENTRIES         ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)
+
+struct pspace {
+       struct pidmap pidmap[PIDMAP_ENTRIES];
+       int last_pid;
+};
+
+extern struct pspace init_pspace;
+
+#endif /* _LINUX_PSPACE_H */
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 63df898..84d8877 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -265,6 +265,8 @@
 int  bitmap_setallbits(struct bitmap *bitmap);
 void bitmap_write_all(struct bitmap *bitmap);
 
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e);
+
 /* these are exported */
 int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
 			unsigned long sectors, int behind);
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index c588709..866a1e2 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -95,7 +95,6 @@
 extern void md_do_sync(mddev_t *mddev);
 extern void md_new_event(mddev_t *mddev);
 
-extern void md_update_sb(mddev_t * mddev);
 
 #endif /* CONFIG_MD */
 #endif 
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 920b94f..8245c28 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -31,18 +31,15 @@
 #define	LEVEL_NONE		(-1000000)
 
 #define MaxSector (~(sector_t)0)
-#define MD_THREAD_NAME_MAX 14
 
 typedef struct mddev_s mddev_t;
 typedef struct mdk_rdev_s mdk_rdev_t;
 
-#define MAX_MD_DEVS  256	/* Max number of md dev */
-
 /*
  * options passed in raidrun:
  */
 
-/* Currently this must fix in an 'int' */
+/* Currently this must fit in an 'int' */
 #define MAX_CHUNK_SIZE (1<<30)
 
 /*
@@ -116,7 +113,11 @@
 	dev_t				unit;
 	int				md_minor;
 	struct list_head 		disks;
-	int				sb_dirty;
+	unsigned long			flags;
+#define MD_CHANGE_DEVS	0	/* Some device status has changed */
+#define MD_CHANGE_CLEAN 1	/* transition to or from 'clean' */
+#define MD_CHANGE_PENDING 2	/* superblock update in progress */
+
 	int				ro;
 
 	struct gendisk			*gendisk;
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h
index 81da20c..7192035 100644
--- a/include/linux/raid/md_u.h
+++ b/include/linux/raid/md_u.h
@@ -41,7 +41,7 @@
 
 /* usage */
 #define RUN_ARRAY		_IOW (MD_MAJOR, 0x30, mdu_param_t)
-#define START_ARRAY		_IO (MD_MAJOR, 0x31)
+/*  0x31 was START_ARRAY  */
 #define STOP_ARRAY		_IO (MD_MAJOR, 0x32)
 #define STOP_ARRAY_RO		_IO (MD_MAJOR, 0x33)
 #define RESTART_ARRAY_RW	_IO (MD_MAJOR, 0x34)
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 3009c81..0a9ba7c 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -30,7 +30,6 @@
 	mddev_t			*mddev;
 	mirror_info_t		*mirrors;
 	int			raid_disks;
-	int			working_disks;
 	int			last_used;
 	sector_t		next_seq_sect;
 	spinlock_t		device_lock;
diff --git a/include/linux/raid/raid10.h b/include/linux/raid/raid10.h
index c41e56a..e9091cf 100644
--- a/include/linux/raid/raid10.h
+++ b/include/linux/raid/raid10.h
@@ -16,7 +16,6 @@
 	mddev_t			*mddev;
 	mirror_info_t		*mirrors;
 	int			raid_disks;
-	int			working_disks;
 	spinlock_t		device_lock;
 
 	/* geometry */
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 20ed4c9..f13299a 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -195,8 +195,9 @@
  * it to the count of prereading stripes.
  * When write is initiated, or the stripe refcnt == 0 (just in case) we
  * clear the PREREAD_ACTIVE flag and decrement the count
- * Whenever the delayed queue is empty and the device is not plugged, we
- * move any strips from delayed to handle and clear the DELAYED flag and set PREREAD_ACTIVE.
+ * Whenever the 'handle' queue is empty and the device is not plugged, we
+ * move any strips from delayed to handle and clear the DELAYED flag and set
+ * PREREAD_ACTIVE.
  * In stripe_handle, if we find pre-reading is necessary, we do it if
  * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
  * HANDLE gets cleared if stripe_handle leave nothing locked.
@@ -213,7 +214,7 @@
 	struct disk_info	*spare;
 	int			chunk_size, level, algorithm;
 	int			max_degraded;
-	int			raid_disks, working_disks, failed_disks;
+	int			raid_disks;
 	int			max_nr_stripes;
 
 	/* used during an expand */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index b4ca73d..c6b7485 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -19,7 +19,7 @@
  *
  * Author: Dipankar Sarma <dipankar@in.ibm.com>
  * 
- * Based on the original work by Paul McKenney <paul.mckenney@us.ibm.com>
+ * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
  * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
  * Papers:
  * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf
@@ -66,6 +66,8 @@
 	long	completed;	/* Number of the last completed batch         */
 	int	next_pending;	/* Is the next batch already waiting?         */
 
+	int	signaled;
+
 	spinlock_t	lock	____cacheline_internodealigned_in_smp;
 	cpumask_t	cpumask; /* CPUs that need to switch in order    */
 	                         /* for current batch to proceed.        */
@@ -106,9 +108,6 @@
 	long		blimit;		 /* Upper limit on a processed batch */
 	int cpu;
 	struct rcu_head barrier;
-#ifdef CONFIG_SMP
-	long		last_rs_qlen;	 /* qlen during the last resched */
-#endif
 };
 
 DECLARE_PER_CPU(struct rcu_data, rcu_data);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 7ef899c..331f450 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -24,6 +24,8 @@
 #define CLONE_UNTRACED		0x00800000	/* set if the tracing process can't force CLONE_PTRACE on this clone */
 #define CLONE_CHILD_SETTID	0x01000000	/* set the TID in the child */
 #define CLONE_STOPPED		0x02000000	/* Start in stopped state */
+#define CLONE_NEWUTS		0x04000000	/* New utsname group? */
+#define CLONE_NEWIPC		0x08000000	/* New ipcs */
 
 /*
  * Scheduling policies
@@ -118,7 +120,6 @@
 
 extern unsigned long total_forks;
 extern int nr_threads;
-extern int last_pid;
 DECLARE_PER_CPU(unsigned long, process_counts);
 extern int nr_processes(void);
 extern unsigned long nr_running(void);
@@ -239,7 +240,7 @@
 extern signed long schedule_timeout_uninterruptible(signed long timeout);
 asmlinkage void schedule(void);
 
-struct namespace;
+struct nsproxy;
 
 /* Maximum number of active map areas.. This is a random (large) number */
 #define DEFAULT_MAX_MAP_COUNT	65536
@@ -624,9 +625,17 @@
 #define SD_WAKE_BALANCE		64	/* Perform balancing at task wakeup */
 #define SD_SHARE_CPUPOWER	128	/* Domain members share cpu power */
 #define SD_POWERSAVINGS_BALANCE	256	/* Balance for power savings */
+#define SD_SHARE_PKG_RESOURCES	512	/* Domain members share cpu pkg resources */
 
-#define BALANCE_FOR_POWER	((sched_mc_power_savings || sched_smt_power_savings) \
-				 ? SD_POWERSAVINGS_BALANCE : 0)
+#define BALANCE_FOR_MC_POWER	\
+	(sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0)
+
+#define BALANCE_FOR_PKG_POWER	\
+	((sched_mc_power_savings || sched_smt_power_savings) ?	\
+	 SD_POWERSAVINGS_BALANCE : 0)
+
+#define test_sd_parent(sd, flag)	((sd->parent &&		\
+					 (sd->parent->flags & flag)) ? 1 : 0)
 
 
 struct sched_group {
@@ -643,6 +652,7 @@
 struct sched_domain {
 	/* These fields must be setup */
 	struct sched_domain *parent;	/* top domain must be null terminated */
+	struct sched_domain *child;	/* bottom domain must be null terminated */
 	struct sched_group *groups;	/* the balancing groups of the domain */
 	cpumask_t span;			/* span of all CPUs in this domain */
 	unsigned long min_interval;	/* Minimum balance interval ms */
@@ -754,6 +764,7 @@
 struct audit_context;		/* See audit.c */
 struct mempolicy;
 struct pipe_inode_info;
+struct uts_namespace;
 
 enum sleep_type {
 	SLEEP_NORMAL,
@@ -897,8 +908,8 @@
 	struct fs_struct *fs;
 /* open file information */
 	struct files_struct *files;
-/* namespace */
-	struct namespace *namespace;
+/* namespaces */
+	struct nsproxy *nsproxy;
 /* signal handlers */
 	struct signal_struct *signal;
 	struct sighand_struct *sighand;
@@ -1020,6 +1031,26 @@
 	return tsk->signal->pgrp;
 }
 
+static inline struct pid *task_pid(struct task_struct *task)
+{
+	return task->pids[PIDTYPE_PID].pid;
+}
+
+static inline struct pid *task_tgid(struct task_struct *task)
+{
+	return task->group_leader->pids[PIDTYPE_PID].pid;
+}
+
+static inline struct pid *task_pgrp(struct task_struct *task)
+{
+	return task->group_leader->pids[PIDTYPE_PGID].pid;
+}
+
+static inline struct pid *task_session(struct task_struct *task)
+{
+	return task->group_leader->pids[PIDTYPE_SID].pid;
+}
+
 /**
  * pid_alive - check that a task structure is not stale
  * @p: Task structure to be checked.
@@ -1043,6 +1074,8 @@
 	return tsk->pid == 1;
 }
 
+extern struct pid *cad_pid;
+
 extern void free_task(struct task_struct *tsk);
 #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
 
@@ -1247,10 +1280,15 @@
 extern int send_group_sig_info(int, struct siginfo *, struct task_struct *);
 extern int force_sigsegv(int, struct task_struct *);
 extern int force_sig_info(int, struct siginfo *, struct task_struct *);
+extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
+extern int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
+extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid);
+extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_t, u32);
+extern int kill_pgrp(struct pid *pid, int sig, int priv);
+extern int kill_pid(struct pid *pid, int sig, int priv);
 extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
 extern int kill_pg_info(int, struct siginfo *, pid_t);
 extern int kill_proc_info(int, struct siginfo *, pid_t);
-extern int kill_proc_info_as_uid(int, struct siginfo *, pid_t, uid_t, uid_t, u32);
 extern void do_notify_parent(struct task_struct *, int);
 extern void force_sig(int, struct task_struct *);
 extern void force_sig_specific(int, struct task_struct *);
@@ -1265,6 +1303,11 @@
 extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
 extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long);
 
+static inline int kill_cad_pid(int sig, int priv)
+{
+	return kill_pid(cad_pid, sig, priv);
+}
+
 /* These can be the second arg to send_sig_info/send_group_sig_info.  */
 #define SEND_SIG_NOINFO ((struct siginfo *) 0)
 #define SEND_SIG_PRIV	((struct siginfo *) 1)
@@ -1358,6 +1401,17 @@
 /* de_thread depends on thread_group_leader not being a pid based check */
 #define thread_group_leader(p)	(p == p->group_leader)
 
+/* Do to the insanities of de_thread it is possible for a process
+ * to have the pid of the thread group leader without actually being
+ * the thread group leader.  For iteration through the pids in proc
+ * all we care about is that we have a task with the appropriate
+ * pid, we don't actually care if we have the right task.
+ */
+static inline int has_group_leader_pid(struct task_struct *p)
+{
+	return p->pid == p->tgid;
+}
+
 static inline struct task_struct *next_thread(const struct task_struct *p)
 {
 	return list_entry(rcu_dereference(p->thread_group.next),
diff --git a/include/linux/scx200.h b/include/linux/scx200.h
index 693c055..de466e1 100644
--- a/include/linux/scx200.h
+++ b/include/linux/scx200.h
@@ -32,7 +32,7 @@
 
 /* High Resolution Timer */
 #define SCx200_TIMER_OFFSET 0x08
-#define SCx200_TIMER_SIZE 0x05
+#define SCx200_TIMER_SIZE 0x06
 
 /* Clock Generators */
 #define SCx200_CLOCKGEN_OFFSET 0x10
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 86501a3..de2e681 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -319,6 +319,7 @@
 #define UIF_CTS_FLOW		((__force uif_t) (1 << 26))
 #define UIF_NORMAL_ACTIVE	((__force uif_t) (1 << 29))
 #define UIF_INITIALIZED		((__force uif_t) (1 << 31))
+#define UIF_SUSPENDED		((__force uif_t) (1 << 30))
 
 	int			blocked_open;
 
@@ -414,7 +415,7 @@
 #ifdef SUPPORT_SYSRQ
 	if (port->sysrq) {
 		if (ch && time_before(jiffies, port->sysrq)) {
-			handle_sysrq(ch, regs, NULL);
+			handle_sysrq(ch, regs, port->info->tty);
 			port->sysrq = 0;
 			return 1;
 		}
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 6348e83..c906931 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -217,5 +217,8 @@
 #define SERIO_LKKBD	0x28
 #define SERIO_ELO	0x29
 #define SERIO_MICROTOUCH	0x30
+#define SERIO_PENMOUNT	0x31
+#define SERIO_TOUCHRIGHT	0x32
+#define SERIO_TOUCHWIN	0x33
 
 #endif
diff --git a/include/linux/slab.h b/include/linux/slab.h
index a96fd93..c4947b8 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -1,5 +1,5 @@
 /*
- * linux/mm/slab.h
+ * linux/include/linux/slab.h
  * Written by Mark Hemment, 1996.
  * (markhe@nextd.demon.co.uk)
  */
@@ -77,13 +77,6 @@
 extern struct cache_sizes malloc_sizes[];
 
 extern void *__kmalloc(size_t, gfp_t);
-#ifndef CONFIG_DEBUG_SLAB
-#define ____kmalloc(size, flags) __kmalloc(size, flags)
-#else
-extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
-#define ____kmalloc(size, flags) \
-    __kmalloc_track_caller(size, flags, __builtin_return_address(0))
-#endif
 
 /**
  * kmalloc - allocate memory
@@ -153,6 +146,23 @@
 	return __kmalloc(size, flags);
 }
 
+/*
+ * kmalloc_track_caller is a special version of kmalloc that records the
+ * calling function of the routine calling it for slab leak tracking instead
+ * of just the calling function (confusing, eh?).
+ * It's useful when the call to kmalloc comes from a widely-used standard
+ * allocator where we care about the real place the memory allocation
+ * request comes from.
+ */
+#ifndef CONFIG_DEBUG_SLAB
+#define kmalloc_track_caller(size, flags) \
+	__kmalloc(size, flags)
+#else
+extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
+#define kmalloc_track_caller(size, flags) \
+	__kmalloc_track_caller(size, flags, __builtin_return_address(0))
+#endif
+
 extern void *__kzalloc(size_t, gfp_t);
 
 /**
@@ -271,7 +281,7 @@
 #define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
 #define kmalloc_node(s, f, n) kmalloc(s, f)
 #define kzalloc(s, f) __kzalloc(s, f)
-#define ____kmalloc kmalloc
+#define kmalloc_track_caller kmalloc
 
 #endif /* CONFIG_SLOB */
 
diff --git a/include/linux/sound.h b/include/linux/sound.h
index f63d834..9e2a94f 100644
--- a/include/linux/sound.h
+++ b/include/linux/sound.h
@@ -35,10 +35,8 @@
 extern int register_sound_mixer(const struct file_operations *fops, int dev);
 extern int register_sound_midi(const struct file_operations *fops, int dev);
 extern int register_sound_dsp(const struct file_operations *fops, int dev);
-extern int register_sound_synth(const struct file_operations *fops, int dev);
 
 extern void unregister_sound_special(int unit);
 extern void unregister_sound_mixer(int unit);
 extern void unregister_sound_midi(int unit);
 extern void unregister_sound_dsp(int unit);
-extern void unregister_sound_synth(int unit);
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
new file mode 100644
index 0000000..aca0eee
--- /dev/null
+++ b/include/linux/srcu.h
@@ -0,0 +1,53 @@
+/*
+ * Sleepable Read-Copy Update mechanism for mutual exclusion
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Paul McKenney <paulmck@us.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ * 		Documentation/RCU/ *.txt
+ *
+ */
+
+#ifndef _LINUX_SRCU_H
+#define _LINUX_SRCU_H
+
+struct srcu_struct_array {
+	int c[2];
+};
+
+struct srcu_struct {
+	int completed;
+	struct srcu_struct_array *per_cpu_ref;
+	struct mutex mutex;
+};
+
+#ifndef CONFIG_PREEMPT
+#define srcu_barrier() barrier()
+#else /* #ifndef CONFIG_PREEMPT */
+#define srcu_barrier()
+#endif /* #else #ifndef CONFIG_PREEMPT */
+
+int init_srcu_struct(struct srcu_struct *sp);
+void cleanup_srcu_struct(struct srcu_struct *sp);
+int srcu_read_lock(struct srcu_struct *sp) __acquires(sp);
+void srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp);
+void synchronize_srcu(struct srcu_struct *sp);
+long srcu_batches_completed(struct srcu_struct *sp);
+
+#endif
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 8669291..679ef0d 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -57,7 +57,7 @@
 #include <linux/time.h>
 
 struct kstat {
-	unsigned long	ino;
+	u64		ino;
 	dev_t		dev;
 	umode_t		mode;
 	unsigned int	nlink;
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 862c0d8c..534cdc7 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -20,9 +20,6 @@
 /* size of the nodename buffer */
 #define UNX_MAXNODENAME	32
 
-/* Maximum size (in bytes) of an rpc credential or verifier */
-#define RPC_MAX_AUTH_SIZE (400)
-
 /* Work around the lack of a VFS credential */
 struct auth_cred {
 	uid_t	uid;
diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
index 03084dc..97b62e9 100644
--- a/include/linux/sunrpc/auth_gss.h
+++ b/include/linux/sunrpc/auth_gss.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/auth_gss.h
+ * linux/include/linux/sunrpc/auth_gss.h
  *
  * Declarations for RPCSEC_GSS
  *
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index b5612c9..3699dff 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -163,6 +163,17 @@
 	kref_put(&h->ref, cd->cache_put);
 }
 
+static inline int cache_valid(struct cache_head *h)
+{
+	/* If an item has been unhashed pending removal when
+	 * the refcount drops to 0, the expiry_time will be
+	 * set to 0.  We don't want to consider such items
+	 * valid in this context even though CACHE_VALID is
+	 * set.
+	 */
+	return (h->expiry_time != 0 && test_bit(CACHE_VALID, &h->flags));
+}
+
 extern int cache_check(struct cache_detail *detail,
 		       struct cache_head *h, struct cache_req *rqstp);
 extern void cache_flush(void);
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
index 6e112cc..5eca9e4 100644
--- a/include/linux/sunrpc/gss_api.h
+++ b/include/linux/sunrpc/gss_api.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/gss_api.h
+ * linux/include/linux/sunrpc/gss_api.h
  *
  * Somewhat simplified version of the gss api.
  *
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index d9f5934..1e65f2d 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/net/sunrpc/msg_prot.h
+ * linux/include/linux/sunrpc/msg_prot.h
  *
  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  */
@@ -11,6 +11,9 @@
 
 #define RPC_VERSION 2
 
+/* size of an XDR encoding unit in bytes, i.e. 32bit */
+#define XDR_UNIT	(4)
+
 /* spec defines authentication flavor as an unsigned 32 bit integer */
 typedef u32	rpc_authflavor_t;
 
@@ -34,6 +37,9 @@
 	RPC_AUTH_GSS_SPKMP = 390011,
 };
 
+/* Maximum size (in bytes) of an rpc credential or verifier */
+#define RPC_MAX_AUTH_SIZE (400)
+
 enum rpc_msg_type {
 	RPC_CALL = 0,
 	RPC_REPLY = 1
@@ -101,5 +107,39 @@
 #define	RPC_FRAGMENT_SIZE_MASK		(~RPC_LAST_STREAM_FRAGMENT)
 #define	RPC_MAX_FRAGMENT_SIZE		((1U << 31) - 1)
 
+/*
+ * RPC call and reply header size as number of 32bit words (verifier
+ * size computed separately, see below)
+ */
+#define RPC_CALLHDRSIZE		(6)
+#define RPC_REPHDRSIZE		(4)
+
+
+/*
+ * Maximum RPC header size, including authentication,
+ * as number of 32bit words (see RFCs 1831, 1832).
+ *
+ *	xid			    1 xdr unit = 4 bytes
+ *	mtype			    1
+ *	rpc_version		    1
+ *	program			    1
+ *	prog_version		    1
+ *	procedure		    1
+ *	cred {
+ *	    flavor		    1
+ *	    length		    1
+ *	    body<RPC_MAX_AUTH_SIZE> 100 xdr units = 400 bytes
+ *	}
+ *	verf {
+ *	    flavor		    1
+ *	    length		    1
+ *	    body<RPC_MAX_AUTH_SIZE> 100 xdr units = 400 bytes
+ *	}
+ *	TOTAL			    210 xdr units = 840 bytes
+ */
+#define RPC_MAX_HEADER_WITH_AUTH \
+	(RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4))
+
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 73140ee..d6288e8 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -13,11 +13,36 @@
 #include <linux/in.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/auth.h>
 #include <linux/sunrpc/svcauth.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 
 /*
+ * This is the RPC server thread function prototype
+ */
+typedef void		(*svc_thread_fn)(struct svc_rqst *);
+
+/*
+ *
+ * RPC service thread pool.
+ *
+ * Pool of threads and temporary sockets.  Generally there is only
+ * a single one of these per RPC service, but on NUMA machines those
+ * services that can benefit from it (i.e. nfs but not lockd) will
+ * have one pool per NUMA node.  This optimisation reduces cross-
+ * node traffic on multi-node NUMA NFS servers.
+ */
+struct svc_pool {
+	unsigned int		sp_id;	    	/* pool id; also node id on NUMA */
+	spinlock_t		sp_lock;	/* protects all fields */
+	struct list_head	sp_threads;	/* idle server threads */
+	struct list_head	sp_sockets;	/* pending sockets */
+	unsigned int		sp_nrthreads;	/* # of threads in pool */
+	struct list_head	sp_all_threads;	/* all server threads */
+} ____cacheline_aligned_in_smp;
+
+/*
  * RPC service.
  *
  * An RPC service is a ``daemon,'' possibly multithreaded, which
@@ -28,8 +53,6 @@
  * We currently do not support more than one RPC program per daemon.
  */
 struct svc_serv {
-	struct list_head	sv_threads;	/* idle server threads */
-	struct list_head	sv_sockets;	/* pending sockets */
 	struct svc_program *	sv_program;	/* RPC program */
 	struct svc_stat *	sv_stats;	/* RPC statistics */
 	spinlock_t		sv_lock;
@@ -40,16 +63,61 @@
 	struct list_head	sv_permsocks;	/* all permanent sockets */
 	struct list_head	sv_tempsocks;	/* all temporary sockets */
 	int			sv_tmpcnt;	/* count of temporary sockets */
+	struct timer_list	sv_temptimer;	/* timer for aging temporary sockets */
 
 	char *			sv_name;	/* service name */
+
+	unsigned int		sv_nrpools;	/* number of thread pools */
+	struct svc_pool *	sv_pools;	/* array of thread pools */
+
+	void			(*sv_shutdown)(struct svc_serv *serv);
+						/* Callback to use when last thread
+						 * exits.
+						 */
+
+	struct module *		sv_module;	/* optional module to count when
+						 * adding threads */
+	svc_thread_fn		sv_function;	/* main function for threads */
+	int			sv_kill_signal;	/* signal to kill threads */
 };
 
 /*
+ * We use sv_nrthreads as a reference count.  svc_destroy() drops
+ * this refcount, so we need to bump it up around operations that
+ * change the number of threads.  Horrible, but there it is.
+ * Should be called with the BKL held.
+ */
+static inline void svc_get(struct svc_serv *serv)
+{
+	serv->sv_nrthreads++;
+}
+
+/*
  * Maximum payload size supported by a kernel RPC server.
  * This is use to determine the max number of pages nfsd is
  * willing to return in a single READ operation.
+ *
+ * These happen to all be powers of 2, which is not strictly
+ * necessary but helps enforce the real limitation, which is
+ * that they should be multiples of PAGE_CACHE_SIZE.
+ *
+ * For UDP transports, a block plus NFS,RPC, and UDP headers
+ * has to fit into the IP datagram limit of 64K.  The largest
+ * feasible number for all known page sizes is probably 48K,
+ * but we choose 32K here.  This is the same as the historical
+ * Linux limit; someone who cares more about NFS/UDP performance
+ * can test a larger number.
+ *
+ * For TCP transports we have more freedom.  A size of 1MB is
+ * chosen to match the client limit.  Other OSes are known to
+ * have larger limits, but those numbers are probably beyond
+ * the point of diminishing returns.
  */
-#define RPCSVC_MAXPAYLOAD	(64*1024u)
+#define RPCSVC_MAXPAYLOAD	(1*1024*1024u)
+#define RPCSVC_MAXPAYLOAD_TCP	RPCSVC_MAXPAYLOAD
+#define RPCSVC_MAXPAYLOAD_UDP	(32*1024u)
+
+extern u32 svc_max_payload(const struct svc_rqst *rqstp);
 
 /*
  * RPC Requsts and replies are stored in one or more pages.
@@ -123,15 +191,16 @@
 /*
  * The context of a single thread, including the request currently being
  * processed.
- * NOTE: First two items must be prev/next.
  */
 struct svc_rqst {
 	struct list_head	rq_list;	/* idle list */
+	struct list_head	rq_all;		/* all threads list */
 	struct svc_sock *	rq_sock;	/* socket */
 	struct sockaddr_in	rq_addr;	/* peer address */
 	int			rq_addrlen;
 
 	struct svc_serv *	rq_server;	/* RPC service definition */
+	struct svc_pool *	rq_pool;	/* thread pool */
 	struct svc_procedure *	rq_procinfo;	/* procedure info */
 	struct auth_ops *	rq_authop;	/* authentication flavour */
 	struct svc_cred		rq_cred;	/* auth info */
@@ -140,12 +209,11 @@
 
 	struct xdr_buf		rq_arg;
 	struct xdr_buf		rq_res;
-	struct page *		rq_argpages[RPCSVC_MAXPAGES];
-	struct page *		rq_respages[RPCSVC_MAXPAGES];
-	int			rq_restailpage;
-	short			rq_argused;	/* pages used for argument */
-	short			rq_arghi;	/* pages available in argument page list */
-	short			rq_resused;	/* pages used for result */
+	struct page *		rq_pages[RPCSVC_MAXPAGES];
+	struct page *		*rq_respages;	/* points into rq_pages */
+	int			rq_resused;	/* number of pages used for result */
+
+	struct kvec		rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
 
 	__be32			rq_xid;		/* transmission id */
 	u32			rq_prog;	/* program number */
@@ -180,6 +248,7 @@
 						 * to prevent encrypting page
 						 * cache pages */
 	wait_queue_head_t	rq_wait;	/* synchronization */
+	struct task_struct	*rq_task;	/* service thread */
 };
 
 /*
@@ -205,63 +274,18 @@
 	return vec->iov_len <= PAGE_SIZE;
 }
 
-static inline struct page *
-svc_take_res_page(struct svc_rqst *rqstp)
+static inline void svc_free_res_pages(struct svc_rqst *rqstp)
 {
-	if (rqstp->rq_arghi <= rqstp->rq_argused)
-		return NULL;
-	rqstp->rq_arghi--;
-	rqstp->rq_respages[rqstp->rq_resused] =
-		rqstp->rq_argpages[rqstp->rq_arghi];
-	return rqstp->rq_respages[rqstp->rq_resused++];
-}
-
-static inline void svc_take_page(struct svc_rqst *rqstp)
-{
-	if (rqstp->rq_arghi <= rqstp->rq_argused) {
-		WARN_ON(1);
-		return;
-	}
-	rqstp->rq_arghi--;
-	rqstp->rq_respages[rqstp->rq_resused] =
-		rqstp->rq_argpages[rqstp->rq_arghi];
-	rqstp->rq_resused++;
-}
-
-static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
-{
-        while (rqstp->rq_resused) {
-		if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
-			continue;
-		rqstp->rq_argpages[rqstp->rq_arghi++] =
-			rqstp->rq_respages[rqstp->rq_resused];
-		rqstp->rq_respages[rqstp->rq_resused] = NULL;
-	}
-}
-
-static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
-{
-	while (rqstp->rq_resused &&
-	       rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
-
-		if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
-			rqstp->rq_argpages[rqstp->rq_arghi++] =
-				rqstp->rq_respages[rqstp->rq_resused];
-			rqstp->rq_respages[rqstp->rq_resused] = NULL;
+	while (rqstp->rq_resused) {
+		struct page **pp = (rqstp->rq_respages +
+				    --rqstp->rq_resused);
+		if (*pp) {
+			put_page(*pp);
+			*pp = NULL;
 		}
 	}
 }
 
-static inline void svc_free_allpages(struct svc_rqst *rqstp)
-{
-        while (rqstp->rq_resused) {
-		if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
-			continue;
-		put_page(rqstp->rq_respages[rqstp->rq_resused]);
-		rqstp->rq_respages[rqstp->rq_resused] = NULL;
-	}
-}
-
 struct svc_deferred_req {
 	u32			prot;	/* protocol (UDP or TCP) */
 	struct sockaddr_in	addr;
@@ -297,6 +321,9 @@
 	struct svc_procedure *	vs_proc;	/* per-procedure info */
 	u32			vs_xdrsize;	/* xdrsize needed for this version */
 
+	unsigned int		vs_hidden : 1;	/* Don't register with portmapper.
+						 * Only used for nfsacl so far. */
+
 	/* Override dispatch function (e.g. when caching replies).
 	 * A return value of 0 means drop the request. 
 	 * vs_dispatch == NULL means use default dispatcher.
@@ -321,20 +348,21 @@
 };
 
 /*
- * This is the RPC server thread function prototype
- */
-typedef void		(*svc_thread_fn)(struct svc_rqst *);
-
-/*
  * Function prototypes.
  */
-struct svc_serv *  svc_create(struct svc_program *, unsigned int);
+struct svc_serv *  svc_create(struct svc_program *, unsigned int,
+			      void (*shutdown)(struct svc_serv*));
 int		   svc_create_thread(svc_thread_fn, struct svc_serv *);
 void		   svc_exit_thread(struct svc_rqst *);
+struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
+			void (*shutdown)(struct svc_serv*),
+			svc_thread_fn, int sig, struct module *);
+int		   svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
 void		   svc_destroy(struct svc_serv *);
-int		   svc_process(struct svc_serv *, struct svc_rqst *);
+int		   svc_process(struct svc_rqst *);
 int		   svc_register(struct svc_serv *, int, unsigned short);
 void		   svc_wake_up(struct svc_serv *);
 void		   svc_reserve(struct svc_rqst *rqstp, int space);
+struct svc_pool *  svc_pool_for_cpu(struct svc_serv *serv, int cpu);
 
 #endif /* SUNRPC_SVC_H */
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index a660165..de92619 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -126,6 +126,7 @@
 extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
 extern int auth_unix_forget_old(struct auth_domain *dom);
 extern void svcauth_unix_purge(void);
+extern void svcauth_unix_info_release(void *);
 
 static inline unsigned long hash_str(char *name, int bits)
 {
diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h
index 3a2206f..5a5db16 100644
--- a/include/linux/sunrpc/svcauth_gss.h
+++ b/include/linux/sunrpc/svcauth_gss.h
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/svcauth_gss.h
+ * linux/include/linux/sunrpc/svcauth_gss.h
  *
  * Bruce Fields <bfields@umich.edu>
  * Copyright (c) 2002 The Regents of the Unviersity of Michigan
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index b4acb3d..98b21ad 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -20,8 +20,9 @@
 	struct socket *		sk_sock;	/* berkeley socket layer */
 	struct sock *		sk_sk;		/* INET layer */
 
+	struct svc_pool *	sk_pool;	/* current pool iff queued */
 	struct svc_serv *	sk_server;	/* service for this socket */
-	unsigned int		sk_inuse;	/* use count */
+	atomic_t		sk_inuse;	/* use count */
 	unsigned long		sk_flags;
 #define	SK_BUSY		0			/* enqueued/receiving */
 #define	SK_CONN		1			/* conn pending */
@@ -31,9 +32,12 @@
 #define	SK_DEAD		6			/* socket closed */
 #define	SK_CHNGBUF	7			/* need to change snd/rcv buffer sizes */
 #define	SK_DEFERRED	8			/* request on sk_deferred */
+#define	SK_OLD		9			/* used for temp socket aging mark+sweep */
+#define	SK_DETACHED	10			/* detached from tempsocks list */
 
-	int			sk_reserved;	/* space on outq that is reserved */
+	atomic_t    	    	sk_reserved;	/* space on outq that is reserved */
 
+	spinlock_t		sk_defer_lock;	/* protects sk_deferred */
 	struct list_head	sk_deferred;	/* deferred requests that need to
 						 * be revisted */
 	struct mutex		sk_mutex;	/* to serialize sending data */
@@ -50,6 +54,9 @@
 	int			sk_reclen;	/* length of record */
 	int			sk_tcplen;	/* current read length */
 	time_t			sk_lastrecv;	/* time of last received request */
+
+	/* cache of various info for TCP sockets */
+	void			*sk_info_authunix;
 };
 
 /*
@@ -57,9 +64,14 @@
  */
 int		svc_makesock(struct svc_serv *, int, unsigned short);
 void		svc_delete_socket(struct svc_sock *);
-int		svc_recv(struct svc_serv *, struct svc_rqst *, long);
+int		svc_recv(struct svc_rqst *, long);
 int		svc_send(struct svc_rqst *);
 void		svc_drop(struct svc_rqst *);
 void		svc_sock_update_bufs(struct svc_serv *serv);
+int		svc_sock_names(char *buf, struct svc_serv *serv, char *toclose);
+int		svc_addsock(struct svc_serv *serv,
+			    int fd,
+			    char *name_return,
+			    int *proto);
 
 #endif /* SUNRPC_SVCSOCK_H */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 6cf6265..60394fb 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -15,6 +15,7 @@
 #include <linux/kref.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/msg_prot.h>
 
 extern unsigned int xprt_udp_slot_table_entries;
 extern unsigned int xprt_tcp_slot_table_entries;
@@ -24,13 +25,6 @@
 #define RPC_MAX_SLOT_TABLE	(128U)
 
 /*
- * RPC call and reply header size as number of 32bit words (verifier
- * size computed separately)
- */
-#define RPC_CALLHDRSIZE		6
-#define RPC_REPHDRSIZE		4
-
-/*
  * Parameters for choosing a free port
  */
 extern unsigned int xprt_min_resvport;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 2d1c3d5c..3efcfc7 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -599,4 +599,6 @@
 				    size_t len);
 asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
 
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+
 #endif
diff --git a/include/linux/tifm.h b/include/linux/tifm.h
new file mode 100644
index 0000000..203dd5e
--- /dev/null
+++ b/include/linux/tifm.h
@@ -0,0 +1,158 @@
+/*
+ *  tifm.h - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * 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 _TIFM_H
+#define _TIFM_H
+
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+/* Host registers (relative to pci base address): */
+enum {
+	FM_SET_INTERRUPT_ENABLE   = 0x008,
+	FM_CLEAR_INTERRUPT_ENABLE = 0x00c,
+	FM_INTERRUPT_STATUS       = 0x014 };
+
+/* Socket registers (relative to socket base address): */
+enum {
+	SOCK_CONTROL                   = 0x004,
+	SOCK_PRESENT_STATE             = 0x008,
+	SOCK_DMA_ADDRESS               = 0x00c,
+	SOCK_DMA_CONTROL               = 0x010,
+	SOCK_DMA_FIFO_INT_ENABLE_SET   = 0x014,
+	SOCK_DMA_FIFO_INT_ENABLE_CLEAR = 0x018,
+	SOCK_DMA_FIFO_STATUS           = 0x020,
+	SOCK_FIFO_CONTROL              = 0x024,
+	SOCK_FIFO_PAGE_SIZE            = 0x028,
+	SOCK_MMCSD_COMMAND             = 0x104,
+	SOCK_MMCSD_ARG_LOW             = 0x108,
+	SOCK_MMCSD_ARG_HIGH            = 0x10c,
+	SOCK_MMCSD_CONFIG              = 0x110,
+	SOCK_MMCSD_STATUS              = 0x114,
+	SOCK_MMCSD_INT_ENABLE          = 0x118,
+	SOCK_MMCSD_COMMAND_TO          = 0x11c,
+	SOCK_MMCSD_DATA_TO             = 0x120,
+	SOCK_MMCSD_DATA                = 0x124,
+	SOCK_MMCSD_BLOCK_LEN           = 0x128,
+	SOCK_MMCSD_NUM_BLOCKS          = 0x12c,
+	SOCK_MMCSD_BUFFER_CONFIG       = 0x130,
+	SOCK_MMCSD_SPI_CONFIG          = 0x134,
+	SOCK_MMCSD_SDIO_MODE_CONFIG    = 0x138,
+	SOCK_MMCSD_RESPONSE            = 0x144,
+	SOCK_MMCSD_SDIO_SR             = 0x164,
+	SOCK_MMCSD_SYSTEM_CONTROL      = 0x168,
+	SOCK_MMCSD_SYSTEM_STATUS       = 0x16c,
+	SOCK_MS_COMMAND                = 0x184,
+	SOCK_MS_DATA                   = 0x188,
+	SOCK_MS_STATUS                 = 0x18c,
+	SOCK_MS_SYSTEM                 = 0x190,
+	SOCK_FIFO_ACCESS               = 0x200 };
+
+
+#define TIFM_IRQ_ENABLE           0x80000000
+#define TIFM_IRQ_SOCKMASK         0x00000001
+#define TIFM_IRQ_CARDMASK         0x00000100
+#define TIFM_IRQ_FIFOMASK         0x00010000
+#define TIFM_IRQ_SETALL           0xffffffff
+#define TIFM_IRQ_SETALLSOCK       0x0000000f
+
+#define TIFM_CTRL_LED             0x00000040
+#define TIFM_CTRL_FAST_CLK        0x00000100
+
+#define TIFM_SOCK_STATE_OCCUPIED  0x00000008
+#define TIFM_SOCK_STATE_POWERED   0x00000080
+
+#define TIFM_FIFO_ENABLE          0x00000001 /* Meaning of this constant is unverified */
+#define TIFM_FIFO_INT_SETALL      0x0000ffff
+#define TIFM_FIFO_INTMASK         0x00000005 /* Meaning of this constant is unverified */
+
+#define TIFM_DMA_RESET            0x00000002 /* Meaning of this constant is unverified */
+#define TIFM_DMA_TX               0x00008000 /* Meaning of this constant is unverified */
+#define TIFM_DMA_EN               0x00000001 /* Meaning of this constant is unverified */
+
+typedef enum {FM_NULL = 0, FM_XD = 0x01, FM_MS = 0x02, FM_SD = 0x03} tifm_media_id;
+
+struct tifm_driver;
+struct tifm_dev {
+	char __iomem            *addr;
+	spinlock_t              lock;
+	tifm_media_id           media_id;
+	char                    wq_name[KOBJ_NAME_LEN];
+	struct workqueue_struct *wq;
+
+	unsigned int            (*signal_irq)(struct tifm_dev *sock,
+					      unsigned int sock_irq_status);
+
+	struct tifm_driver      *drv;
+	struct device           dev;
+};
+
+struct tifm_driver {
+	tifm_media_id        *id_table;
+	int                  (*probe)(struct tifm_dev *dev);
+	void                 (*remove)(struct tifm_dev *dev);
+
+	struct device_driver driver;
+};
+
+struct tifm_adapter {
+	char __iomem            *addr;
+	unsigned int            irq_status;
+	unsigned int            insert_mask;
+	unsigned int            remove_mask;
+	spinlock_t              lock;
+	unsigned int            id;
+	unsigned int            max_sockets;
+	char                    wq_name[KOBJ_NAME_LEN];
+	unsigned int            inhibit_new_cards;
+	struct workqueue_struct *wq;
+	struct work_struct      media_inserter;
+	struct work_struct      media_remover;
+	struct tifm_dev         **sockets;
+	struct class_device     cdev;
+	struct device           *dev;
+
+	void                    (*eject)(struct tifm_adapter *fm, struct tifm_dev *sock);
+};
+
+struct tifm_adapter *tifm_alloc_adapter(void);
+void tifm_free_device(struct device *dev);
+void tifm_free_adapter(struct tifm_adapter *fm);
+int tifm_add_adapter(struct tifm_adapter *fm);
+void tifm_remove_adapter(struct tifm_adapter *fm);
+struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id);
+int tifm_register_driver(struct tifm_driver *drv);
+void tifm_unregister_driver(struct tifm_driver *drv);
+void tifm_eject(struct tifm_dev *sock);
+int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+		int direction);
+void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+		   int direction);
+
+
+static inline void *tifm_get_drvdata(struct tifm_dev *dev)
+{
+        return dev_get_drvdata(&dev->dev);
+}
+
+static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data)
+{
+	dev_set_drvdata(&dev->dev, data);
+}
+
+struct tifm_device_id {
+	tifm_media_id media_id;
+};
+
+#endif
diff --git a/include/linux/topology.h b/include/linux/topology.h
index ec1eca8..da508d1 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -89,6 +89,7 @@
 #define SD_SIBLING_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 1,			\
 	.max_interval		= 2,			\
@@ -114,11 +115,13 @@
 #endif
 #endif /* CONFIG_SCHED_SMT */
 
-/* Common values for CPUs */
-#ifndef SD_CPU_INIT
-#define SD_CPU_INIT (struct sched_domain) {		\
+#ifdef CONFIG_SCHED_MC
+/* Common values for MC siblings. for now mostly derived from SD_CPU_INIT */
+#ifndef SD_MC_INIT
+#define SD_MC_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 1,			\
 	.max_interval		= 4,			\
@@ -135,7 +138,38 @@
 				| SD_BALANCE_NEWIDLE	\
 				| SD_BALANCE_EXEC	\
 				| SD_WAKE_AFFINE	\
-				| BALANCE_FOR_POWER,	\
+				| SD_SHARE_PKG_RESOURCES\
+				| BALANCE_FOR_MC_POWER,	\
+	.last_balance		= jiffies,		\
+	.balance_interval	= 1,			\
+	.nr_balance_failed	= 0,			\
+}
+#endif
+#endif /* CONFIG_SCHED_MC */
+
+/* Common values for CPUs */
+#ifndef SD_CPU_INIT
+#define SD_CPU_INIT (struct sched_domain) {		\
+	.span			= CPU_MASK_NONE,	\
+	.parent			= NULL,			\
+	.child			= NULL,			\
+	.groups			= NULL,			\
+	.min_interval		= 1,			\
+	.max_interval		= 4,			\
+	.busy_factor		= 64,			\
+	.imbalance_pct		= 125,			\
+	.cache_nice_tries	= 1,			\
+	.per_cpu_gain		= 100,			\
+	.busy_idx		= 2,			\
+	.idle_idx		= 1,			\
+	.newidle_idx		= 2,			\
+	.wake_idx		= 1,			\
+	.forkexec_idx		= 1,			\
+	.flags			= SD_LOAD_BALANCE	\
+				| SD_BALANCE_NEWIDLE	\
+				| SD_BALANCE_EXEC	\
+				| SD_WAKE_AFFINE	\
+				| BALANCE_FOR_PKG_POWER,\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
 	.nr_balance_failed	= 0,			\
@@ -146,6 +180,7 @@
 #define SD_ALLNODES_INIT (struct sched_domain) {	\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 64,			\
 	.max_interval		= 64*num_online_cpus(),	\
@@ -165,15 +200,6 @@
 	.nr_balance_failed	= 0,			\
 }
 
-#ifdef CONFIG_SCHED_MC
-#ifndef SD_MC_INIT
-/* for now its same as SD_CPU_INIT.
- * TBD: Tune Domain parameters!
- */
-#define SD_MC_INIT   SD_CPU_INIT
-#endif
-#endif
-
 #ifdef CONFIG_NUMA
 #ifndef SD_NODE_INIT
 #error Please define an appropriate SD_NODE_INIT in include/asm/topology.h!!!
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 58c961c..5c8473b 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -219,7 +219,8 @@
 
 struct tty_driver *alloc_tty_driver(int lines);
 void put_tty_driver(struct tty_driver *driver);
-void tty_set_operations(struct tty_driver *driver, struct tty_operations *op);
+void tty_set_operations(struct tty_driver *driver,
+			const struct tty_operations *op);
 
 /* tty driver magic number */
 #define TTY_DRIVER_MAGIC		0x5402
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index 7168302..1fd61ee 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -22,12 +22,18 @@
  * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
  *
  * Changes/Revisions:
+ *	0.3	24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
+ *		- update ff support for the changes in kernel interface
+ *		- add UINPUT_VERSION
  *	0.2	16/10/2004 (Micah Dowty <micah@navi.cx>)
  *		- added force feedback support
  *             - added UI_SET_PHYS
  *	0.1	20/06/2002
  *		- first public version
  */
+
+#define UINPUT_VERSION		3
+
 #ifdef __KERNEL__
 #define UINPUT_MINOR		223
 #define UINPUT_NAME		"uinput"
@@ -45,7 +51,10 @@
 
 	union {
 		int		effect_id;
-		struct ff_effect* effect;
+		struct {
+			struct ff_effect *effect;
+			struct ff_effect *old;
+		} upload;
 	} u;
 };
 
@@ -58,6 +67,7 @@
 	unsigned char		head;
 	unsigned char		tail;
 	struct input_event	buff[UINPUT_BUFFER_SIZE];
+	int			ff_effects_max;
 
 	struct uinput_request	*requests[UINPUT_NUM_REQUESTS];
 	wait_queue_head_t	requests_waitq;
@@ -69,6 +79,7 @@
 	int			request_id;
 	int			retval;
 	struct ff_effect	effect;
+	struct ff_effect	old;
 };
 
 struct uinput_ff_erase {
@@ -98,33 +109,33 @@
 #define UI_BEGIN_FF_ERASE	_IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
 #define UI_END_FF_ERASE		_IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
 
-/* To write a force-feedback-capable driver, the upload_effect
+/*
+ * To write a force-feedback-capable driver, the upload_effect
  * and erase_effect callbacks in input_dev must be implemented.
  * The uinput driver will generate a fake input event when one of
  * these callbacks are invoked. The userspace code then uses
  * ioctls to retrieve additional parameters and send the return code.
  * The callback blocks until this return code is sent.
  *
- * The described callback mechanism is only used if EV_FF is set.
- * Otherwise, default implementations of upload_effect and erase_effect
- * are used.
+ * The described callback mechanism is only used if ff_effects_max
+ * is set.
  *
  * To implement upload_effect():
- *   1. Wait for an event with type==EV_UINPUT and code==UI_FF_UPLOAD.
+ *   1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
  *      A request ID will be given in 'value'.
  *   2. Allocate a uinput_ff_upload struct, fill in request_id with
  *      the 'value' from the EV_UINPUT event.
  *   3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
  *      uinput_ff_upload struct. It will be filled in with the
- *      ff_effect passed to upload_effect().
- *   4. Perform the effect upload, and place the modified ff_effect
- *      and a return code back into the uinput_ff_upload struct.
+ *      ff_effects passed to upload_effect().
+ *   4. Perform the effect upload, and place a return code back into
+        the uinput_ff_upload struct.
  *   5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
  *      uinput_ff_upload_effect struct. This will complete execution
  *      of our upload_effect() handler.
  *
  * To implement erase_effect():
- *   1. Wait for an event with type==EV_UINPUT and code==UI_FF_ERASE.
+ *   1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
  *      A request ID will be given in 'value'.
  *   2. Allocate a uinput_ff_erase struct, fill in request_id with
  *      the 'value' from the EV_UINPUT event.
@@ -133,13 +144,13 @@
  *      effect ID passed to erase_effect().
  *   4. Perform the effect erasure, and place a return code back
  *      into the uinput_ff_erase struct.
- *      and a return code back into the uinput_ff_erase struct.
  *   5. Issue a UI_END_FF_ERASE ioctl, also giving it the
  *      uinput_ff_erase_effect struct. This will complete execution
  *      of our erase_effect() handler.
  */
 
-/* This is the new event type, used only by uinput.
+/*
+ * This is the new event type, used only by uinput.
  * 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
  * is the unique request ID. This number was picked
  * arbitrarily, above EV_MAX (since the input system
diff --git a/include/linux/unistd.h b/include/linux/unistd.h
index c18c60f..aa8d5b5 100644
--- a/include/linux/unistd.h
+++ b/include/linux/unistd.h
@@ -1,12 +1,8 @@
 #ifndef _LINUX_UNISTD_H_
 #define _LINUX_UNISTD_H_
 
-#ifdef __KERNEL__
-extern int errno;
-#endif
-
 /*
- * Include machine specific syscallX macros
+ * Include machine specific syscall numbers
  */
 #include <asm/unistd.h>
 
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index 13e1da0..a4555fe 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -30,7 +30,65 @@
 	char domainname[65];
 };
 
-extern struct new_utsname system_utsname;
+#ifdef __KERNEL__
+
+#include <linux/sched.h>
+#include <linux/kref.h>
+#include <linux/nsproxy.h>
+#include <asm/atomic.h>
+
+struct uts_namespace {
+	struct kref kref;
+	struct new_utsname name;
+};
+extern struct uts_namespace init_uts_ns;
+
+static inline void get_uts_ns(struct uts_namespace *ns)
+{
+	kref_get(&ns->kref);
+}
+
+#ifdef CONFIG_UTS_NS
+extern int unshare_utsname(unsigned long unshare_flags,
+				struct uts_namespace **new_uts);
+extern int copy_utsname(int flags, struct task_struct *tsk);
+extern void free_uts_ns(struct kref *kref);
+
+static inline void put_uts_ns(struct uts_namespace *ns)
+{
+	kref_put(&ns->kref, free_uts_ns);
+}
+#else
+static inline int unshare_utsname(unsigned long unshare_flags,
+			struct uts_namespace **new_uts)
+{
+	if (unshare_flags & CLONE_NEWUTS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static inline int copy_utsname(int flags, struct task_struct *tsk)
+{
+	return 0;
+}
+static inline void put_uts_ns(struct uts_namespace *ns)
+{
+}
+#endif
+
+static inline struct new_utsname *utsname(void)
+{
+	return &current->nsproxy->uts_ns->name;
+}
+
+static inline struct new_utsname *init_utsname(void)
+{
+	return &init_uts_ns.name;
+}
 
 extern struct rw_semaphore uts_sem;
-#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_UTSNAME_H */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 44c59da..c5fdf62 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -276,6 +276,82 @@
 
 #define V4L2_FMT_FLAG_COMPRESSED 0x0001
 
+#if 1
+	/* Experimental Frame Size and frame rate enumeration */
+/*
+ *	F R A M E   S I Z E   E N U M E R A T I O N
+ */
+enum v4l2_frmsizetypes
+{
+	V4L2_FRMSIZE_TYPE_DISCRETE	= 1,
+	V4L2_FRMSIZE_TYPE_CONTINUOUS	= 2,
+	V4L2_FRMSIZE_TYPE_STEPWISE	= 3,
+};
+
+struct v4l2_frmsize_discrete
+{
+	__u32			width;		/* Frame width [pixel] */
+	__u32			height;		/* Frame height [pixel] */
+};
+
+struct v4l2_frmsize_stepwise
+{
+	__u32			min_width;	/* Minimum frame width [pixel] */
+	__u32			max_width;	/* Maximum frame width [pixel] */
+	__u32			step_width;	/* Frame width step size [pixel] */
+	__u32			min_height;	/* Minimum frame height [pixel] */
+	__u32			max_height;	/* Maximum frame height [pixel] */
+	__u32			step_height;	/* Frame height step size [pixel] */
+};
+
+struct v4l2_frmsizeenum
+{
+	__u32			index;		/* Frame size number */
+	__u32			pixel_format;	/* Pixel format */
+	__u32			type;		/* Frame size type the device supports. */
+
+	union {					/* Frame size */
+		struct v4l2_frmsize_discrete	discrete;
+		struct v4l2_frmsize_stepwise	stepwise;
+	};
+
+	__u32   reserved[2];			/* Reserved space for future use */
+};
+
+/*
+ *	F R A M E   R A T E   E N U M E R A T I O N
+ */
+enum v4l2_frmivaltypes
+{
+	V4L2_FRMIVAL_TYPE_DISCRETE	= 1,
+	V4L2_FRMIVAL_TYPE_CONTINUOUS	= 2,
+	V4L2_FRMIVAL_TYPE_STEPWISE	= 3,
+};
+
+struct v4l2_frmival_stepwise
+{
+	struct v4l2_fract	min;		/* Minimum frame interval [s] */
+	struct v4l2_fract	max;		/* Maximum frame interval [s] */
+	struct v4l2_fract	step;		/* Frame interval step size [s] */
+};
+
+struct v4l2_frmivalenum
+{
+	__u32			index;		/* Frame format index */
+	__u32			pixel_format;	/* Pixel format */
+	__u32			width;		/* Frame width */
+	__u32			height;		/* Frame height */
+	__u32			type;		/* Frame interval type the device supports. */
+
+	union {					/* Frame interval */
+		struct v4l2_fract		discrete;
+		struct v4l2_frmival_stepwise	stepwise;
+	};
+
+	__u32	reserved[2];			/* Reserved space for future use */
+};
+#endif
+
 /*
  *	T I M E C O D E
  */
@@ -1249,6 +1325,10 @@
 #define VIDIOC_G_EXT_CTRLS	_IOWR ('V', 71, struct v4l2_ext_controls)
 #define VIDIOC_S_EXT_CTRLS	_IOWR ('V', 72, struct v4l2_ext_controls)
 #define VIDIOC_TRY_EXT_CTRLS	_IOWR ('V', 73, struct v4l2_ext_controls)
+#if 1
+#define VIDIOC_ENUM_FRAMESIZES	_IOWR ('V', 74, struct v4l2_frmsizeenum)
+#define VIDIOC_ENUM_FRAMEINTERVALS	_IOWR ('V', 75, struct v4l2_frmivalenum)
+#endif
 
 #ifdef __OLD_VIDIOC_
 /* for compatibility, will go away some day */
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 1009d3f..37a1a41 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -84,4 +84,11 @@
 extern char con_buf[CON_BUF_SIZE];
 extern struct semaphore con_buf_sem;
 
+struct vt_spawn_console {
+	spinlock_t lock;
+	struct pid *pid;
+	int sig;
+};
+extern struct vt_spawn_console vt_spawn_con;
+
 #endif /* _VT_KERN_H */
diff --git a/include/linux/wavefront.h b/include/linux/wavefront.h
deleted file mode 100644
index 51ab3c9..0000000
--- a/include/linux/wavefront.h
+++ /dev/null
@@ -1,675 +0,0 @@
-#ifndef __wavefront_h__
-#define __wavefront_h__
-
-/* WaveFront header file.
- *   
- * Copyright (C) by Paul Barton-Davis 1998
- *
- * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.  
- */
-
-#if (!defined(__GNUC__) && !defined(__GNUG__))
-
-     You will not be able to compile this file correctly without gcc, because
-     it is necessary to pack the "wavefront_alias" structure to a size
-     of 22 bytes, corresponding to 16-bit alignment (as would have been
-     the case on the original platform, MS-DOS). If this is not done,
-     then WavePatch-format files cannot be read/written correctly.
-     The method used to do this here ("__attribute__((packed)") is
-     completely compiler dependent.
-     
-     All other wavefront_* types end up aligned to 32 bit values and
-     still have the same (correct) size.
-
-#else
-
-     /* However, note that as of G++ 2.7.3.2, g++ was unable to
-	correctly parse *type* __attribute__ tags. It will do the
-	right thing if we use the "packed" attribute on each struct
-	member, which has the same semantics anyway. 
-     */
-
-#endif /* __GNUC__ */
-
-/***************************** WARNING ********************************
-  PLEASE DO NOT MODIFY THIS FILE IN ANY WAY THAT AFFECTS ITS ABILITY TO 
-  BE USED WITH EITHER C *OR* C++.
- **********************************************************************/
-
-#ifndef NUM_MIDIKEYS 
-#define NUM_MIDIKEYS 128
-#endif  /* NUM_MIDIKEYS */
-
-#ifndef NUM_MIDICHANNELS
-#define NUM_MIDICHANNELS 16
-#endif  /* NUM_MIDICHANNELS */
-
-/* These are very useful/important. the original wavefront interface
-   was developed on a 16 bit system, where sizeof(int) = 2
-   bytes. Defining things like this makes the code much more portable, and
-   easier to understand without having to toggle back and forth
-   between a 16-bit view of the world and a 32-bit one. 
- */   
-
-typedef short INT16;
-typedef unsigned short UINT16;
-typedef int INT32;
-typedef unsigned int UINT32;
-typedef char CHAR8;
-typedef unsigned char UCHAR8;
-
-/* Pseudo-commands not part of the WaveFront command set.
-   These are used for various driver controls and direct
-   hardware control.
- */
-
-#define WFC_DEBUG_DRIVER                0
-#define WFC_FX_IOCTL                    1
-#define WFC_PATCH_STATUS                2
-#define WFC_PROGRAM_STATUS              3
-#define WFC_SAMPLE_STATUS               4
-#define WFC_DISABLE_INTERRUPTS          5
-#define WFC_ENABLE_INTERRUPTS           6
-#define WFC_INTERRUPT_STATUS            7
-#define WFC_ROMSAMPLES_RDONLY           8
-#define WFC_IDENTIFY_SLOT_TYPE          9
-
-/* Wavefront synth commands
- */
-
-#define WFC_DOWNLOAD_SAMPLE		0x80
-#define WFC_DOWNLOAD_BLOCK		0x81
-#define WFC_DOWNLOAD_MULTISAMPLE	0x82
-#define WFC_DOWNLOAD_SAMPLE_ALIAS	0x83
-#define WFC_DELETE_SAMPLE		0x84
-#define WFC_REPORT_FREE_MEMORY		0x85
-#define WFC_DOWNLOAD_PATCH		0x86
-#define WFC_DOWNLOAD_PROGRAM		0x87
-#define WFC_SET_SYNTHVOL		0x89
-#define WFC_SET_NVOICES			0x8B
-#define WFC_DOWNLOAD_DRUM		0x90
-#define WFC_GET_SYNTHVOL		0x92
-#define WFC_GET_NVOICES			0x94
-#define WFC_DISABLE_CHANNEL		0x9A
-#define WFC_ENABLE_CHANNEL		0x9B
-#define WFC_MISYNTH_OFF			0x9D
-#define WFC_MISYNTH_ON			0x9E
-#define WFC_FIRMWARE_VERSION		0x9F
-#define WFC_GET_NSAMPLES		0xA0
-#define WFC_DISABLE_DRUM_PROGRAM	0xA2
-#define WFC_UPLOAD_PATCH		0xA3
-#define WFC_UPLOAD_PROGRAM		0xA4
-#define WFC_SET_TUNING			0xA6
-#define WFC_GET_TUNING			0xA7
-#define WFC_VMIDI_ON			0xA8
-#define WFC_VMIDI_OFF			0xA9
-#define WFC_MIDI_STATUS			0xAA
-#define WFC_GET_CHANNEL_STATUS		0xAB
-#define WFC_DOWNLOAD_SAMPLE_HEADER	0xAC
-#define WFC_UPLOAD_SAMPLE_HEADER	0xAD
-#define WFC_UPLOAD_MULTISAMPLE		0xAE
-#define WFC_UPLOAD_SAMPLE_ALIAS		0xAF
-#define WFC_IDENTIFY_SAMPLE_TYPE	0xB0
-#define WFC_DOWNLOAD_EDRUM_PROGRAM	0xB1
-#define WFC_UPLOAD_EDRUM_PROGRAM	0xB2
-#define WFC_SET_EDRUM_CHANNEL		0xB3
-#define WFC_INSTOUT_LEVELS		0xB4
-#define WFC_PEAKOUT_LEVELS		0xB5
-#define WFC_REPORT_CHANNEL_PROGRAMS	0xB6
-#define WFC_HARDWARE_VERSION		0xCF
-#define WFC_UPLOAD_SAMPLE_PARAMS	0xD7
-#define WFC_DOWNLOAD_OS			0xF1
-#define WFC_NOOP                        0xFF
-
-#define WF_MAX_SAMPLE   512
-#define WF_MAX_PATCH    256
-#define WF_MAX_PROGRAM  128
-
-#define WF_SECTION_MAX  44   /* longest OS section length */
-
-/* # of bytes we send to the board when sending it various kinds of
-   substantive data, such as samples, patches and programs.
-*/
-
-#define WF_PROGRAM_BYTES 32
-#define WF_PATCH_BYTES 132
-#define WF_SAMPLE_BYTES 27
-#define WF_SAMPLE_HDR_BYTES 25
-#define WF_ALIAS_BYTES 25
-#define WF_DRUM_BYTES 9
-#define WF_MSAMPLE_BYTES 259 /* (MIDI_KEYS * 2) + 3 */
-
-#define WF_ACK     0x80
-#define WF_DMA_ACK 0x81
-
-/* OR-values for MIDI status bits */
-
-#define WF_MIDI_VIRTUAL_ENABLED 0x1
-#define WF_MIDI_VIRTUAL_IS_EXTERNAL 0x2
-#define WF_MIDI_IN_TO_SYNTH_DISABLED 0x4
-
-/* slot indexes for struct address_info: makes code a little more mnemonic */
-
-#define WF_SYNTH_SLOT         0
-#define WF_INTERNAL_MIDI_SLOT 1
-#define WF_EXTERNAL_MIDI_SLOT 2
-
-/* Magic MIDI bytes used to switch I/O streams on the ICS2115 MPU401
-   emulation. Note these NEVER show up in output from the device and
-   should NEVER be used in input unless Virtual MIDI mode has been 
-   disabled. If they do show up as input, the results are unpredictable.
-*/
-
-#define WF_EXTERNAL_SWITCH  0xFD
-#define WF_INTERNAL_SWITCH  0xF9
-
-/* Debugging flags */
-
-#define WF_DEBUG_CMD 0x1
-#define WF_DEBUG_DATA 0x2
-#define WF_DEBUG_LOAD_PATCH 0x4
-#define WF_DEBUG_IO 0x8
-
-/* WavePatch file format stuff */
-
-#define WF_WAVEPATCH_VERSION     120;  /*  Current version number (1.2)  */
-#define WF_MAX_COMMENT           64    /*  Comment length */
-#define WF_NUM_LAYERS            4
-#define WF_NAME_LENGTH           32
-#define WF_SOURCE_LENGTH         260
-
-#define BankFileID     "Bank"
-#define DrumkitFileID  "DrumKit"
-#define ProgramFileID  "Program"
-
-struct wf_envelope
-{
-    UCHAR8 attack_time:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 decay1_time:7;
-    UCHAR8 Unused2:1;
-
-    UCHAR8 decay2_time:7;
-    UCHAR8 Unused3:1;
-
-    UCHAR8 sustain_time:7;
-    UCHAR8 Unused4:1;
-
-    UCHAR8 release_time:7;
-    UCHAR8 Unused5:1;
-
-    UCHAR8 release2_time:7;
-    UCHAR8 Unused6:1;
-
-    CHAR8 attack_level;
-    CHAR8 decay1_level;
-    CHAR8 decay2_level;
-    CHAR8 sustain_level;
-    CHAR8 release_level;
-
-    UCHAR8 attack_velocity:7;
-    UCHAR8 Unused7:1;
-
-    UCHAR8 volume_velocity:7;
-    UCHAR8 Unused8:1;
-
-    UCHAR8 keyboard_scaling:7;
-    UCHAR8 Unused9:1;
-};
-typedef struct wf_envelope wavefront_envelope;
-
-struct wf_lfo
-{
-    UCHAR8 sample_number;
-
-    UCHAR8 frequency:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 am_src:4;
-    UCHAR8 fm_src:4;
-
-    CHAR8 fm_amount;
-    CHAR8 am_amount;
-    CHAR8 start_level;
-    CHAR8 end_level;
-
-    UCHAR8 ramp_delay:7;
-    UCHAR8 wave_restart:1; /* for LFO2 only */
-
-    UCHAR8 ramp_time:7;
-    UCHAR8 Unused2:1;
-};
-typedef struct wf_lfo wavefront_lfo;
-
-struct wf_patch
-{
-    INT16  frequency_bias;         /*  ** THIS IS IN MOTOROLA FORMAT!! ** */
-
-    UCHAR8 amplitude_bias:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 portamento:7;
-    UCHAR8 Unused2:1;
-
-    UCHAR8 sample_number;
-
-    UCHAR8 pitch_bend:4;
-    UCHAR8 sample_msb:1;
-    UCHAR8 Unused3:3;
-
-    UCHAR8 mono:1;
-    UCHAR8 retrigger:1;
-    UCHAR8 nohold:1;
-    UCHAR8 restart:1;
-    UCHAR8 filterconfig:2; /* SDK says "not used" */
-    UCHAR8 reuse:1;
-    UCHAR8 reset_lfo:1;    
-
-    UCHAR8 fm_src2:4;
-    UCHAR8 fm_src1:4;   
-
-    CHAR8 fm_amount1;
-    CHAR8 fm_amount2;
-
-    UCHAR8 am_src:4;
-    UCHAR8 Unused4:4;
-
-    CHAR8 am_amount;
-
-    UCHAR8 fc1_mode:4;
-    UCHAR8 fc2_mode:4;
-
-    CHAR8 fc1_mod_amount;
-    CHAR8 fc1_keyboard_scaling;
-    CHAR8 fc1_bias;
-    CHAR8 fc2_mod_amount;
-    CHAR8 fc2_keyboard_scaling;
-    CHAR8 fc2_bias;
-
-    UCHAR8 randomizer:7;
-    UCHAR8 Unused5:1;
-
-    struct wf_envelope envelope1;
-    struct wf_envelope envelope2;
-    struct wf_lfo lfo1;
-    struct wf_lfo lfo2;
-};
-typedef struct wf_patch wavefront_patch;
-
-struct wf_layer
-{
-    UCHAR8 patch_number;
-
-    UCHAR8 mix_level:7;
-    UCHAR8 mute:1;
-
-    UCHAR8 split_point:7;
-    UCHAR8 play_below:1;
-
-    UCHAR8 pan_mod_src:2;
-    UCHAR8 pan_or_mod:1;
-    UCHAR8 pan:4;
-    UCHAR8 split_type:1;
-};
-typedef struct wf_layer wavefront_layer;
-
-struct wf_program
-{
-    struct wf_layer layer[WF_NUM_LAYERS];
-};
-typedef struct wf_program wavefront_program;
-
-struct wf_sample_offset
-{
-    INT32 Fraction:4;
-    INT32 Integer:20;
-    INT32 Unused:8;
-};
-typedef struct wf_sample_offset wavefront_sample_offset;          
-     
-/* Sample slot types */
-
-#define WF_ST_SAMPLE      0
-#define WF_ST_MULTISAMPLE 1
-#define WF_ST_ALIAS       2
-#define WF_ST_EMPTY       3
-
-/* pseudo's */
-
-#define WF_ST_DRUM        4
-#define WF_ST_PROGRAM     5
-#define WF_ST_PATCH       6
-#define WF_ST_SAMPLEHDR   7
-
-#define WF_ST_MASK        0xf
-
-/* Flags for slot status. These occupy the upper bits of the same byte
-   as a sample type.
-*/
-
-#define WF_SLOT_USED      0x80   /* XXX don't rely on this being accurate */
-#define WF_SLOT_FILLED    0x40
-#define WF_SLOT_ROM       0x20
-
-#define WF_SLOT_MASK      0xf0
-
-/* channel constants */
-
-#define WF_CH_MONO  0
-#define WF_CH_LEFT  1
-#define WF_CH_RIGHT 2
-
-/* Sample formats */
-
-#define LINEAR_16BIT 0
-#define WHITE_NOISE  1
-#define LINEAR_8BIT  2
-#define MULAW_8BIT   3
-
-#define WF_SAMPLE_IS_8BIT(smpl) ((smpl)->SampleResolution&2)
-
-
-/* 
-
-  Because most/all of the sample data we pass in via pointers has
-  never been copied (just mmap-ed into user space straight from the
-  disk), it would be nice to allow handling of multi-channel sample
-  data without forcing user-level extraction of the relevant bytes.
-  
-  So, we need a way of specifying which channel to use (the WaveFront
-  only handles mono samples in a given slot), and the only way to do
-  this without using some struct other than wavefront_sample as the
-  interface is the awful hack of using the unused bits in a
-  wavefront_sample:
-  
-  Val      Meaning
-  ---      -------
-  0        no channel selection (use channel 1, sample is MONO)
-  1        use first channel, and skip one
-  2        use second channel, and skip one
-  3        use third channel, and skip two
-  4        use fourth channel, skip three
-  5        use fifth channel, skip four
-  6        use six channel, skip five
-
-
-  This can handle up to 4 channels, and anyone downloading >4 channels
-  of sample data just to select one of them needs to find some tools
-  like sox ...
-
-  NOTE: values 0, 1 and 2 correspond to WF_CH_* above. This is 
-  important.
-
-*/
-
-#define WF_SET_CHANNEL(samp,chn) \
- (samp)->Unused1 = chn & 0x1; \
- (samp)->Unused2 = chn & 0x2; \
- (samp)->Unused3 = chn & 0x4 
-  
-#define WF_GET_CHANNEL(samp) \
-  (((samp)->Unused3 << 2)|((samp)->Unused2<<1)|(samp)->Unused1)
-  
-typedef struct wf_sample {
-    struct wf_sample_offset sampleStartOffset;
-    struct wf_sample_offset loopStartOffset;
-    struct wf_sample_offset loopEndOffset;
-    struct wf_sample_offset sampleEndOffset;
-    INT16 FrequencyBias;
-    UCHAR8 SampleResolution:2;  /* sample_format */
-    UCHAR8 Unused1:1;
-    UCHAR8 Loop:1;
-    UCHAR8 Bidirectional:1;
-    UCHAR8 Unused2:1;
-    UCHAR8 Reverse:1;
-    UCHAR8 Unused3:1;
-} wavefront_sample;
-
-typedef struct wf_multisample {
-    INT16 NumberOfSamples;   /* log2 of the number of samples */
-    INT16 SampleNumber[NUM_MIDIKEYS];
-} wavefront_multisample;
-
-typedef struct wf_alias {
-    INT16 OriginalSample;
-
-    struct wf_sample_offset sampleStartOffset;
-    struct wf_sample_offset loopStartOffset;
-    struct wf_sample_offset sampleEndOffset;
-    struct wf_sample_offset loopEndOffset;
-
-    INT16  FrequencyBias;
-
-    UCHAR8 SampleResolution:2;
-    UCHAR8 Unused1:1;
-    UCHAR8 Loop:1;
-    UCHAR8 Bidirectional:1;
-    UCHAR8 Unused2:1;
-    UCHAR8 Reverse:1;
-    UCHAR8 Unused3:1;
-    
-    /* This structure is meant to be padded only to 16 bits on their
-       original. Of course, whoever wrote their documentation didn't
-       realize that sizeof(struct) can be >=
-       sum(sizeof(struct-fields)) and so thought that giving a C level
-       description of the structs used in WavePatch files was
-       sufficient. I suppose it was, as long as you remember the 
-       standard 16->32 bit issues.
-    */
-
-    UCHAR8 sixteen_bit_padding;
-} __attribute__((packed)) wavefront_alias;
-
-typedef struct wf_drum {
-    UCHAR8 PatchNumber;
-    UCHAR8 MixLevel:7;
-    UCHAR8 Unmute:1;
-    UCHAR8 Group:4;
-    UCHAR8 Unused1:4;
-    UCHAR8 PanModSource:2;
-    UCHAR8 PanModulated:1;
-    UCHAR8 PanAmount:4;
-    UCHAR8 Unused2:1;
-} wavefront_drum;
-
-typedef struct wf_drumkit {
-    struct wf_drum drum[NUM_MIDIKEYS];
-} wavefront_drumkit;
-
-typedef struct wf_channel_programs {
-    UCHAR8 Program[NUM_MIDICHANNELS];
-} wavefront_channel_programs;
-
-/* How to get MIDI channel status from the data returned by
-   a WFC_GET_CHANNEL_STATUS command (a struct wf_channel_programs)
-*/
-
-#define WF_CHANNEL_STATUS(ch,wcp) (wcp)[(ch/7)] & (1<<((ch)%7))
-
-typedef union wf_any {
-    wavefront_sample s;
-    wavefront_multisample ms;
-    wavefront_alias a;
-    wavefront_program pr;
-    wavefront_patch p;
-    wavefront_drum d;
-} wavefront_any;
-
-/* Hannu Solvainen hoped that his "patch_info" struct in soundcard.h
-   might work for other wave-table based patch loading situations.
-   Alas, his fears were correct. The WaveFront doesn't even come with
-   just "patches", but several different kind of structures that
-   control the sound generation process.
- */
-
-typedef struct wf_patch_info {
-    
-    /* the first two fields are used by the OSS "patch loading" interface
-       only, and are unused by the current user-level library.
-    */
-
-    INT16   key;               /* Use WAVEFRONT_PATCH here */
-    UINT16  devno;             /* fill in when sending */
-    UCHAR8  subkey;            /* WF_ST_{SAMPLE,ALIAS,etc.} */
-
-#define WAVEFRONT_FIND_FREE_SAMPLE_SLOT 999
-
-    UINT16  number;            /* patch/sample/prog number */
-
-    UINT32  size;              /* size of any data included in 
-				  one of the fields in `hdrptr', or
-				  as `dataptr'.
-
-				  NOTE: for actual samples, this is
-				  the size of the *SELECTED CHANNEL*
-				  even if more data is actually available.
-				  
-				  So, a stereo sample (2 channels) of
-				  6000 bytes total has `size' = 3000.
-
-				  See the macros and comments for
-				  WF_{GET,SET}_CHANNEL above.
-
-			       */
-    wavefront_any __user *hdrptr;      /* user-space ptr to hdr bytes */
-    UINT16 __user *dataptr;            /* actual sample data */
-
-    wavefront_any hdr;          /* kernel-space copy of hdr bytes */         
-} wavefront_patch_info;
-
-/* The maximum number of bytes we will ever move to or from user space
-   in response to a WFC_* command.  This obviously doesn't cover
-   actual sample data.
-*/
-
-#define WF_MAX_READ sizeof(wavefront_multisample)
-#define WF_MAX_WRITE sizeof(wavefront_multisample)
-
-/*
-   This allows us to execute any WF command except the download/upload
-   ones, which are handled differently due to copyin/copyout issues as
-   well as data-nybbling to/from the card.
- */
-
-typedef struct wavefront_control {
-    int cmd;                           /* WFC_* */
-    char status;                       /* return status to user-space */
-    unsigned char rbuf[WF_MAX_READ];   /* bytes read from card */
-    unsigned char wbuf[WF_MAX_WRITE];  /* bytes written to card */
-} wavefront_control;
-
-#define WFCTL_WFCMD    0x1
-#define WFCTL_LOAD_SPP 0x2
-
-/* Modulator table */
-
-#define WF_MOD_LFO1      0
-#define WF_MOD_LFO2      1
-#define WF_MOD_ENV1      2
-#define WF_MOD_ENV2      3
-#define WF_MOD_KEYBOARD  4
-#define WF_MOD_LOGKEY    5
-#define WF_MOD_VELOCITY  6
-#define WF_MOD_LOGVEL    7
-#define WF_MOD_RANDOM    8
-#define WF_MOD_PRESSURE  9
-#define WF_MOD_MOD_WHEEL 10
-#define WF_MOD_1         WF_MOD_MOD_WHEEL 
-#define WF_MOD_BREATH    11
-#define WF_MOD_2         WF_MOD_BREATH
-#define WF_MOD_FOOT      12
-#define WF_MOD_4         WF_MOD_FOOT
-#define WF_MOD_VOLUME    13
-#define WF_MOD_7         WF_MOD_VOLUME
-#define WF_MOD_PAN       14
-#define WF_MOD_10        WF_MOD_PAN
-#define WF_MOD_EXPR      15
-#define WF_MOD_11        WF_MOD_EXPR
-
-/* FX-related material */
-
-typedef struct wf_fx_info {
-    int request;             /* see list below */
-    int data[4];             /* we don't need much */
-} wavefront_fx_info;
-
-/* support for each of these will be forthcoming once I or someone 
-   else has figured out which of the addresses on page 6 and page 7 of 
-   the YSS225 control each parameter. Incidentally, these come from
-   the Windows driver interface, but again, Turtle Beach didn't
-   document the API to use them.
-*/
-
-#define WFFX_SETOUTGAIN		        0
-#define WFFX_SETSTEREOOUTGAIN		1
-#define WFFX_SETREVERBIN1GAIN		2
-#define WFFX_SETREVERBIN2GAIN		3
-#define WFFX_SETREVERBIN3GAIN		4
-#define WFFX_SETCHORUSINPORT		5
-#define WFFX_SETREVERBIN1PORT		6
-#define WFFX_SETREVERBIN2PORT		7
-#define WFFX_SETREVERBIN3PORT		8
-#define WFFX_SETEFFECTPORT		9
-#define WFFX_SETAUXPORT		        10
-#define WFFX_SETREVERBTYPE		11
-#define WFFX_SETREVERBDELAY		12
-#define WFFX_SETCHORUSLFO		13
-#define WFFX_SETCHORUSPMD		14
-#define WFFX_SETCHORUSAMD		15
-#define WFFX_SETEFFECT		        16
-#define WFFX_SETBASEALL		        17
-#define WFFX_SETREVERBALL		18
-#define WFFX_SETCHORUSALL		20
-#define WFFX_SETREVERBDEF		22
-#define WFFX_SETCHORUSDEF		23
-#define WFFX_DELAYSETINGAIN		24
-#define WFFX_DELAYSETFBGAIN	        25
-#define WFFX_DELAYSETFBLPF		26
-#define WFFX_DELAYSETGAIN		27
-#define WFFX_DELAYSETTIME		28
-#define WFFX_DELAYSETFBTIME		29
-#define WFFX_DELAYSETALL		30
-#define WFFX_DELAYSETDEF		32
-#define WFFX_SDELAYSETINGAIN		33
-#define WFFX_SDELAYSETFBGAIN		34
-#define WFFX_SDELAYSETFBLPF		35
-#define WFFX_SDELAYSETGAIN		36
-#define WFFX_SDELAYSETTIME		37
-#define WFFX_SDELAYSETFBTIME		38
-#define WFFX_SDELAYSETALL		39
-#define WFFX_SDELAYSETDEF		41
-#define WFFX_DEQSETINGAIN		42
-#define WFFX_DEQSETFILTER		43
-#define WFFX_DEQSETALL		        44
-#define WFFX_DEQSETDEF		        46
-#define WFFX_MUTE		        47
-#define WFFX_FLANGESETBALANCE	        48	
-#define WFFX_FLANGESETDELAY		49
-#define WFFX_FLANGESETDWFFX_TH		50
-#define WFFX_FLANGESETFBGAIN		51
-#define WFFX_FLANGESETINGAIN		52
-#define WFFX_FLANGESETLFO		53
-#define WFFX_FLANGESETALL		54
-#define WFFX_FLANGESETDEF		56
-#define WFFX_PITCHSETSHIFT		57
-#define WFFX_PITCHSETBALANCE		58
-#define WFFX_PITCHSETALL		59
-#define WFFX_PITCHSETDEF		61
-#define WFFX_SRSSETINGAIN		62
-#define WFFX_SRSSETSPACE		63
-#define WFFX_SRSSETCENTER		64
-#define WFFX_SRSSETGAIN		        65
-#define WFFX_SRSSETMODE	        	66
-#define WFFX_SRSSETDEF		        68
-
-/* Allow direct user-space control over FX memory/coefficient data.
-   In theory this could be used to download the FX microprogram,
-   but it would be a little slower, and involve some weird code.
- */
-
-#define WFFX_MEMSET              69
-
-#endif /* __wavefront_h__ */
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 4f4d98a..a341c80 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -1,5 +1,5 @@
 /*
- * include/linux/writeback.h.
+ * include/linux/writeback.h
  */
 #ifndef WRITEBACK_H
 #define WRITEBACK_H
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 430afd0..8ae7f74 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -129,7 +129,8 @@
 #define XFRM_MODE_TUNNEL 1
 #define XFRM_MODE_ROUTEOPTIMIZATION 2
 #define XFRM_MODE_IN_TRIGGER 3
-#define XFRM_MODE_MAX 4
+#define XFRM_MODE_BEET 4
+#define XFRM_MODE_MAX 5
 
 /* Netlink configuration messages.  */
 enum {
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index 1fd4a22..db8823d 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -18,7 +18,9 @@
 	AUDIO_CHIP_TDA9874,
 	AUDIO_CHIP_PIC16C54,
 	/* Provided by msp3400.c */
-	AUDIO_CHIP_MSP34XX
+	AUDIO_CHIP_MSP34XX,
+	/* Provided by wm8775.c */
+	AUDIO_CHIP_WM8775
 };
 
 #endif /* AUDIOCHIP_H */
diff --git a/include/mtd/Kbuild b/include/mtd/Kbuild
index 13e7a3c..e0fe92b 100644
--- a/include/mtd/Kbuild
+++ b/include/mtd/Kbuild
@@ -1,6 +1,5 @@
 header-y += inftl-user.h
 header-y += jffs2-user.h
+header-y += mtd-abi.h
 header-y += mtd-user.h
 header-y += nftl-user.h
-
-unifdef-y += mtd-abi.h
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index b0a67b7..f913c30 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -7,12 +7,6 @@
 #ifndef __MTD_ABI_H__
 #define __MTD_ABI_H__
 
-#ifndef __KERNEL__ 
-/* Urgh. The whole point of splitting this out into
-   separate files was to avoid #ifdef __KERNEL__ */
-#define __user
-#endif
-
 struct erase_info_user {
 	uint32_t start;
 	uint32_t length;
diff --git a/include/video/s1d13xxxfb.h b/include/video/s1d13xxxfb.h
index f06cc88..c99d261 100644
--- a/include/video/s1d13xxxfb.h
+++ b/include/video/s1d13xxxfb.h
@@ -1,4 +1,4 @@
-/* drivers/video/s1d3xxxfb.h
+/* include/video/s1d13xxxfb.h
  *
  * (c) 2004 Simtec Electronics
  * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org>
diff --git a/include/video/sstfb.h b/include/video/sstfb.h
index 3570f9c..5dbf5e7 100644
--- a/include/video/sstfb.h
+++ b/include/video/sstfb.h
@@ -68,10 +68,6 @@
 #  define print_var(X,Y...)
 #endif
 
-#define eprintk(X...)	printk(KERN_ERR "sstfb: " X)
-#define iprintk(X...)	printk(KERN_INFO "sstfb: " X)
-#define wprintk(X...)	printk(KERN_WARNING "sstfb: " X)
-
 #define BIT(x)		(1ul<<(x))
 #define POW2(x)		(1ul<<(x))
 
diff --git a/init/Kconfig b/init/Kconfig
index f7a04d0..1038293 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -115,6 +115,15 @@
 	  section 6.4 of the Linux Programmer's Guide, available from
 	  <http://www.tldp.org/guides.html>.
 
+config IPC_NS
+	bool "IPC Namespaces"
+	depends on SYSVIPC
+	default n
+	help
+	  Support ipc namespaces.  This allows containers, i.e. virtual
+	  environments, to use ipc namespaces to provide different ipc
+	  objects for different servers.  If unsure, say N.
+
 config POSIX_MQUEUE
 	bool "POSIX Message Queues"
 	depends on NET && EXPERIMENTAL
@@ -182,6 +191,14 @@
 
 	  Say N if unsure.
 
+config UTS_NS
+	bool "UTS Namespaces"
+	default n
+	help
+	  Support uts namespaces.  This allows containers, i.e.
+	  vservers, to use uts namespaces to provide different
+	  uts info for different servers.  If unsure, say N.
+
 config AUDIT
 	bool "Auditing support"
 	depends on NET
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index a06f037..919a80c 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -1,4 +1,3 @@
-#define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
@@ -35,7 +34,7 @@
 	(void) sys_open("/dev/console",O_RDWR,0);
 	(void) sys_dup(0);
 	(void) sys_dup(0);
-	return execve(shell, argv, envp_init);
+	return kernel_execve(shell, argv, envp_init);
 }
 
 static void __init handle_initrd(void)
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 2429e1b..753dc54 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -20,7 +20,7 @@
 	int level;
 	int chunk;
 	char *device_names;
-} md_setup_args[MAX_MD_DEVS] __initdata;
+} md_setup_args[256] __initdata;
 
 static int md_setup_ents __initdata;
 
@@ -61,10 +61,6 @@
 		return 0;
 	}
 	str1 = str;
-	if (minor >= MAX_MD_DEVS) {
-		printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
-		return 0;
-	}
 	for (ent=0 ; ent< md_setup_ents ; ent++)
 		if (md_setup_args[ent].minor == minor &&
 		    md_setup_args[ent].partitioned == partitioned) {
@@ -72,7 +68,7 @@
 			       "Replacing previous definition.\n", partitioned?"d":"", minor);
 			break;
 		}
-	if (ent >= MAX_MD_DEVS) {
+	if (ent >= ARRAY_SIZE(md_setup_args)) {
 		printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
 		return 0;
 	}
diff --git a/init/main.c b/init/main.c
index 0766e69..ee12324 100644
--- a/init/main.c
+++ b/init/main.c
@@ -9,8 +9,6 @@
  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
  */
 
-#define __KERNEL_SYSCALLS__
-
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
@@ -703,7 +701,7 @@
 static void run_init_process(char *init_filename)
 {
 	argv_init[0] = init_filename;
-	execve(init_filename, argv_init, envp_init);
+	kernel_execve(init_filename, argv_init, envp_init);
 }
 
 static int init(void * unused)
@@ -723,6 +721,8 @@
 	 */
 	child_reaper = current;
 
+	cad_pid = task_pid(current);
+
 	smp_prepare_cpus(max_cpus);
 
 	do_pre_smp_initcalls();
diff --git a/init/version.c b/init/version.c
index e290802..8f28344 100644
--- a/init/version.c
+++ b/init/version.c
@@ -12,22 +12,27 @@
 #include <linux/utsname.h>
 #include <linux/utsrelease.h>
 #include <linux/version.h>
+#include <linux/sched.h>
 
 #define version(a) Version_ ## a
 #define version_string(a) version(a)
 
 int version_string(LINUX_VERSION_CODE);
 
-struct new_utsname system_utsname = {
-	.sysname	= UTS_SYSNAME,
-	.nodename	= UTS_NODENAME,
-	.release	= UTS_RELEASE,
-	.version	= UTS_VERSION,
-	.machine	= UTS_MACHINE,
-	.domainname	= UTS_DOMAINNAME,
+struct uts_namespace init_uts_ns = {
+	.kref = {
+		.refcount	= ATOMIC_INIT(2),
+	},
+	.name = {
+		.sysname	= UTS_SYSNAME,
+		.nodename	= UTS_NODENAME,
+		.release	= UTS_RELEASE,
+		.version	= UTS_VERSION,
+		.machine	= UTS_MACHINE,
+		.domainname	= UTS_DOMAINNAME,
+	},
 };
-
-EXPORT_SYMBOL(system_utsname);
+EXPORT_SYMBOL_GPL(init_uts_ns);
 
 const char linux_banner[] =
 	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index d75d0ba..7c27400 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -2,7 +2,7 @@
  * POSIX message queues filesystem for Linux.
  *
  * Copyright (C) 2003,2004  Krzysztof Benedyczak    (golbi@mat.uni.torun.pl)
- *                          Michal Wronski          (Michal.Wronski@motorola.com)
+ *                          Michal Wronski          (michal.wronski@gmail.com)
  *
  * Spinlocks:               Mohamed Abbas           (abbas.mohamed@intel.com)
  * Lockless receive & send, fd based notify:
@@ -73,7 +73,7 @@
 	struct mq_attr attr;
 
 	struct sigevent notify;
-	pid_t notify_owner;
+	struct pid* notify_owner;
 	struct user_struct *user;	/* user who created, for accounting */
 	struct sock *notify_sock;
 	struct sk_buff *notify_cookie;
@@ -134,7 +134,7 @@
 			INIT_LIST_HEAD(&info->e_wait_q[0].list);
 			INIT_LIST_HEAD(&info->e_wait_q[1].list);
 			info->messages = NULL;
-			info->notify_owner = 0;
+			info->notify_owner = NULL;
 			info->qsize = 0;
 			info->user = NULL;	/* set when all is ok */
 			memset(&info->attr, 0, sizeof(info->attr));
@@ -338,7 +338,7 @@
 			(info->notify_owner &&
 			 info->notify.sigev_notify == SIGEV_SIGNAL) ?
 				info->notify.sigev_signo : 0,
-			info->notify_owner);
+			pid_nr(info->notify_owner));
 	spin_unlock(&info->lock);
 	buffer[sizeof(buffer)-1] = '\0';
 	slen = strlen(buffer)+1;
@@ -363,7 +363,7 @@
 	struct mqueue_inode_info *info = MQUEUE_I(filp->f_dentry->d_inode);
 
 	spin_lock(&info->lock);
-	if (current->tgid == info->notify_owner)
+	if (task_tgid(current) == info->notify_owner)
 		remove_notification(info);
 
 	spin_unlock(&info->lock);
@@ -518,8 +518,8 @@
 			sig_i.si_pid = current->tgid;
 			sig_i.si_uid = current->uid;
 
-			kill_proc_info(info->notify.sigev_signo,
-				       &sig_i, info->notify_owner);
+			kill_pid_info(info->notify.sigev_signo,
+				      &sig_i, info->notify_owner);
 			break;
 		case SIGEV_THREAD:
 			set_cookie(info->notify_cookie, NOTIFY_WOKENUP);
@@ -528,7 +528,8 @@
 			break;
 		}
 		/* after notification unregisters process */
-		info->notify_owner = 0;
+		put_pid(info->notify_owner);
+		info->notify_owner = NULL;
 	}
 	wake_up(&info->wait_q);
 }
@@ -566,12 +567,13 @@
 
 static void remove_notification(struct mqueue_inode_info *info)
 {
-	if (info->notify_owner != 0 &&
+	if (info->notify_owner != NULL &&
 	    info->notify.sigev_notify == SIGEV_THREAD) {
 		set_cookie(info->notify_cookie, NOTIFY_REMOVED);
 		netlink_sendskb(info->notify_sock, info->notify_cookie, 0);
 	}
-	info->notify_owner = 0;
+	put_pid(info->notify_owner);
+	info->notify_owner = NULL;
 }
 
 static int mq_attr_ok(struct mq_attr *attr)
@@ -1062,11 +1064,11 @@
 	ret = 0;
 	spin_lock(&info->lock);
 	if (u_notification == NULL) {
-		if (info->notify_owner == current->tgid) {
+		if (info->notify_owner == task_tgid(current)) {
 			remove_notification(info);
 			inode->i_atime = inode->i_ctime = CURRENT_TIME;
 		}
-	} else if (info->notify_owner != 0) {
+	} else if (info->notify_owner != NULL) {
 		ret = -EBUSY;
 	} else {
 		switch (notification.sigev_notify) {
@@ -1086,7 +1088,8 @@
 			info->notify.sigev_notify = SIGEV_SIGNAL;
 			break;
 		}
-		info->notify_owner = current->tgid;
+
+		info->notify_owner = get_pid(task_tgid(current));
 		inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	}
 	spin_unlock(&info->lock);
diff --git a/ipc/msg.c b/ipc/msg.c
index 2b4fccf..5b213d9 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -16,6 +16,10 @@
  *
  * support for audit of ipc object properties and permission changes
  * Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/capability.h>
@@ -31,16 +35,12 @@
 #include <linux/audit.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
 #include "util.h"
 
-/* sysctl: */
-int msg_ctlmax = MSGMAX;
-int msg_ctlmnb = MSGMNB;
-int msg_ctlmni = MSGMNI;
-
 /*
  * one msg_receiver structure for each sleeping receiver:
  */
@@ -69,30 +69,75 @@
 static atomic_t msg_bytes =	ATOMIC_INIT(0);
 static atomic_t msg_hdrs =	ATOMIC_INIT(0);
 
-static struct ipc_ids msg_ids;
+static struct ipc_ids init_msg_ids;
 
-#define msg_lock(id)		((struct msg_queue *)ipc_lock(&msg_ids, id))
+#define msg_ids(ns)	(*((ns)->ids[IPC_MSG_IDS]))
+
+#define msg_lock(ns, id)	((struct msg_queue*)ipc_lock(&msg_ids(ns), id))
 #define msg_unlock(msq)		ipc_unlock(&(msq)->q_perm)
-#define msg_rmid(id)		((struct msg_queue *)ipc_rmid(&msg_ids, id))
-#define msg_checkid(msq, msgid)	ipc_checkid(&msg_ids, &msq->q_perm, msgid)
-#define msg_buildid(id, seq)	ipc_buildid(&msg_ids, id, seq)
+#define msg_rmid(ns, id)	((struct msg_queue*)ipc_rmid(&msg_ids(ns), id))
+#define msg_checkid(ns, msq, msgid)	\
+	ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid)
+#define msg_buildid(ns, id, seq) \
+	ipc_buildid(&msg_ids(ns), id, seq)
 
-static void freeque(struct msg_queue *msq, int id);
-static int newque(key_t key, int msgflg);
+static void freeque (struct ipc_namespace *ns, struct msg_queue *msq, int id);
+static int newque (struct ipc_namespace *ns, key_t key, int msgflg);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
 #endif
 
-void __init msg_init(void)
+static void __ipc_init __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
 {
-	ipc_init_ids(&msg_ids, msg_ctlmni);
-	ipc_init_proc_interface("sysvipc/msg",
-				"       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
-				&msg_ids,
-				sysvipc_msg_proc_show);
+	ns->ids[IPC_MSG_IDS] = ids;
+	ns->msg_ctlmax = MSGMAX;
+	ns->msg_ctlmnb = MSGMNB;
+	ns->msg_ctlmni = MSGMNI;
+	ipc_init_ids(ids, ns->msg_ctlmni);
 }
 
-static int newque(key_t key, int msgflg)
+#ifdef CONFIG_IPC_NS
+int msg_init_ns(struct ipc_namespace *ns)
+{
+	struct ipc_ids *ids;
+
+	ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+	if (ids == NULL)
+		return -ENOMEM;
+
+	__msg_init_ns(ns, ids);
+	return 0;
+}
+
+void msg_exit_ns(struct ipc_namespace *ns)
+{
+	int i;
+	struct msg_queue *msq;
+
+	mutex_lock(&msg_ids(ns).mutex);
+	for (i = 0; i <= msg_ids(ns).max_id; i++) {
+		msq = msg_lock(ns, i);
+		if (msq == NULL)
+			continue;
+
+		freeque(ns, msq, i);
+	}
+	mutex_unlock(&msg_ids(ns).mutex);
+
+	kfree(ns->ids[IPC_MSG_IDS]);
+	ns->ids[IPC_MSG_IDS] = NULL;
+}
+#endif
+
+void __init msg_init(void)
+{
+	__msg_init_ns(&init_ipc_ns, &init_msg_ids);
+	ipc_init_proc_interface("sysvipc/msg",
+				"       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
+				IPC_MSG_IDS, sysvipc_msg_proc_show);
+}
+
+static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
 {
 	struct msg_queue *msq;
 	int id, retval;
@@ -111,18 +156,18 @@
 		return retval;
 	}
 
-	id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni);
+	id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
 	if (id == -1) {
 		security_msg_queue_free(msq);
 		ipc_rcu_putref(msq);
 		return -ENOSPC;
 	}
 
-	msq->q_id = msg_buildid(id, msq->q_perm.seq);
+	msq->q_id = msg_buildid(ns, id, msq->q_perm.seq);
 	msq->q_stime = msq->q_rtime = 0;
 	msq->q_ctime = get_seconds();
 	msq->q_cbytes = msq->q_qnum = 0;
-	msq->q_qbytes = msg_ctlmnb;
+	msq->q_qbytes = ns->msg_ctlmnb;
 	msq->q_lspid = msq->q_lrpid = 0;
 	INIT_LIST_HEAD(&msq->q_messages);
 	INIT_LIST_HEAD(&msq->q_receivers);
@@ -186,13 +231,13 @@
  * msg_ids.mutex and the spinlock for this message queue is hold
  * before freeque() is called. msg_ids.mutex remains locked on exit.
  */
-static void freeque(struct msg_queue *msq, int id)
+static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
 {
 	struct list_head *tmp;
 
 	expunge_all(msq, -EIDRM);
 	ss_wakeup(&msq->q_senders, 1);
-	msq = msg_rmid(id);
+	msq = msg_rmid(ns, id);
 	msg_unlock(msq);
 
 	tmp = msq->q_messages.next;
@@ -212,24 +257,27 @@
 {
 	struct msg_queue *msq;
 	int id, ret = -EPERM;
+	struct ipc_namespace *ns;
+
+	ns = current->nsproxy->ipc_ns;
 	
-	mutex_lock(&msg_ids.mutex);
+	mutex_lock(&msg_ids(ns).mutex);
 	if (key == IPC_PRIVATE) 
-		ret = newque(key, msgflg);
-	else if ((id = ipc_findkey(&msg_ids, key)) == -1) { /* key not used */
+		ret = newque(ns, key, msgflg);
+	else if ((id = ipc_findkey(&msg_ids(ns), key)) == -1) { /* key not used */
 		if (!(msgflg & IPC_CREAT))
 			ret = -ENOENT;
 		else
-			ret = newque(key, msgflg);
+			ret = newque(ns, key, msgflg);
 	} else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) {
 		ret = -EEXIST;
 	} else {
-		msq = msg_lock(id);
+		msq = msg_lock(ns, id);
 		BUG_ON(msq == NULL);
 		if (ipcperms(&msq->q_perm, msgflg))
 			ret = -EACCES;
 		else {
-			int qid = msg_buildid(id, msq->q_perm.seq);
+			int qid = msg_buildid(ns, id, msq->q_perm.seq);
 
 			ret = security_msg_queue_associate(msq, msgflg);
 			if (!ret)
@@ -237,7 +285,7 @@
 		}
 		msg_unlock(msq);
 	}
-	mutex_unlock(&msg_ids.mutex);
+	mutex_unlock(&msg_ids(ns).mutex);
 
 	return ret;
 }
@@ -341,11 +389,13 @@
 	struct msq_setbuf setbuf;
 	struct msg_queue *msq;
 	int err, version;
+	struct ipc_namespace *ns;
 
 	if (msqid < 0 || cmd < 0)
 		return -EINVAL;
 
 	version = ipc_parse_version(&cmd);
+	ns = current->nsproxy->ipc_ns;
 
 	switch (cmd) {
 	case IPC_INFO:
@@ -366,14 +416,14 @@
 			return err;
 
 		memset(&msginfo, 0, sizeof(msginfo));
-		msginfo.msgmni = msg_ctlmni;
-		msginfo.msgmax = msg_ctlmax;
-		msginfo.msgmnb = msg_ctlmnb;
+		msginfo.msgmni = ns->msg_ctlmni;
+		msginfo.msgmax = ns->msg_ctlmax;
+		msginfo.msgmnb = ns->msg_ctlmnb;
 		msginfo.msgssz = MSGSSZ;
 		msginfo.msgseg = MSGSEG;
-		mutex_lock(&msg_ids.mutex);
+		mutex_lock(&msg_ids(ns).mutex);
 		if (cmd == MSG_INFO) {
-			msginfo.msgpool = msg_ids.in_use;
+			msginfo.msgpool = msg_ids(ns).in_use;
 			msginfo.msgmap = atomic_read(&msg_hdrs);
 			msginfo.msgtql = atomic_read(&msg_bytes);
 		} else {
@@ -381,8 +431,8 @@
 			msginfo.msgpool = MSGPOOL;
 			msginfo.msgtql = MSGTQL;
 		}
-		max_id = msg_ids.max_id;
-		mutex_unlock(&msg_ids.mutex);
+		max_id = msg_ids(ns).max_id;
+		mutex_unlock(&msg_ids(ns).mutex);
 		if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
 			return -EFAULT;
 		return (max_id < 0) ? 0 : max_id;
@@ -395,20 +445,20 @@
 
 		if (!buf)
 			return -EFAULT;
-		if (cmd == MSG_STAT && msqid >= msg_ids.entries->size)
+		if (cmd == MSG_STAT && msqid >= msg_ids(ns).entries->size)
 			return -EINVAL;
 
 		memset(&tbuf, 0, sizeof(tbuf));
 
-		msq = msg_lock(msqid);
+		msq = msg_lock(ns, msqid);
 		if (msq == NULL)
 			return -EINVAL;
 
 		if (cmd == MSG_STAT) {
-			success_return = msg_buildid(msqid, msq->q_perm.seq);
+			success_return = msg_buildid(ns, msqid, msq->q_perm.seq);
 		} else {
 			err = -EIDRM;
-			if (msg_checkid(msq, msqid))
+			if (msg_checkid(ns, msq, msqid))
 				goto out_unlock;
 			success_return = 0;
 		}
@@ -446,14 +496,14 @@
 		return  -EINVAL;
 	}
 
-	mutex_lock(&msg_ids.mutex);
-	msq = msg_lock(msqid);
+	mutex_lock(&msg_ids(ns).mutex);
+	msq = msg_lock(ns, msqid);
 	err = -EINVAL;
 	if (msq == NULL)
 		goto out_up;
 
 	err = -EIDRM;
-	if (msg_checkid(msq, msqid))
+	if (msg_checkid(ns, msq, msqid))
 		goto out_unlock_up;
 	ipcp = &msq->q_perm;
 
@@ -481,7 +531,7 @@
 	case IPC_SET:
 	{
 		err = -EPERM;
-		if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
+		if (setbuf.qbytes > ns->msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
 			goto out_unlock_up;
 
 		msq->q_qbytes = setbuf.qbytes;
@@ -503,12 +553,12 @@
 		break;
 	}
 	case IPC_RMID:
-		freeque(msq, msqid);
+		freeque(ns, msq, msqid);
 		break;
 	}
 	err = 0;
 out_up:
-	mutex_unlock(&msg_ids.mutex);
+	mutex_unlock(&msg_ids(ns).mutex);
 	return err;
 out_unlock_up:
 	msg_unlock(msq);
@@ -582,8 +632,11 @@
 	struct msg_msg *msg;
 	long mtype;
 	int err;
+	struct ipc_namespace *ns;
 
-	if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0)
+	ns = current->nsproxy->ipc_ns;
+
+	if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0)
 		return -EINVAL;
 	if (get_user(mtype, &msgp->mtype))
 		return -EFAULT;
@@ -597,13 +650,13 @@
 	msg->m_type = mtype;
 	msg->m_ts = msgsz;
 
-	msq = msg_lock(msqid);
+	msq = msg_lock(ns, msqid);
 	err = -EINVAL;
 	if (msq == NULL)
 		goto out_free;
 
 	err= -EIDRM;
-	if (msg_checkid(msq, msqid))
+	if (msg_checkid(ns, msq, msqid))
 		goto out_unlock_free;
 
 	for (;;) {
@@ -694,17 +747,19 @@
 	struct msg_queue *msq;
 	struct msg_msg *msg;
 	int mode;
+	struct ipc_namespace *ns;
 
 	if (msqid < 0 || (long) msgsz < 0)
 		return -EINVAL;
 	mode = convert_mode(&msgtyp, msgflg);
+	ns = current->nsproxy->ipc_ns;
 
-	msq = msg_lock(msqid);
+	msq = msg_lock(ns, msqid);
 	if (msq == NULL)
 		return -EINVAL;
 
 	msg = ERR_PTR(-EIDRM);
-	if (msg_checkid(msq, msqid))
+	if (msg_checkid(ns, msq, msqid))
 		goto out_unlock;
 
 	for (;;) {
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index 66cfb87..0992616 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -1,5 +1,5 @@
 /*
- * linux/ipc/util.c
+ * linux/ipc/msgutil.c
  * Copyright (C) 1999, 2004 Manfred Spraul
  *
  * This file is released under GNU General Public Licence version 2 or
diff --git a/ipc/sem.c b/ipc/sem.c
index 6013c75..0dafcc4 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -64,6 +64,10 @@
  *
  * support for audit of ipc object properties and permission changes
  * Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/slab.h>
@@ -78,22 +82,25 @@
 #include <linux/capability.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
 #include "util.h"
 
+#define sem_ids(ns)	(*((ns)->ids[IPC_SEM_IDS]))
 
-#define sem_lock(id)	((struct sem_array*)ipc_lock(&sem_ids,id))
-#define sem_unlock(sma)	ipc_unlock(&(sma)->sem_perm)
-#define sem_rmid(id)	((struct sem_array*)ipc_rmid(&sem_ids,id))
-#define sem_checkid(sma, semid)	\
-	ipc_checkid(&sem_ids,&sma->sem_perm,semid)
-#define sem_buildid(id, seq) \
-	ipc_buildid(&sem_ids, id, seq)
-static struct ipc_ids sem_ids;
+#define sem_lock(ns, id)	((struct sem_array*)ipc_lock(&sem_ids(ns), id))
+#define sem_unlock(sma)		ipc_unlock(&(sma)->sem_perm)
+#define sem_rmid(ns, id)	((struct sem_array*)ipc_rmid(&sem_ids(ns), id))
+#define sem_checkid(ns, sma, semid)	\
+	ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid)
+#define sem_buildid(ns, id, seq) \
+	ipc_buildid(&sem_ids(ns), id, seq)
 
-static int newary (key_t, int, int);
-static void freeary (struct sem_array *sma, int id);
+static struct ipc_ids init_sem_ids;
+
+static int newary(struct ipc_namespace *, key_t, int, int);
+static void freeary(struct ipc_namespace *ns, struct sem_array *sma, int id);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
 #endif
@@ -110,22 +117,61 @@
  *	
  */
 
-int sem_ctls[4] = {SEMMSL, SEMMNS, SEMOPM, SEMMNI};
-#define sc_semmsl	(sem_ctls[0])
-#define sc_semmns	(sem_ctls[1])
-#define sc_semopm	(sem_ctls[2])
-#define sc_semmni	(sem_ctls[3])
+#define sc_semmsl	sem_ctls[0]
+#define sc_semmns	sem_ctls[1]
+#define sc_semopm	sem_ctls[2]
+#define sc_semmni	sem_ctls[3]
 
-static int used_sems;
+static void __ipc_init __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+	ns->ids[IPC_SEM_IDS] = ids;
+	ns->sc_semmsl = SEMMSL;
+	ns->sc_semmns = SEMMNS;
+	ns->sc_semopm = SEMOPM;
+	ns->sc_semmni = SEMMNI;
+	ns->used_sems = 0;
+	ipc_init_ids(ids, ns->sc_semmni);
+}
+
+#ifdef CONFIG_IPC_NS
+int sem_init_ns(struct ipc_namespace *ns)
+{
+	struct ipc_ids *ids;
+
+	ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+	if (ids == NULL)
+		return -ENOMEM;
+
+	__sem_init_ns(ns, ids);
+	return 0;
+}
+
+void sem_exit_ns(struct ipc_namespace *ns)
+{
+	int i;
+	struct sem_array *sma;
+
+	mutex_lock(&sem_ids(ns).mutex);
+	for (i = 0; i <= sem_ids(ns).max_id; i++) {
+		sma = sem_lock(ns, i);
+		if (sma == NULL)
+			continue;
+
+		freeary(ns, sma, i);
+	}
+	mutex_unlock(&sem_ids(ns).mutex);
+
+	kfree(ns->ids[IPC_SEM_IDS]);
+	ns->ids[IPC_SEM_IDS] = NULL;
+}
+#endif
 
 void __init sem_init (void)
 {
-	used_sems = 0;
-	ipc_init_ids(&sem_ids,sc_semmni);
+	__sem_init_ns(&init_ipc_ns, &init_sem_ids);
 	ipc_init_proc_interface("sysvipc/sem",
 				"       key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime\n",
-				&sem_ids,
-				sysvipc_sem_proc_show);
+				IPC_SEM_IDS, sysvipc_sem_proc_show);
 }
 
 /*
@@ -162,7 +208,7 @@
  */
 #define IN_WAKEUP	1
 
-static int newary (key_t key, int nsems, int semflg)
+static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
 {
 	int id;
 	int retval;
@@ -171,7 +217,7 @@
 
 	if (!nsems)
 		return -EINVAL;
-	if (used_sems + nsems > sc_semmns)
+	if (ns->used_sems + nsems > ns->sc_semmns)
 		return -ENOSPC;
 
 	size = sizeof (*sma) + nsems * sizeof (struct sem);
@@ -191,15 +237,15 @@
 		return retval;
 	}
 
-	id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni);
+	id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
 	if(id == -1) {
 		security_sem_free(sma);
 		ipc_rcu_putref(sma);
 		return -ENOSPC;
 	}
-	used_sems += nsems;
+	ns->used_sems += nsems;
 
-	sma->sem_id = sem_buildid(id, sma->sem_perm.seq);
+	sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
 	sma->sem_base = (struct sem *) &sma[1];
 	/* sma->sem_pending = NULL; */
 	sma->sem_pending_last = &sma->sem_pending;
@@ -215,29 +261,32 @@
 {
 	int id, err = -EINVAL;
 	struct sem_array *sma;
+	struct ipc_namespace *ns;
 
-	if (nsems < 0 || nsems > sc_semmsl)
+	ns = current->nsproxy->ipc_ns;
+
+	if (nsems < 0 || nsems > ns->sc_semmsl)
 		return -EINVAL;
-	mutex_lock(&sem_ids.mutex);
+	mutex_lock(&sem_ids(ns).mutex);
 	
 	if (key == IPC_PRIVATE) {
-		err = newary(key, nsems, semflg);
-	} else if ((id = ipc_findkey(&sem_ids, key)) == -1) {  /* key not used */
+		err = newary(ns, key, nsems, semflg);
+	} else if ((id = ipc_findkey(&sem_ids(ns), key)) == -1) {  /* key not used */
 		if (!(semflg & IPC_CREAT))
 			err = -ENOENT;
 		else
-			err = newary(key, nsems, semflg);
+			err = newary(ns, key, nsems, semflg);
 	} else if (semflg & IPC_CREAT && semflg & IPC_EXCL) {
 		err = -EEXIST;
 	} else {
-		sma = sem_lock(id);
+		sma = sem_lock(ns, id);
 		BUG_ON(sma==NULL);
 		if (nsems > sma->sem_nsems)
 			err = -EINVAL;
 		else if (ipcperms(&sma->sem_perm, semflg))
 			err = -EACCES;
 		else {
-			int semid = sem_buildid(id, sma->sem_perm.seq);
+			int semid = sem_buildid(ns, id, sma->sem_perm.seq);
 			err = security_sem_associate(sma, semflg);
 			if (!err)
 				err = semid;
@@ -245,7 +294,7 @@
 		sem_unlock(sma);
 	}
 
-	mutex_unlock(&sem_ids.mutex);
+	mutex_unlock(&sem_ids(ns).mutex);
 	return err;
 }
 
@@ -444,7 +493,7 @@
  * the spinlock for this semaphore set hold. sem_ids.mutex remains locked
  * on exit.
  */
-static void freeary (struct sem_array *sma, int id)
+static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
 {
 	struct sem_undo *un;
 	struct sem_queue *q;
@@ -472,10 +521,10 @@
 	}
 
 	/* Remove the semaphore set from the ID array*/
-	sma = sem_rmid(id);
+	sma = sem_rmid(ns, id);
 	sem_unlock(sma);
 
-	used_sems -= sma->sem_nsems;
+	ns->used_sems -= sma->sem_nsems;
 	size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
 	security_sem_free(sma);
 	ipc_rcu_putref(sma);
@@ -503,7 +552,8 @@
 	}
 }
 
-static int semctl_nolock(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
+		int cmd, int version, union semun arg)
 {
 	int err = -EINVAL;
 	struct sem_array *sma;
@@ -520,24 +570,24 @@
 			return err;
 		
 		memset(&seminfo,0,sizeof(seminfo));
-		seminfo.semmni = sc_semmni;
-		seminfo.semmns = sc_semmns;
-		seminfo.semmsl = sc_semmsl;
-		seminfo.semopm = sc_semopm;
+		seminfo.semmni = ns->sc_semmni;
+		seminfo.semmns = ns->sc_semmns;
+		seminfo.semmsl = ns->sc_semmsl;
+		seminfo.semopm = ns->sc_semopm;
 		seminfo.semvmx = SEMVMX;
 		seminfo.semmnu = SEMMNU;
 		seminfo.semmap = SEMMAP;
 		seminfo.semume = SEMUME;
-		mutex_lock(&sem_ids.mutex);
+		mutex_lock(&sem_ids(ns).mutex);
 		if (cmd == SEM_INFO) {
-			seminfo.semusz = sem_ids.in_use;
-			seminfo.semaem = used_sems;
+			seminfo.semusz = sem_ids(ns).in_use;
+			seminfo.semaem = ns->used_sems;
 		} else {
 			seminfo.semusz = SEMUSZ;
 			seminfo.semaem = SEMAEM;
 		}
-		max_id = sem_ids.max_id;
-		mutex_unlock(&sem_ids.mutex);
+		max_id = sem_ids(ns).max_id;
+		mutex_unlock(&sem_ids(ns).mutex);
 		if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) 
 			return -EFAULT;
 		return (max_id < 0) ? 0: max_id;
@@ -547,12 +597,12 @@
 		struct semid64_ds tbuf;
 		int id;
 
-		if(semid >= sem_ids.entries->size)
+		if(semid >= sem_ids(ns).entries->size)
 			return -EINVAL;
 
 		memset(&tbuf,0,sizeof(tbuf));
 
-		sma = sem_lock(semid);
+		sma = sem_lock(ns, semid);
 		if(sma == NULL)
 			return -EINVAL;
 
@@ -564,7 +614,7 @@
 		if (err)
 			goto out_unlock;
 
-		id = sem_buildid(semid, sma->sem_perm.seq);
+		id = sem_buildid(ns, semid, sma->sem_perm.seq);
 
 		kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
 		tbuf.sem_otime  = sma->sem_otime;
@@ -584,7 +634,8 @@
 	return err;
 }
 
-static int semctl_main(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
+		int cmd, int version, union semun arg)
 {
 	struct sem_array *sma;
 	struct sem* curr;
@@ -593,14 +644,14 @@
 	ushort* sem_io = fast_sem_io;
 	int nsems;
 
-	sma = sem_lock(semid);
+	sma = sem_lock(ns, semid);
 	if(sma==NULL)
 		return -EINVAL;
 
 	nsems = sma->sem_nsems;
 
 	err=-EIDRM;
-	if (sem_checkid(sma,semid))
+	if (sem_checkid(ns,sma,semid))
 		goto out_unlock;
 
 	err = -EACCES;
@@ -802,7 +853,8 @@
 	}
 }
 
-static int semctl_down(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
+		int cmd, int version, union semun arg)
 {
 	struct sem_array *sma;
 	int err;
@@ -813,11 +865,11 @@
 		if(copy_semid_from_user (&setbuf, arg.buf, version))
 			return -EFAULT;
 	}
-	sma = sem_lock(semid);
+	sma = sem_lock(ns, semid);
 	if(sma==NULL)
 		return -EINVAL;
 
-	if (sem_checkid(sma,semid)) {
+	if (sem_checkid(ns,sma,semid)) {
 		err=-EIDRM;
 		goto out_unlock;
 	}	
@@ -844,7 +896,7 @@
 
 	switch(cmd){
 	case IPC_RMID:
-		freeary(sma, semid);
+		freeary(ns, sma, semid);
 		err = 0;
 		break;
 	case IPC_SET:
@@ -872,17 +924,19 @@
 {
 	int err = -EINVAL;
 	int version;
+	struct ipc_namespace *ns;
 
 	if (semid < 0)
 		return -EINVAL;
 
 	version = ipc_parse_version(&cmd);
+	ns = current->nsproxy->ipc_ns;
 
 	switch(cmd) {
 	case IPC_INFO:
 	case SEM_INFO:
 	case SEM_STAT:
-		err = semctl_nolock(semid,semnum,cmd,version,arg);
+		err = semctl_nolock(ns,semid,semnum,cmd,version,arg);
 		return err;
 	case GETALL:
 	case GETVAL:
@@ -892,13 +946,13 @@
 	case IPC_STAT:
 	case SETVAL:
 	case SETALL:
-		err = semctl_main(semid,semnum,cmd,version,arg);
+		err = semctl_main(ns,semid,semnum,cmd,version,arg);
 		return err;
 	case IPC_RMID:
 	case IPC_SET:
-		mutex_lock(&sem_ids.mutex);
-		err = semctl_down(semid,semnum,cmd,version,arg);
-		mutex_unlock(&sem_ids.mutex);
+		mutex_lock(&sem_ids(ns).mutex);
+		err = semctl_down(ns,semid,semnum,cmd,version,arg);
+		mutex_unlock(&sem_ids(ns).mutex);
 		return err;
 	default:
 		return -EINVAL;
@@ -949,15 +1003,12 @@
 static inline int get_undo_list(struct sem_undo_list **undo_listp)
 {
 	struct sem_undo_list *undo_list;
-	int size;
 
 	undo_list = current->sysvsem.undo_list;
 	if (!undo_list) {
-		size = sizeof(struct sem_undo_list);
-		undo_list = (struct sem_undo_list *) kmalloc(size, GFP_KERNEL);
+		undo_list = kzalloc(sizeof(*undo_list), GFP_KERNEL);
 		if (undo_list == NULL)
 			return -ENOMEM;
-		memset(undo_list, 0, size);
 		spin_lock_init(&undo_list->lock);
 		atomic_set(&undo_list->refcnt, 1);
 		current->sysvsem.undo_list = undo_list;
@@ -986,7 +1037,7 @@
 	return un;
 }
 
-static struct sem_undo *find_undo(int semid)
+static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
 {
 	struct sem_array *sma;
 	struct sem_undo_list *ulp;
@@ -1005,12 +1056,12 @@
 		goto out;
 
 	/* no undo structure around - allocate one. */
-	sma = sem_lock(semid);
+	sma = sem_lock(ns, semid);
 	un = ERR_PTR(-EINVAL);
 	if(sma==NULL)
 		goto out;
 	un = ERR_PTR(-EIDRM);
-	if (sem_checkid(sma,semid)) {
+	if (sem_checkid(ns,sma,semid)) {
 		sem_unlock(sma);
 		goto out;
 	}
@@ -1070,10 +1121,13 @@
 	int undos = 0, alter = 0, max;
 	struct sem_queue queue;
 	unsigned long jiffies_left = 0;
+	struct ipc_namespace *ns;
+
+	ns = current->nsproxy->ipc_ns;
 
 	if (nsops < 1 || semid < 0)
 		return -EINVAL;
-	if (nsops > sc_semopm)
+	if (nsops > ns->sc_semopm)
 		return -E2BIG;
 	if(nsops > SEMOPM_FAST) {
 		sops = kmalloc(sizeof(*sops)*nsops,GFP_KERNEL);
@@ -1109,7 +1163,7 @@
 
 retry_undos:
 	if (undos) {
-		un = find_undo(semid);
+		un = find_undo(ns, semid);
 		if (IS_ERR(un)) {
 			error = PTR_ERR(un);
 			goto out_free;
@@ -1117,12 +1171,12 @@
 	} else
 		un = NULL;
 
-	sma = sem_lock(semid);
+	sma = sem_lock(ns, semid);
 	error=-EINVAL;
 	if(sma==NULL)
 		goto out_free;
 	error = -EIDRM;
-	if (sem_checkid(sma,semid))
+	if (sem_checkid(ns,sma,semid))
 		goto out_unlock_free;
 	/*
 	 * semid identifies are not unique - find_undo may have
@@ -1190,7 +1244,7 @@
 		goto out_free;
 	}
 
-	sma = sem_lock(semid);
+	sma = sem_lock(ns, semid);
 	if(sma==NULL) {
 		BUG_ON(queue.prev != NULL);
 		error = -EIDRM;
@@ -1267,6 +1321,7 @@
 {
 	struct sem_undo_list *undo_list;
 	struct sem_undo *u, **up;
+	struct ipc_namespace *ns;
 
 	undo_list = tsk->sysvsem.undo_list;
 	if (!undo_list)
@@ -1275,6 +1330,7 @@
 	if (!atomic_dec_and_test(&undo_list->refcnt))
 		return;
 
+	ns = tsk->nsproxy->ipc_ns;
 	/* There's no need to hold the semundo list lock, as current
          * is the last task exiting for this undo list.
 	 */
@@ -1288,14 +1344,14 @@
 
 		if(semid == -1)
 			continue;
-		sma = sem_lock(semid);
+		sma = sem_lock(ns, semid);
 		if (sma == NULL)
 			continue;
 
 		if (u->semid == -1)
 			goto next_entry;
 
-		BUG_ON(sem_checkid(sma,u->semid));
+		BUG_ON(sem_checkid(ns,sma,u->semid));
 
 		/* remove u from the sma->undo list */
 		for (unp = &sma->undo; (un = *unp); unp = &un->id_next) {
diff --git a/ipc/shm.c b/ipc/shm.c
index 940b0c9..bfbd317 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -15,6 +15,10 @@
  *
  * support for audit of ipc object properties and permission changes
  * Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/slab.h>
@@ -32,6 +36,7 @@
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
 
@@ -40,59 +45,115 @@
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
 
-static struct ipc_ids shm_ids;
+static struct ipc_ids init_shm_ids;
 
-#define shm_lock(id)	((struct shmid_kernel*)ipc_lock(&shm_ids,id))
-#define shm_unlock(shp)	ipc_unlock(&(shp)->shm_perm)
-#define shm_get(id)	((struct shmid_kernel*)ipc_get(&shm_ids,id))
-#define shm_buildid(id, seq) \
-	ipc_buildid(&shm_ids, id, seq)
+#define shm_ids(ns)	(*((ns)->ids[IPC_SHM_IDS]))
 
-static int newseg (key_t key, int shmflg, size_t size);
+#define shm_lock(ns, id)		\
+	((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id))
+#define shm_unlock(shp)			\
+	ipc_unlock(&(shp)->shm_perm)
+#define shm_get(ns, id)			\
+	((struct shmid_kernel*)ipc_get(&shm_ids(ns),id))
+#define shm_buildid(ns, id, seq)	\
+	ipc_buildid(&shm_ids(ns), id, seq)
+
+static int newseg (struct ipc_namespace *ns, key_t key,
+		int shmflg, size_t size);
 static void shm_open (struct vm_area_struct *shmd);
 static void shm_close (struct vm_area_struct *shmd);
+static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
 #endif
 
-size_t	shm_ctlmax = SHMMAX;
-size_t 	shm_ctlall = SHMALL;
-int 	shm_ctlmni = SHMMNI;
+static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+	ns->ids[IPC_SHM_IDS] = ids;
+	ns->shm_ctlmax = SHMMAX;
+	ns->shm_ctlall = SHMALL;
+	ns->shm_ctlmni = SHMMNI;
+	ns->shm_tot = 0;
+	ipc_init_ids(ids, 1);
+}
 
-static int shm_tot; /* total number of shared memory pages */
+static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
+{
+	if (shp->shm_nattch){
+		shp->shm_perm.mode |= SHM_DEST;
+		/* Do not find it any more */
+		shp->shm_perm.key = IPC_PRIVATE;
+		shm_unlock(shp);
+	} else
+		shm_destroy(ns, shp);
+}
+
+#ifdef CONFIG_IPC_NS
+int shm_init_ns(struct ipc_namespace *ns)
+{
+	struct ipc_ids *ids;
+
+	ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+	if (ids == NULL)
+		return -ENOMEM;
+
+	__shm_init_ns(ns, ids);
+	return 0;
+}
+
+void shm_exit_ns(struct ipc_namespace *ns)
+{
+	int i;
+	struct shmid_kernel *shp;
+
+	mutex_lock(&shm_ids(ns).mutex);
+	for (i = 0; i <= shm_ids(ns).max_id; i++) {
+		shp = shm_lock(ns, i);
+		if (shp == NULL)
+			continue;
+
+		do_shm_rmid(ns, shp);
+	}
+	mutex_unlock(&shm_ids(ns).mutex);
+
+	kfree(ns->ids[IPC_SHM_IDS]);
+	ns->ids[IPC_SHM_IDS] = NULL;
+}
+#endif
 
 void __init shm_init (void)
 {
-	ipc_init_ids(&shm_ids, 1);
+	__shm_init_ns(&init_ipc_ns, &init_shm_ids);
 	ipc_init_proc_interface("sysvipc/shm",
 				"       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n",
-				&shm_ids,
-				sysvipc_shm_proc_show);
+				IPC_SHM_IDS, sysvipc_shm_proc_show);
 }
 
-static inline int shm_checkid(struct shmid_kernel *s, int id)
+static inline int shm_checkid(struct ipc_namespace *ns,
+		struct shmid_kernel *s, int id)
 {
-	if (ipc_checkid(&shm_ids,&s->shm_perm,id))
+	if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id))
 		return -EIDRM;
 	return 0;
 }
 
-static inline struct shmid_kernel *shm_rmid(int id)
+static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id)
 {
-	return (struct shmid_kernel *)ipc_rmid(&shm_ids,id);
+	return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id);
 }
 
-static inline int shm_addid(struct shmid_kernel *shp)
+static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
-	return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni);
+	return ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
 }
 
 
 
-static inline void shm_inc (int id) {
+static inline void shm_inc(struct ipc_namespace *ns, int id)
+{
 	struct shmid_kernel *shp;
 
-	shp = shm_lock(id);
+	shp = shm_lock(ns, id);
 	BUG_ON(!shp);
 	shp->shm_atim = get_seconds();
 	shp->shm_lprid = current->tgid;
@@ -100,10 +161,13 @@
 	shm_unlock(shp);
 }
 
+#define shm_file_ns(file) (*((struct ipc_namespace **)&(file)->private_data))
+
 /* This is called by fork, once for every shm attach. */
-static void shm_open (struct vm_area_struct *shmd)
+static void shm_open(struct vm_area_struct *shmd)
 {
-	shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
+	shm_inc(shm_file_ns(shmd->vm_file),
+			shmd->vm_file->f_dentry->d_inode->i_ino);
 }
 
 /*
@@ -114,10 +178,10 @@
  * It has to be called with shp and shm_ids.mutex locked,
  * but returns with shp unlocked and freed.
  */
-static void shm_destroy (struct shmid_kernel *shp)
+static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
-	shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	shm_rmid (shp->id);
+	ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	shm_rmid(ns, shp->id);
 	shm_unlock(shp);
 	if (!is_file_hugepages(shp->shm_file))
 		shmem_lock(shp->shm_file, 0, shp->mlock_user);
@@ -140,20 +204,23 @@
 	struct file * file = shmd->vm_file;
 	int id = file->f_dentry->d_inode->i_ino;
 	struct shmid_kernel *shp;
+	struct ipc_namespace *ns;
 
-	mutex_lock(&shm_ids.mutex);
+	ns = shm_file_ns(file);
+
+	mutex_lock(&shm_ids(ns).mutex);
 	/* remove from the list of attaches of the shm segment */
-	shp = shm_lock(id);
+	shp = shm_lock(ns, id);
 	BUG_ON(!shp);
 	shp->shm_lprid = current->tgid;
 	shp->shm_dtim = get_seconds();
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_perm.mode & SHM_DEST)
-		shm_destroy (shp);
+		shm_destroy(ns, shp);
 	else
 		shm_unlock(shp);
-	mutex_unlock(&shm_ids.mutex);
+	mutex_unlock(&shm_ids(ns).mutex);
 }
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
@@ -165,14 +232,25 @@
 		vma->vm_ops = &shm_vm_ops;
 		if (!(vma->vm_flags & VM_WRITE))
 			vma->vm_flags &= ~VM_MAYWRITE;
-		shm_inc(file->f_dentry->d_inode->i_ino);
+		shm_inc(shm_file_ns(file), file->f_dentry->d_inode->i_ino);
 	}
 
 	return ret;
 }
 
+static int shm_release(struct inode *ino, struct file *file)
+{
+	struct ipc_namespace *ns;
+
+	ns = shm_file_ns(file);
+	put_ipc_ns(ns);
+	shm_file_ns(file) = NULL;
+	return 0;
+}
+
 static struct file_operations shm_file_operations = {
-	.mmap	= shm_mmap,
+	.mmap		= shm_mmap,
+	.release	= shm_release,
 #ifndef CONFIG_MMU
 	.get_unmapped_area = shmem_get_unmapped_area,
 #endif
@@ -188,7 +266,7 @@
 #endif
 };
 
-static int newseg (key_t key, int shmflg, size_t size)
+static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
 {
 	int error;
 	struct shmid_kernel *shp;
@@ -197,10 +275,10 @@
 	char name[13];
 	int id;
 
-	if (size < SHMMIN || size > shm_ctlmax)
+	if (size < SHMMIN || size > ns->shm_ctlmax)
 		return -EINVAL;
 
-	if (shm_tot + numpages >= shm_ctlall)
+	if (ns->shm_tot + numpages >= ns->shm_ctlall)
 		return -ENOSPC;
 
 	shp = ipc_rcu_alloc(sizeof(*shp));
@@ -239,7 +317,7 @@
 		goto no_file;
 
 	error = -ENOSPC;
-	id = shm_addid(shp);
+	id = shm_addid(ns, shp);
 	if(id == -1) 
 		goto no_id;
 
@@ -249,15 +327,17 @@
 	shp->shm_ctim = get_seconds();
 	shp->shm_segsz = size;
 	shp->shm_nattch = 0;
-	shp->id = shm_buildid(id,shp->shm_perm.seq);
+	shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
 	shp->shm_file = file;
 	file->f_dentry->d_inode->i_ino = shp->id;
 
+	shm_file_ns(file) = get_ipc_ns(ns);
+
 	/* Hugetlb ops would have already been assigned. */
 	if (!(shmflg & SHM_HUGETLB))
 		file->f_op = &shm_file_operations;
 
-	shm_tot += numpages;
+	ns->shm_tot += numpages;
 	shm_unlock(shp);
 	return shp->id;
 
@@ -273,33 +353,36 @@
 {
 	struct shmid_kernel *shp;
 	int err, id = 0;
+	struct ipc_namespace *ns;
 
-	mutex_lock(&shm_ids.mutex);
+	ns = current->nsproxy->ipc_ns;
+
+	mutex_lock(&shm_ids(ns).mutex);
 	if (key == IPC_PRIVATE) {
-		err = newseg(key, shmflg, size);
-	} else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
+		err = newseg(ns, key, shmflg, size);
+	} else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) {
 		if (!(shmflg & IPC_CREAT))
 			err = -ENOENT;
 		else
-			err = newseg(key, shmflg, size);
+			err = newseg(ns, key, shmflg, size);
 	} else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
 		err = -EEXIST;
 	} else {
-		shp = shm_lock(id);
+		shp = shm_lock(ns, id);
 		BUG_ON(shp==NULL);
 		if (shp->shm_segsz < size)
 			err = -EINVAL;
 		else if (ipcperms(&shp->shm_perm, shmflg))
 			err = -EACCES;
 		else {
-			int shmid = shm_buildid(id, shp->shm_perm.seq);
+			int shmid = shm_buildid(ns, id, shp->shm_perm.seq);
 			err = security_shm_associate(shp, shmflg);
 			if (!err)
 				err = shmid;
 		}
 		shm_unlock(shp);
 	}
-	mutex_unlock(&shm_ids.mutex);
+	mutex_unlock(&shm_ids(ns).mutex);
 
 	return err;
 }
@@ -395,18 +478,19 @@
 	}
 }
 
-static void shm_get_stat(unsigned long *rss, unsigned long *swp) 
+static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
+		unsigned long *swp)
 {
 	int i;
 
 	*rss = 0;
 	*swp = 0;
 
-	for (i = 0; i <= shm_ids.max_id; i++) {
+	for (i = 0; i <= shm_ids(ns).max_id; i++) {
 		struct shmid_kernel *shp;
 		struct inode *inode;
 
-		shp = shm_get(i);
+		shp = shm_get(ns, i);
 		if(!shp)
 			continue;
 
@@ -430,6 +514,7 @@
 	struct shm_setbuf setbuf;
 	struct shmid_kernel *shp;
 	int err, version;
+	struct ipc_namespace *ns;
 
 	if (cmd < 0 || shmid < 0) {
 		err = -EINVAL;
@@ -437,6 +522,7 @@
 	}
 
 	version = ipc_parse_version(&cmd);
+	ns = current->nsproxy->ipc_ns;
 
 	switch (cmd) { /* replace with proc interface ? */
 	case IPC_INFO:
@@ -448,15 +534,15 @@
 			return err;
 
 		memset(&shminfo,0,sizeof(shminfo));
-		shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
-		shminfo.shmmax = shm_ctlmax;
-		shminfo.shmall = shm_ctlall;
+		shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
+		shminfo.shmmax = ns->shm_ctlmax;
+		shminfo.shmall = ns->shm_ctlall;
 
 		shminfo.shmmin = SHMMIN;
 		if(copy_shminfo_to_user (buf, &shminfo, version))
 			return -EFAULT;
 		/* reading a integer is always atomic */
-		err= shm_ids.max_id;
+		err= shm_ids(ns).max_id;
 		if(err<0)
 			err = 0;
 		goto out;
@@ -470,14 +556,14 @@
 			return err;
 
 		memset(&shm_info,0,sizeof(shm_info));
-		mutex_lock(&shm_ids.mutex);
-		shm_info.used_ids = shm_ids.in_use;
-		shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
-		shm_info.shm_tot = shm_tot;
+		mutex_lock(&shm_ids(ns).mutex);
+		shm_info.used_ids = shm_ids(ns).in_use;
+		shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
+		shm_info.shm_tot = ns->shm_tot;
 		shm_info.swap_attempts = 0;
 		shm_info.swap_successes = 0;
-		err = shm_ids.max_id;
-		mutex_unlock(&shm_ids.mutex);
+		err = shm_ids(ns).max_id;
+		mutex_unlock(&shm_ids(ns).mutex);
 		if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
 			err = -EFAULT;
 			goto out;
@@ -492,17 +578,17 @@
 		struct shmid64_ds tbuf;
 		int result;
 		memset(&tbuf, 0, sizeof(tbuf));
-		shp = shm_lock(shmid);
+		shp = shm_lock(ns, shmid);
 		if(shp==NULL) {
 			err = -EINVAL;
 			goto out;
 		} else if(cmd==SHM_STAT) {
 			err = -EINVAL;
-			if (shmid > shm_ids.max_id)
+			if (shmid > shm_ids(ns).max_id)
 				goto out_unlock;
-			result = shm_buildid(shmid, shp->shm_perm.seq);
+			result = shm_buildid(ns, shmid, shp->shm_perm.seq);
 		} else {
-			err = shm_checkid(shp,shmid);
+			err = shm_checkid(ns, shp,shmid);
 			if(err)
 				goto out_unlock;
 			result = 0;
@@ -534,12 +620,12 @@
 	case SHM_LOCK:
 	case SHM_UNLOCK:
 	{
-		shp = shm_lock(shmid);
+		shp = shm_lock(ns, shmid);
 		if(shp==NULL) {
 			err = -EINVAL;
 			goto out;
 		}
-		err = shm_checkid(shp,shmid);
+		err = shm_checkid(ns, shp,shmid);
 		if(err)
 			goto out_unlock;
 
@@ -590,12 +676,12 @@
 		 *	Instead we set a destroyed flag, and then blow
 		 *	the name away when the usage hits zero.
 		 */
-		mutex_lock(&shm_ids.mutex);
-		shp = shm_lock(shmid);
+		mutex_lock(&shm_ids(ns).mutex);
+		shp = shm_lock(ns, shmid);
 		err = -EINVAL;
 		if (shp == NULL) 
 			goto out_up;
-		err = shm_checkid(shp, shmid);
+		err = shm_checkid(ns, shp, shmid);
 		if(err)
 			goto out_unlock_up;
 
@@ -614,14 +700,8 @@
 		if (err)
 			goto out_unlock_up;
 
-		if (shp->shm_nattch){
-			shp->shm_perm.mode |= SHM_DEST;
-			/* Do not find it any more */
-			shp->shm_perm.key = IPC_PRIVATE;
-			shm_unlock(shp);
-		} else
-			shm_destroy (shp);
-		mutex_unlock(&shm_ids.mutex);
+		do_shm_rmid(ns, shp);
+		mutex_unlock(&shm_ids(ns).mutex);
 		goto out;
 	}
 
@@ -631,12 +711,12 @@
 			err = -EFAULT;
 			goto out;
 		}
-		mutex_lock(&shm_ids.mutex);
-		shp = shm_lock(shmid);
+		mutex_lock(&shm_ids(ns).mutex);
+		shp = shm_lock(ns, shmid);
 		err=-EINVAL;
 		if(shp==NULL)
 			goto out_up;
-		err = shm_checkid(shp,shmid);
+		err = shm_checkid(ns, shp,shmid);
 		if(err)
 			goto out_unlock_up;
 		err = audit_ipc_obj(&(shp->shm_perm));
@@ -673,7 +753,7 @@
 out_unlock_up:
 	shm_unlock(shp);
 out_up:
-	mutex_unlock(&shm_ids.mutex);
+	mutex_unlock(&shm_ids(ns).mutex);
 	goto out;
 out_unlock:
 	shm_unlock(shp);
@@ -699,6 +779,7 @@
 	unsigned long prot;
 	int acc_mode;
 	void *user_addr;
+	struct ipc_namespace *ns;
 
 	if (shmid < 0) {
 		err = -EINVAL;
@@ -737,12 +818,13 @@
 	 * We cannot rely on the fs check since SYSV IPC does have an
 	 * additional creator id...
 	 */
-	shp = shm_lock(shmid);
+	ns = current->nsproxy->ipc_ns;
+	shp = shm_lock(ns, shmid);
 	if(shp == NULL) {
 		err = -EINVAL;
 		goto out;
 	}
-	err = shm_checkid(shp,shmid);
+	err = shm_checkid(ns, shp,shmid);
 	if (err) {
 		shm_unlock(shp);
 		goto out;
@@ -783,16 +865,16 @@
 invalid:
 	up_write(&current->mm->mmap_sem);
 
-	mutex_lock(&shm_ids.mutex);
-	shp = shm_lock(shmid);
+	mutex_lock(&shm_ids(ns).mutex);
+	shp = shm_lock(ns, shmid);
 	BUG_ON(!shp);
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_perm.mode & SHM_DEST)
-		shm_destroy (shp);
+		shm_destroy(ns, shp);
 	else
 		shm_unlock(shp);
-	mutex_unlock(&shm_ids.mutex);
+	mutex_unlock(&shm_ids(ns).mutex);
 
 	*raddr = (unsigned long) user_addr;
 	err = 0;
diff --git a/ipc/util.c b/ipc/util.c
index 67b6d17..42479e4 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -12,6 +12,9 @@
  *            Mingming Cao <cmm@us.ibm.com>
  * Mar 2006 - support for audit of ipc object properties
  *            Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ * Jun 2006 - namespaces ssupport
+ *            OpenVZ, SWsoft Inc.
+ *            Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/mm.h>
@@ -29,6 +32,7 @@
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <linux/audit.h>
+#include <linux/nsproxy.h>
 
 #include <asm/unistd.h>
 
@@ -37,10 +41,111 @@
 struct ipc_proc_iface {
 	const char *path;
 	const char *header;
-	struct ipc_ids *ids;
+	int ids;
 	int (*show)(struct seq_file *, void *);
 };
 
+struct ipc_namespace init_ipc_ns = {
+	.kref = {
+		.refcount	= ATOMIC_INIT(2),
+	},
+};
+
+#ifdef CONFIG_IPC_NS
+static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
+{
+	int err;
+	struct ipc_namespace *ns;
+
+	err = -ENOMEM;
+	ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
+	if (ns == NULL)
+		goto err_mem;
+
+	err = sem_init_ns(ns);
+	if (err)
+		goto err_sem;
+	err = msg_init_ns(ns);
+	if (err)
+		goto err_msg;
+	err = shm_init_ns(ns);
+	if (err)
+		goto err_shm;
+
+	kref_init(&ns->kref);
+	return ns;
+
+err_shm:
+	msg_exit_ns(ns);
+err_msg:
+	sem_exit_ns(ns);
+err_sem:
+	kfree(ns);
+err_mem:
+	return ERR_PTR(err);
+}
+
+int unshare_ipcs(unsigned long unshare_flags, struct ipc_namespace **new_ipc)
+{
+	struct ipc_namespace *new;
+
+	if (unshare_flags & CLONE_NEWIPC) {
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		new = clone_ipc_ns(current->nsproxy->ipc_ns);
+		if (IS_ERR(new))
+			return PTR_ERR(new);
+
+		*new_ipc = new;
+	}
+
+	return 0;
+}
+
+int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+	struct ipc_namespace *old_ns = tsk->nsproxy->ipc_ns;
+	struct ipc_namespace *new_ns;
+	int err = 0;
+
+	if (!old_ns)
+		return 0;
+
+	get_ipc_ns(old_ns);
+
+	if (!(flags & CLONE_NEWIPC))
+		return 0;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		err = -EPERM;
+		goto out;
+	}
+
+	new_ns = clone_ipc_ns(old_ns);
+	if (!new_ns) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	tsk->nsproxy->ipc_ns = new_ns;
+out:
+	put_ipc_ns(old_ns);
+	return err;
+}
+
+void free_ipc_ns(struct kref *kref)
+{
+	struct ipc_namespace *ns;
+
+	ns = container_of(kref, struct ipc_namespace, kref);
+	sem_exit_ns(ns);
+	msg_exit_ns(ns);
+	shm_exit_ns(ns);
+	kfree(ns);
+}
+#endif
+
 /**
  *	ipc_init	-	initialise IPC subsystem
  *
@@ -67,7 +172,7 @@
  *	array itself. 
  */
  
-void __init ipc_init_ids(struct ipc_ids* ids, int size)
+void __ipc_init ipc_init_ids(struct ipc_ids* ids, int size)
 {
 	int i;
 
@@ -110,8 +215,7 @@
  *	@show: show routine.
  */
 void __init ipc_init_proc_interface(const char *path, const char *header,
-				    struct ipc_ids *ids,
-				    int (*show)(struct seq_file *, void *))
+		int ids, int (*show)(struct seq_file *, void *))
 {
 	struct proc_dir_entry *pde;
 	struct ipc_proc_iface *iface;
@@ -635,6 +739,9 @@
 	struct ipc_proc_iface *iface = s->private;
 	struct kern_ipc_perm *ipc = it;
 	loff_t p;
+	struct ipc_ids *ids;
+
+	ids = current->nsproxy->ipc_ns->ids[iface->ids];
 
 	/* If we had an ipc id locked before, unlock it */
 	if (ipc && ipc != SEQ_START_TOKEN)
@@ -644,8 +751,8 @@
 	 * p = *pos - 1 (because id 0 starts at position 1)
 	 *          + 1 (because we increment the position by one)
 	 */
-	for (p = *pos; p <= iface->ids->max_id; p++) {
-		if ((ipc = ipc_lock(iface->ids, p)) != NULL) {
+	for (p = *pos; p <= ids->max_id; p++) {
+		if ((ipc = ipc_lock(ids, p)) != NULL) {
 			*pos = p + 1;
 			return ipc;
 		}
@@ -664,12 +771,15 @@
 	struct ipc_proc_iface *iface = s->private;
 	struct kern_ipc_perm *ipc;
 	loff_t p;
+	struct ipc_ids *ids;
+
+	ids = current->nsproxy->ipc_ns->ids[iface->ids];
 
 	/*
 	 * Take the lock - this will be released by the corresponding
 	 * call to stop().
 	 */
-	mutex_lock(&iface->ids->mutex);
+	mutex_lock(&ids->mutex);
 
 	/* pos < 0 is invalid */
 	if (*pos < 0)
@@ -680,8 +790,8 @@
 		return SEQ_START_TOKEN;
 
 	/* Find the (pos-1)th ipc */
-	for (p = *pos - 1; p <= iface->ids->max_id; p++) {
-		if ((ipc = ipc_lock(iface->ids, p)) != NULL) {
+	for (p = *pos - 1; p <= ids->max_id; p++) {
+		if ((ipc = ipc_lock(ids, p)) != NULL) {
 			*pos = p + 1;
 			return ipc;
 		}
@@ -693,13 +803,15 @@
 {
 	struct kern_ipc_perm *ipc = it;
 	struct ipc_proc_iface *iface = s->private;
+	struct ipc_ids *ids;
 
 	/* If we had a locked segment, release it */
 	if (ipc && ipc != SEQ_START_TOKEN)
 		ipc_unlock(ipc);
 
+	ids = current->nsproxy->ipc_ns->ids[iface->ids];
 	/* Release the lock we took in start() */
-	mutex_unlock(&iface->ids->mutex);
+	mutex_unlock(&ids->mutex);
 }
 
 static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index 0181553d..c8fd6b9 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -3,6 +3,8 @@
  * Copyright (C) 1999 Christoph Rohland
  *
  * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
+ * namespaces support.      2006 OpenVZ, SWsoft Inc.
+ *                               Pavel Emelianov <xemul@openvz.org>
  */
 
 #ifndef _IPC_UTIL_H
@@ -15,6 +17,14 @@
 void msg_init (void);
 void shm_init (void);
 
+int sem_init_ns(struct ipc_namespace *ns);
+int msg_init_ns(struct ipc_namespace *ns);
+int shm_init_ns(struct ipc_namespace *ns);
+
+void sem_exit_ns(struct ipc_namespace *ns);
+void msg_exit_ns(struct ipc_namespace *ns);
+void shm_exit_ns(struct ipc_namespace *ns);
+
 struct ipc_id_ary {
 	int size;
 	struct kern_ipc_perm *p[0];
@@ -31,15 +41,23 @@
 };
 
 struct seq_file;
-void __init ipc_init_ids(struct ipc_ids* ids, int size);
+#ifdef CONFIG_IPC_NS
+#define __ipc_init
+#else
+#define __ipc_init	__init
+#endif
+void __ipc_init ipc_init_ids(struct ipc_ids *ids, int size);
 #ifdef CONFIG_PROC_FS
 void __init ipc_init_proc_interface(const char *path, const char *header,
-				    struct ipc_ids *ids,
-				    int (*show)(struct seq_file *, void *));
+		int ids, int (*show)(struct seq_file *, void *));
 #else
 #define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
 #endif
 
+#define IPC_SEM_IDS	0
+#define IPC_MSG_IDS	1
+#define IPC_SHM_IDS	2
+
 /* must be called with ids->mutex acquired.*/
 int ipc_findkey(struct ipc_ids* ids, key_t key);
 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
diff --git a/kernel/Makefile b/kernel/Makefile
index aacaafb..5e3f3b7 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,7 +8,7 @@
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
-	    hrtimer.o rwsem.o latency.o
+	    hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
@@ -48,6 +48,7 @@
 obj-$(CONFIG_SECCOMP) += seccomp.o
 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
 obj-$(CONFIG_RELAY) += relay.o
+obj-$(CONFIG_UTS_NS) += utsname.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
 
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 1a58a81..4f40d92 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -411,7 +411,6 @@
 		case AUDIT_FSGID:
 		case AUDIT_LOGINUID:
 		case AUDIT_PERS:
-		case AUDIT_ARCH:
 		case AUDIT_MSGTYPE:
 		case AUDIT_PPID:
 		case AUDIT_DEVMAJOR:
@@ -423,6 +422,14 @@
 		case AUDIT_ARG2:
 		case AUDIT_ARG3:
 			break;
+		/* arch is only allowed to be = or != */
+		case AUDIT_ARCH:
+			if ((f->op != AUDIT_NOT_EQUAL) && (f->op != AUDIT_EQUAL)
+					&& (f->op != AUDIT_NEGATE) && (f->op)) {
+				err = -EINVAL;
+				goto exit_free;
+			}
+			break;
 		case AUDIT_PERM:
 			if (f->val & ~15)
 				goto exit_free;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 1051476..42f2f11 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -278,8 +278,11 @@
 			result = audit_comparator(tsk->pid, f->op, f->val);
 			break;
 		case AUDIT_PPID:
-			if (ctx)
+			if (ctx) {
+				if (!ctx->ppid)
+					ctx->ppid = sys_getppid();
 				result = audit_comparator(ctx->ppid, f->op, f->val);
+			}
 			break;
 		case AUDIT_UID:
 			result = audit_comparator(tsk->uid, f->op, f->val);
@@ -795,7 +798,8 @@
 
 	/* tsk == current */
 	context->pid = tsk->pid;
-	context->ppid = sys_getppid();	/* sic.  tsk == current in all cases */
+	if (!context->ppid)
+		context->ppid = sys_getppid();
 	context->uid = tsk->uid;
 	context->gid = tsk->gid;
 	context->euid = tsk->euid;
@@ -1137,6 +1141,7 @@
 	context->ctime      = CURRENT_TIME;
 	context->in_syscall = 1;
 	context->auditable  = !!(state == AUDIT_RECORD_CONTEXT);
+	context->ppid       = 0;
 }
 
 /**
@@ -1352,7 +1357,13 @@
 		}
 
 update_context:
-	idx = context->name_count++;
+	idx = context->name_count;
+	if (context->name_count == AUDIT_NAMES) {
+		printk(KERN_DEBUG "name_count maxed and losing %s\n",
+			found_name ?: "(null)");
+		return;
+	}
+	context->name_count++;
 #if AUDIT_DEBUG
 	context->ino_count++;
 #endif
@@ -1370,7 +1381,16 @@
 	/* A parent was not found in audit_names, so copy the inode data for the
 	 * provided parent. */
 	if (!found_name) {
-		idx = context->name_count++;
+		idx = context->name_count;
+		if (context->name_count == AUDIT_NAMES) {
+			printk(KERN_DEBUG
+				"name_count maxed and losing parent inode data: dev=%02x:%02x, inode=%lu",
+				MAJOR(parent->i_sb->s_dev),
+				MINOR(parent->i_sb->s_dev),
+				parent->i_ino);
+			return;
+		}
+		context->name_count++;
 #if AUDIT_DEBUG
 		context->ino_count++;
 #endif
diff --git a/kernel/compat.c b/kernel/compat.c
index b4fbd83..75573e5 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -26,8 +26,6 @@
 
 #include <asm/uaccess.h>
 
-extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
-
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
 	return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
diff --git a/kernel/dma.c b/kernel/dma.c
index aef0a45..2020644 100644
--- a/kernel/dma.c
+++ b/kernel/dma.c
@@ -62,6 +62,11 @@
 };
 
 
+/**
+ * request_dma - request and reserve a system DMA channel
+ * @dmanr: DMA channel number
+ * @device_id: reserving device ID string, used in /proc/dma
+ */
 int request_dma(unsigned int dmanr, const char * device_id)
 {
 	if (dmanr >= MAX_DMA_CHANNELS)
@@ -76,7 +81,10 @@
 	return 0;
 } /* request_dma */
 
-
+/**
+ * free_dma - free a reserved system DMA channel
+ * @dmanr: DMA channel number
+ */
 void free_dma(unsigned int dmanr)
 {
 	if (dmanr >= MAX_DMA_CHANNELS) {
diff --git a/kernel/exit.c b/kernel/exit.c
index 3b47f26..f250a5e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -21,6 +21,7 @@
 #include <linux/tsacct_kern.h>
 #include <linux/file.h>
 #include <linux/binfmts.h>
+#include <linux/nsproxy.h>
 #include <linux/ptrace.h>
 #include <linux/profile.h>
 #include <linux/mount.h>
@@ -397,9 +398,11 @@
 	fs = init_task.fs;
 	current->fs = fs;
 	atomic_inc(&fs->count);
-	exit_namespace(current);
-	current->namespace = init_task.namespace;
-	get_namespace(current->namespace);
+
+	exit_task_namespaces(current);
+	current->nsproxy = init_task.nsproxy;
+	get_task_namespaces(current);
+
  	exit_files(current);
 	current->files = init_task.files;
 	atomic_inc(&current->files->count);
@@ -917,7 +920,6 @@
 	exit_sem(tsk);
 	__exit_files(tsk);
 	__exit_fs(tsk);
-	exit_namespace(tsk);
 	exit_thread();
 	cpuset_exit(tsk);
 	exit_keys(tsk);
@@ -932,6 +934,7 @@
 	tsk->exit_code = code;
 	proc_exit_connector(tsk);
 	exit_notify(tsk);
+	exit_task_namespaces(tsk);
 #ifdef CONFIG_NUMA
 	mpol_free(tsk->mempolicy);
 	tsk->mempolicy = NULL;
diff --git a/kernel/fork.c b/kernel/fork.c
index 89f6664..7dc6140 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -27,6 +27,7 @@
 #include <linux/binfmts.h>
 #include <linux/mman.h>
 #include <linux/fs.h>
+#include <linux/nsproxy.h>
 #include <linux/capability.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
@@ -1116,11 +1117,11 @@
 		goto bad_fork_cleanup_signal;
 	if ((retval = copy_keys(clone_flags, p)))
 		goto bad_fork_cleanup_mm;
-	if ((retval = copy_namespace(clone_flags, p)))
+	if ((retval = copy_namespaces(clone_flags, p)))
 		goto bad_fork_cleanup_keys;
 	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
 	if (retval)
-		goto bad_fork_cleanup_namespace;
+		goto bad_fork_cleanup_namespaces;
 
 	p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
 	/*
@@ -1212,7 +1213,7 @@
 		spin_unlock(&current->sighand->siglock);
 		write_unlock_irq(&tasklist_lock);
 		retval = -ERESTARTNOINTR;
-		goto bad_fork_cleanup_namespace;
+		goto bad_fork_cleanup_namespaces;
 	}
 
 	if (clone_flags & CLONE_THREAD) {
@@ -1260,8 +1261,8 @@
 	proc_fork_connector(p);
 	return p;
 
-bad_fork_cleanup_namespace:
-	exit_namespace(p);
+bad_fork_cleanup_namespaces:
+	exit_task_namespaces(p);
 bad_fork_cleanup_keys:
 	exit_keys(p);
 bad_fork_cleanup_mm:
@@ -1514,10 +1515,9 @@
  */
 static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
 {
-	struct namespace *ns = current->namespace;
+	struct namespace *ns = current->nsproxy->namespace;
 
-	if ((unshare_flags & CLONE_NEWNS) &&
-	    (ns && atomic_read(&ns->count) > 1)) {
+	if ((unshare_flags & CLONE_NEWNS) && ns) {
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
@@ -1589,6 +1589,16 @@
 	return 0;
 }
 
+#ifndef CONFIG_IPC_NS
+static inline int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns)
+{
+	if (flags & CLONE_NEWIPC)
+		return -EINVAL;
+
+	return 0;
+}
+#endif
+
 /*
  * unshare allows a process to 'unshare' part of the process
  * context which was originally shared using clone.  copy_*
@@ -1606,13 +1616,17 @@
 	struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
 	struct files_struct *fd, *new_fd = NULL;
 	struct sem_undo_list *new_ulist = NULL;
+	struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
+	struct uts_namespace *uts, *new_uts = NULL;
+	struct ipc_namespace *ipc, *new_ipc = NULL;
 
 	check_unshare_flags(&unshare_flags);
 
 	/* Return -EINVAL for all unsupported flags */
 	err = -EINVAL;
 	if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
-				CLONE_VM|CLONE_FILES|CLONE_SYSVSEM))
+				CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
+				CLONE_NEWUTS|CLONE_NEWIPC))
 		goto bad_unshare_out;
 
 	if ((err = unshare_thread(unshare_flags)))
@@ -1629,11 +1643,30 @@
 		goto bad_unshare_cleanup_vm;
 	if ((err = unshare_semundo(unshare_flags, &new_ulist)))
 		goto bad_unshare_cleanup_fd;
+	if ((err = unshare_utsname(unshare_flags, &new_uts)))
+		goto bad_unshare_cleanup_semundo;
+	if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
+		goto bad_unshare_cleanup_uts;
 
-	if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) {
+	if (new_ns || new_uts || new_ipc) {
+		old_nsproxy = current->nsproxy;
+		new_nsproxy = dup_namespaces(old_nsproxy);
+		if (!new_nsproxy) {
+			err = -ENOMEM;
+			goto bad_unshare_cleanup_ipc;
+		}
+	}
+
+	if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
+				new_uts || new_ipc) {
 
 		task_lock(current);
 
+		if (new_nsproxy) {
+			current->nsproxy = new_nsproxy;
+			new_nsproxy = old_nsproxy;
+		}
+
 		if (new_fs) {
 			fs = current->fs;
 			current->fs = new_fs;
@@ -1641,8 +1674,8 @@
 		}
 
 		if (new_ns) {
-			ns = current->namespace;
-			current->namespace = new_ns;
+			ns = current->nsproxy->namespace;
+			current->nsproxy->namespace = new_ns;
 			new_ns = ns;
 		}
 
@@ -1667,9 +1700,33 @@
 			new_fd = fd;
 		}
 
+		if (new_uts) {
+			uts = current->nsproxy->uts_ns;
+			current->nsproxy->uts_ns = new_uts;
+			new_uts = uts;
+		}
+
+		if (new_ipc) {
+			ipc = current->nsproxy->ipc_ns;
+			current->nsproxy->ipc_ns = new_ipc;
+			new_ipc = ipc;
+		}
+
 		task_unlock(current);
 	}
 
+	if (new_nsproxy)
+		put_nsproxy(new_nsproxy);
+
+bad_unshare_cleanup_ipc:
+	if (new_ipc)
+		put_ipc_ns(new_ipc);
+
+bad_unshare_cleanup_uts:
+	if (new_uts)
+		put_uts_ns(new_uts);
+
+bad_unshare_cleanup_semundo:
 bad_unshare_cleanup_fd:
 	if (new_fd)
 		put_files_struct(new_fd);
diff --git a/kernel/futex.c b/kernel/futex.c
index 4b6770e..4aaf919 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1527,7 +1527,7 @@
 	filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
 
 	if (signal) {
-		err = f_setown(filp, current->pid, 1);
+		err = __f_setown(filp, task_pid(current), PIDTYPE_PID, 1);
 		if (err < 0) {
 			goto error;
 		}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 736cb0b..4cf65f5 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -18,6 +18,69 @@
 #include "internals.h"
 
 /**
+ *	dynamic_irq_init - initialize a dynamically allocated irq
+ *	@irq:	irq number to initialize
+ */
+void dynamic_irq_init(unsigned int irq)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS) {
+		printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
+		WARN_ON(1);
+		return;
+	}
+
+	/* Ensure we don't have left over values from a previous use of this irq */
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock, flags);
+	desc->status = IRQ_DISABLED;
+	desc->chip = &no_irq_chip;
+	desc->handle_irq = handle_bad_irq;
+	desc->depth = 1;
+	desc->handler_data = NULL;
+	desc->chip_data = NULL;
+	desc->action = NULL;
+	desc->irq_count = 0;
+	desc->irqs_unhandled = 0;
+#ifdef CONFIG_SMP
+	desc->affinity = CPU_MASK_ALL;
+#endif
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	dynamic_irq_cleanup - cleanup a dynamically allocated irq
+ *	@irq:	irq number to initialize
+ */
+void dynamic_irq_cleanup(unsigned int irq)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS) {
+		printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
+		WARN_ON(1);
+		return;
+	}
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock, flags);
+	if (desc->action) {
+		spin_unlock_irqrestore(&desc->lock, flags);
+		printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n",
+			irq);
+		WARN_ON(1);
+		return;
+	}
+	desc->handle_irq = handle_bad_irq;
+	desc->chip = &no_irq_chip;
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+
+/**
  *	set_irq_chip - set the irq chip for an irq
  *	@irq:	irq number
  *	@chip:	pointer to irq chip description structure
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index a57ebe9..4baa3bb 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -7,17 +7,17 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&desc->lock, flags);
-	desc->move_irq = 1;
+	desc->status |= IRQ_MOVE_PENDING;
 	irq_desc[irq].pending_mask = mask;
 	spin_unlock_irqrestore(&desc->lock, flags);
 }
 
-void move_native_irq(int irq)
+void move_masked_irq(int irq)
 {
 	struct irq_desc *desc = irq_desc + irq;
 	cpumask_t tmp;
 
-	if (likely(!desc->move_irq))
+	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
 		return;
 
 	/*
@@ -28,7 +28,7 @@
 		return;
 	}
 
-	desc->move_irq = 0;
+	desc->status &= ~IRQ_MOVE_PENDING;
 
 	if (unlikely(cpus_empty(irq_desc[irq].pending_mask)))
 		return;
@@ -48,15 +48,29 @@
 	 * when an active trigger is comming in. This could
 	 * cause some ioapics to mal-function.
 	 * Being paranoid i guess!
+	 *
+	 * For correct operation this depends on the caller
+	 * masking the irqs.
 	 */
 	if (likely(!cpus_empty(tmp))) {
-		if (likely(!(desc->status & IRQ_DISABLED)))
-			desc->chip->disable(irq);
-
 		desc->chip->set_affinity(irq,tmp);
-
-		if (likely(!(desc->status & IRQ_DISABLED)))
-			desc->chip->enable(irq);
 	}
 	cpus_clear(irq_desc[irq].pending_mask);
 }
+
+void move_native_irq(int irq)
+{
+	struct irq_desc *desc = irq_desc + irq;
+
+	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
+		return;
+
+	if (likely(!(desc->status & IRQ_DISABLED)))
+		desc->chip->disable(irq);
+
+	move_masked_irq(irq);
+
+	if (likely(!(desc->status & IRQ_DISABLED)))
+		desc->chip->enable(irq);
+}
+
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index ab16a5a..eeac3e3 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -69,6 +69,15 @@
 	return in_gate_area_no_task(addr);
 }
 
+static int is_ksym_addr(unsigned long addr)
+{
+	if (all_var)
+		return is_kernel(addr);
+
+	return is_kernel_text(addr) || is_kernel_inittext(addr) ||
+		is_kernel_extratext(addr);
+}
+
 /* expand a compressed symbol data into the resulting uncompressed string,
    given the offset to where the symbol is in the compressed stream */
 static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
@@ -154,7 +163,73 @@
 	}
 	return module_kallsyms_lookup_name(name);
 }
-EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
+
+static unsigned long get_symbol_pos(unsigned long addr,
+				    unsigned long *symbolsize,
+				    unsigned long *offset)
+{
+	unsigned long symbol_start = 0, symbol_end = 0;
+	unsigned long i, low, high, mid;
+
+	/* This kernel should never had been booted. */
+	BUG_ON(!kallsyms_addresses);
+
+	/* do a binary search on the sorted kallsyms_addresses array */
+	low = 0;
+	high = kallsyms_num_syms;
+
+	while (high - low > 1) {
+		mid = (low + high) / 2;
+		if (kallsyms_addresses[mid] <= addr)
+			low = mid;
+		else
+			high = mid;
+	}
+
+	/*
+	 * search for the first aliased symbol. Aliased
+	 * symbols are symbols with the same address
+	 */
+	while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low])
+		--low;
+
+	symbol_start = kallsyms_addresses[low];
+
+	/* Search for next non-aliased symbol */
+	for (i = low + 1; i < kallsyms_num_syms; i++) {
+		if (kallsyms_addresses[i] > symbol_start) {
+			symbol_end = kallsyms_addresses[i];
+			break;
+		}
+	}
+
+	/* if we found no next symbol, we use the end of the section */
+	if (!symbol_end) {
+		if (is_kernel_inittext(addr))
+			symbol_end = (unsigned long)_einittext;
+		else if (all_var)
+			symbol_end = (unsigned long)_end;
+		else
+			symbol_end = (unsigned long)_etext;
+	}
+
+	*symbolsize = symbol_end - symbol_start;
+	*offset = addr - symbol_start;
+
+	return low;
+}
+
+/*
+ * Lookup an address but don't bother to find any names.
+ */
+int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
+				unsigned long *offset)
+{
+	if (is_ksym_addr(addr))
+		return !!get_symbol_pos(addr, symbolsize, offset);
+
+	return !!module_address_lookup(addr, symbolsize, offset, NULL);
+}
 
 /*
  * Lookup an address
@@ -168,57 +243,18 @@
 			    unsigned long *offset,
 			    char **modname, char *namebuf)
 {
-	unsigned long i, low, high, mid;
 	const char *msym;
 
-	/* This kernel should never had been booted. */
-	BUG_ON(!kallsyms_addresses);
-
 	namebuf[KSYM_NAME_LEN] = 0;
 	namebuf[0] = 0;
 
-	if ((all_var && is_kernel(addr)) ||
-	    (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
-				is_kernel_extratext(addr)))) {
-		unsigned long symbol_end = 0;
+	if (is_ksym_addr(addr)) {
+		unsigned long pos;
 
-		/* do a binary search on the sorted kallsyms_addresses array */
-		low = 0;
-		high = kallsyms_num_syms;
-
-		while (high-low > 1) {
-			mid = (low + high) / 2;
-			if (kallsyms_addresses[mid] <= addr) low = mid;
-			else high = mid;
-		}
-
-		/* search for the first aliased symbol. Aliased symbols are
-		   symbols with the same address */
-		while (low && kallsyms_addresses[low - 1] == kallsyms_addresses[low])
-			--low;
-
+		pos = get_symbol_pos(addr, symbolsize, offset);
 		/* Grab name */
-		kallsyms_expand_symbol(get_symbol_offset(low), namebuf);
-
-		/* Search for next non-aliased symbol */
-		for (i = low + 1; i < kallsyms_num_syms; i++) {
-			if (kallsyms_addresses[i] > kallsyms_addresses[low]) {
-				symbol_end = kallsyms_addresses[i];
-				break;
-			}
-		}
-
-		/* if we found no next symbol, we use the end of the section */
-		if (!symbol_end) {
-			if (is_kernel_inittext(addr))
-				symbol_end = (unsigned long)_einittext;
-			else
-				symbol_end = all_var ? (unsigned long)_end : (unsigned long)_etext;
-		}
-
-		*symbolsize = symbol_end - kallsyms_addresses[low];
+		kallsyms_expand_symbol(get_symbol_offset(pos), namebuf);
 		*modname = NULL;
-		*offset = addr - kallsyms_addresses[low];
 		return namebuf;
 	}
 
diff --git a/kernel/kmod.c b/kernel/kmod.c
index f8121b9..bb4e29d 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -18,8 +18,6 @@
 	call_usermodehelper wait flag, and remove exec_usermodehelper.
 	Rusty Russell <rusty@rustcorp.com.au>  Jan 2003
 */
-#define __KERNEL_SYSCALLS__
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/syscalls.h>
@@ -169,7 +167,8 @@
 
 	retval = -EPERM;
 	if (current->fs->root)
-		retval = execve(sub_info->path, sub_info->argv, sub_info->envp);
+		retval = kernel_execve(sub_info->path,
+				sub_info->argv, sub_info->envp);
 
 	/* Exec failed? */
 	sub_info->retval = retval;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 3f57dfd..610c837 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -37,6 +37,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/moduleloader.h>
+#include <linux/kallsyms.h>
 #include <asm-generic/sections.h>
 #include <asm/cacheflush.h>
 #include <asm/errno.h>
@@ -45,6 +46,16 @@
 #define KPROBE_HASH_BITS 6
 #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
 
+
+/*
+ * Some oddball architectures like 64bit powerpc have function descriptors
+ * so this must be overridable.
+ */
+#ifndef kprobe_lookup_name
+#define kprobe_lookup_name(name, addr) \
+	addr = ((kprobe_opcode_t *)(kallsyms_lookup_name(name)))
+#endif
+
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 static atomic_t kprobe_count;
@@ -308,7 +319,8 @@
 }
 
 /* Called with kretprobe_lock held */
-void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
+void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
+				struct hlist_head *head)
 {
 	/* remove rp inst off the rprobe_inst_table */
 	hlist_del(&ri->hlist);
@@ -320,7 +332,7 @@
 		hlist_add_head(&ri->uflist, &ri->rp->free_instances);
 	} else
 		/* Unregistering */
-		kfree(ri);
+		hlist_add_head(&ri->hlist, head);
 }
 
 struct hlist_head __kprobes *kretprobe_inst_table_head(struct task_struct *tsk)
@@ -336,18 +348,24 @@
  */
 void __kprobes kprobe_flush_task(struct task_struct *tk)
 {
-        struct kretprobe_instance *ri;
-        struct hlist_head *head;
+	struct kretprobe_instance *ri;
+	struct hlist_head *head, empty_rp;
 	struct hlist_node *node, *tmp;
 	unsigned long flags = 0;
 
+	INIT_HLIST_HEAD(&empty_rp);
 	spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(tk);
-        hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task == tk)
-                        recycle_rp_inst(ri);
-        }
+	head = kretprobe_inst_table_head(tk);
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+		if (ri->task == tk)
+			recycle_rp_inst(ri, &empty_rp);
+	}
 	spin_unlock_irqrestore(&kretprobe_lock, flags);
+
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
 }
 
 static inline void free_rp_inst(struct kretprobe *rp)
@@ -447,6 +465,21 @@
 	struct kprobe *old_p;
 	struct module *probed_mod;
 
+	/*
+	 * If we have a symbol_name argument look it up,
+	 * and add it to the address.  That way the addr
+	 * field can either be global or relative to a symbol.
+	 */
+	if (p->symbol_name) {
+		if (p->addr)
+			return -EINVAL;
+		kprobe_lookup_name(p->symbol_name, p->addr);
+	}
+
+	if (!p->addr)
+		return -EINVAL;
+	p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset);
+
 	if ((!kernel_text_address((unsigned long) p->addr)) ||
 		in_kprobes_functions((unsigned long) p->addr))
 		return -EINVAL;
@@ -488,7 +521,7 @@
 				(ARCH_INACTIVE_KPROBE_COUNT + 1))
 		register_page_fault_notifier(&kprobe_page_fault_nb);
 
-  	arch_arm_kprobe(p);
+	arch_arm_kprobe(p);
 
 out:
 	mutex_unlock(&kprobe_mutex);
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index e596525..4c05534 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -518,9 +518,9 @@
 
 static void print_kernel_version(void)
 {
-	printk("%s %.*s\n", system_utsname.release,
-		(int)strcspn(system_utsname.version, " "),
-		system_utsname.version);
+	printk("%s %.*s\n", init_utsname()->release,
+		(int)strcspn(init_utsname()->version, " "),
+		init_utsname()->version);
 }
 
 /*
diff --git a/kernel/module.c b/kernel/module.c
index 05625d5..7f60e78 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -851,6 +851,7 @@
 		printk("%s: no version for \"%s\" found: kernel tainted.\n",
 		       mod->name, symname);
 		add_taint(TAINT_FORCED_MODULE);
+		mod->taints |= TAINT_FORCED_MODULE;
 	}
 	return 1;
 }
@@ -1339,6 +1340,7 @@
 		printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
 		       mod->name, license);
 		add_taint(TAINT_PROPRIETARY_MODULE);
+		mod->taints |= TAINT_PROPRIETARY_MODULE;
 	}
 }
 
@@ -1618,6 +1620,7 @@
 	/* This is allowed: modprobe --force will invalidate it. */
 	if (!modmagic) {
 		add_taint(TAINT_FORCED_MODULE);
+		mod->taints |= TAINT_FORCED_MODULE;
 		printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
 		       mod->name);
 	} else if (!same_magic(modmagic, vermagic)) {
@@ -1711,10 +1714,14 @@
 	/* Set up license info based on the info section */
 	set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
-	if (strcmp(mod->name, "ndiswrapper") == 0)
+	if (strcmp(mod->name, "ndiswrapper") == 0) {
 		add_taint(TAINT_PROPRIETARY_MODULE);
-	if (strcmp(mod->name, "driverloader") == 0)
+		mod->taints |= TAINT_PROPRIETARY_MODULE;
+	}
+	if (strcmp(mod->name, "driverloader") == 0) {
 		add_taint(TAINT_PROPRIETARY_MODULE);
+		mod->taints |= TAINT_PROPRIETARY_MODULE;
+	}
 
 	/* Set up MODINFO_ATTR fields */
 	setup_modinfo(mod, sechdrs, infoindex);
@@ -1760,6 +1767,7 @@
 		printk(KERN_WARNING "%s: No versions for exported symbols."
 		       " Tainting kernel.\n", mod->name);
 		add_taint(TAINT_FORCED_MODULE);
+		mod->taints |= TAINT_FORCED_MODULE;
 	}
 #endif
 
@@ -2032,7 +2040,8 @@
 	list_for_each_entry(mod, &modules, list) {
 		if (within(addr, mod->module_init, mod->init_size)
 		    || within(addr, mod->module_core, mod->core_size)) {
-			*modname = mod->name;
+			if (modname)
+				*modname = mod->name;
 			return get_ksymbol(mod, addr, size, offset);
 		}
 	}
@@ -2226,14 +2235,37 @@
 	return mod;
 }
 
+static char *taint_flags(unsigned int taints, char *buf)
+{
+	*buf = '\0';
+	if (taints) {
+		int bx;
+
+		buf[0] = '(';
+		bx = 1;
+		if (taints & TAINT_PROPRIETARY_MODULE)
+			buf[bx++] = 'P';
+		if (taints & TAINT_FORCED_MODULE)
+			buf[bx++] = 'F';
+		/*
+		 * TAINT_FORCED_RMMOD: could be added.
+		 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
+		 * apply to modules.
+		 */
+		buf[bx] = ')';
+	}
+	return buf;
+}
+
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)
 {
 	struct module *mod;
+	char buf[8];
 
 	printk("Modules linked in:");
 	list_for_each_entry(mod, &modules, list)
-		printk(" %s", mod->name);
+		printk(" %s%s", mod->name, taint_flags(mod->taints, buf));
 	printk("\n");
 }
 
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
new file mode 100644
index 0000000..6ebdb82
--- /dev/null
+++ b/kernel/nsproxy.c
@@ -0,0 +1,139 @@
+/*
+ *  Copyright (C) 2006 IBM Corporation
+ *
+ *  Author: Serge Hallyn <serue@us.ibm.com>
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License as
+ *  published by the Free Software Foundation, version 2 of the
+ *  License.
+ *
+ *  Jun 2006 - namespaces support
+ *             OpenVZ, SWsoft Inc.
+ *             Pavel Emelianov <xemul@openvz.org>
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/nsproxy.h>
+#include <linux/init_task.h>
+#include <linux/namespace.h>
+#include <linux/utsname.h>
+
+struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
+
+static inline void get_nsproxy(struct nsproxy *ns)
+{
+	atomic_inc(&ns->count);
+}
+
+void get_task_namespaces(struct task_struct *tsk)
+{
+	struct nsproxy *ns = tsk->nsproxy;
+	if (ns) {
+		get_nsproxy(ns);
+	}
+}
+
+/*
+ * creates a copy of "orig" with refcount 1.
+ * This does not grab references to the contained namespaces,
+ * so that needs to be done by dup_namespaces.
+ */
+static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
+{
+	struct nsproxy *ns;
+
+	ns = kmalloc(sizeof(struct nsproxy), GFP_KERNEL);
+	if (ns) {
+		memcpy(ns, orig, sizeof(struct nsproxy));
+		atomic_set(&ns->count, 1);
+	}
+	return ns;
+}
+
+/*
+ * copies the nsproxy, setting refcount to 1, and grabbing a
+ * reference to all contained namespaces.  Called from
+ * sys_unshare()
+ */
+struct nsproxy *dup_namespaces(struct nsproxy *orig)
+{
+	struct nsproxy *ns = clone_namespaces(orig);
+
+	if (ns) {
+		if (ns->namespace)
+			get_namespace(ns->namespace);
+		if (ns->uts_ns)
+			get_uts_ns(ns->uts_ns);
+		if (ns->ipc_ns)
+			get_ipc_ns(ns->ipc_ns);
+	}
+
+	return ns;
+}
+
+/*
+ * called from clone.  This now handles copy for nsproxy and all
+ * namespaces therein.
+ */
+int copy_namespaces(int flags, struct task_struct *tsk)
+{
+	struct nsproxy *old_ns = tsk->nsproxy;
+	struct nsproxy *new_ns;
+	int err = 0;
+
+	if (!old_ns)
+		return 0;
+
+	get_nsproxy(old_ns);
+
+	if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
+		return 0;
+
+	new_ns = clone_namespaces(old_ns);
+	if (!new_ns) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	tsk->nsproxy = new_ns;
+
+	err = copy_namespace(flags, tsk);
+	if (err)
+		goto out_ns;
+
+	err = copy_utsname(flags, tsk);
+	if (err)
+		goto out_uts;
+
+	err = copy_ipcs(flags, tsk);
+	if (err)
+		goto out_ipc;
+
+out:
+	put_nsproxy(old_ns);
+	return err;
+
+out_ipc:
+	if (new_ns->uts_ns)
+		put_uts_ns(new_ns->uts_ns);
+out_uts:
+	if (new_ns->namespace)
+		put_namespace(new_ns->namespace);
+out_ns:
+	tsk->nsproxy = old_ns;
+	kfree(new_ns);
+	goto out;
+}
+
+void free_nsproxy(struct nsproxy *ns)
+{
+		if (ns->namespace)
+			put_namespace(ns->namespace);
+		if (ns->uts_ns)
+			put_uts_ns(ns->uts_ns);
+		if (ns->ipc_ns)
+			put_ipc_ns(ns->ipc_ns);
+		kfree(ns);
+}
diff --git a/kernel/pid.c b/kernel/pid.c
index 8387e8c..b914392 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/hash.h>
+#include <linux/pspace.h>
 
 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
 static struct hlist_head *pid_hash;
@@ -33,17 +34,20 @@
 static kmem_cache_t *pid_cachep;
 
 int pid_max = PID_MAX_DEFAULT;
-int last_pid;
 
 #define RESERVED_PIDS		300
 
 int pid_max_min = RESERVED_PIDS + 1;
 int pid_max_max = PID_MAX_LIMIT;
 
-#define PIDMAP_ENTRIES		((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)
 #define BITS_PER_PAGE		(PAGE_SIZE*8)
 #define BITS_PER_PAGE_MASK	(BITS_PER_PAGE-1)
-#define mk_pid(map, off)	(((map) - pidmap_array)*BITS_PER_PAGE + (off))
+
+static inline int mk_pid(struct pspace *pspace, struct pidmap *map, int off)
+{
+	return (map - pspace->pidmap)*BITS_PER_PAGE + off;
+}
+
 #define find_next_offset(map, off)					\
 		find_next_zero_bit((map)->page, BITS_PER_PAGE, off)
 
@@ -53,13 +57,12 @@
  * value does not cause lots of bitmaps to be allocated, but
  * the scheme scales to up to 4 million PIDs, runtime.
  */
-typedef struct pidmap {
-	atomic_t nr_free;
-	void *page;
-} pidmap_t;
-
-static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
-	 { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } };
+struct pspace init_pspace = {
+	.pidmap = {
+		[ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
+	},
+	.last_pid = 0
+};
 
 /*
  * Note: disable interrupts while the pidmap_lock is held as an
@@ -74,40 +77,41 @@
  * irq handlers that take it we can leave the interrupts enabled.
  * For now it is easier to be safe than to prove it can't happen.
  */
+
 static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock);
 
-static fastcall void free_pidmap(int pid)
+static fastcall void free_pidmap(struct pspace *pspace, int pid)
 {
-	pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE;
+	struct pidmap *map = pspace->pidmap + pid / BITS_PER_PAGE;
 	int offset = pid & BITS_PER_PAGE_MASK;
 
 	clear_bit(offset, map->page);
 	atomic_inc(&map->nr_free);
 }
 
-static int alloc_pidmap(void)
+static int alloc_pidmap(struct pspace *pspace)
 {
-	int i, offset, max_scan, pid, last = last_pid;
-	pidmap_t *map;
+	int i, offset, max_scan, pid, last = pspace->last_pid;
+	struct pidmap *map;
 
 	pid = last + 1;
 	if (pid >= pid_max)
 		pid = RESERVED_PIDS;
 	offset = pid & BITS_PER_PAGE_MASK;
-	map = &pidmap_array[pid/BITS_PER_PAGE];
+	map = &pspace->pidmap[pid/BITS_PER_PAGE];
 	max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
 	for (i = 0; i <= max_scan; ++i) {
 		if (unlikely(!map->page)) {
-			unsigned long page = get_zeroed_page(GFP_KERNEL);
+			void *page = kzalloc(PAGE_SIZE, GFP_KERNEL);
 			/*
 			 * Free the page if someone raced with us
 			 * installing it:
 			 */
 			spin_lock_irq(&pidmap_lock);
 			if (map->page)
-				free_page(page);
+				kfree(page);
 			else
-				map->page = (void *)page;
+				map->page = page;
 			spin_unlock_irq(&pidmap_lock);
 			if (unlikely(!map->page))
 				break;
@@ -116,11 +120,11 @@
 			do {
 				if (!test_and_set_bit(offset, map->page)) {
 					atomic_dec(&map->nr_free);
-					last_pid = pid;
+					pspace->last_pid = pid;
 					return pid;
 				}
 				offset = find_next_offset(map, offset);
-				pid = mk_pid(map, offset);
+				pid = mk_pid(pspace, map, offset);
 			/*
 			 * find_next_offset() found a bit, the pid from it
 			 * is in-bounds, and if we fell back to the last
@@ -131,16 +135,34 @@
 					(i != max_scan || pid < last ||
 					    !((last+1) & BITS_PER_PAGE_MASK)));
 		}
-		if (map < &pidmap_array[(pid_max-1)/BITS_PER_PAGE]) {
+		if (map < &pspace->pidmap[(pid_max-1)/BITS_PER_PAGE]) {
 			++map;
 			offset = 0;
 		} else {
-			map = &pidmap_array[0];
+			map = &pspace->pidmap[0];
 			offset = RESERVED_PIDS;
 			if (unlikely(last == offset))
 				break;
 		}
-		pid = mk_pid(map, offset);
+		pid = mk_pid(pspace, map, offset);
+	}
+	return -1;
+}
+
+static int next_pidmap(struct pspace *pspace, int last)
+{
+	int offset;
+	struct pidmap *map, *end;
+
+	offset = (last + 1) & BITS_PER_PAGE_MASK;
+	map = &pspace->pidmap[(last + 1)/BITS_PER_PAGE];
+	end = &pspace->pidmap[PIDMAP_ENTRIES];
+	for (; map < end; map++, offset = 0) {
+		if (unlikely(!map->page))
+			continue;
+		offset = find_next_bit((map)->page, BITS_PER_PAGE, offset);
+		if (offset < BITS_PER_PAGE)
+			return mk_pid(pspace, map, offset);
 	}
 	return -1;
 }
@@ -153,6 +175,7 @@
 	     atomic_dec_and_test(&pid->count))
 		kmem_cache_free(pid_cachep, pid);
 }
+EXPORT_SYMBOL_GPL(put_pid);
 
 static void delayed_put_pid(struct rcu_head *rhp)
 {
@@ -169,7 +192,7 @@
 	hlist_del_rcu(&pid->pid_chain);
 	spin_unlock_irqrestore(&pidmap_lock, flags);
 
-	free_pidmap(pid->nr);
+	free_pidmap(&init_pspace, pid->nr);
 	call_rcu(&pid->rcu, delayed_put_pid);
 }
 
@@ -183,7 +206,7 @@
 	if (!pid)
 		goto out;
 
-	nr = alloc_pidmap();
+	nr = alloc_pidmap(&init_pspace);
 	if (nr < 0)
 		goto out_free;
 
@@ -217,6 +240,7 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(find_pid);
 
 int fastcall attach_pid(struct task_struct *task, enum pid_type type, int nr)
 {
@@ -280,6 +304,15 @@
 
 EXPORT_SYMBOL(find_task_by_pid_type);
 
+struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
+{
+	struct pid *pid;
+	rcu_read_lock();
+	pid = get_pid(task->pids[type].pid);
+	rcu_read_unlock();
+	return pid;
+}
+
 struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)
 {
 	struct task_struct *result;
@@ -303,6 +336,26 @@
 }
 
 /*
+ * Used by proc to find the first pid that is greater then or equal to nr.
+ *
+ * If there is a pid at nr this function is exactly the same as find_pid.
+ */
+struct pid *find_ge_pid(int nr)
+{
+	struct pid *pid;
+
+	do {
+		pid = find_pid(nr);
+		if (pid)
+			break;
+		nr = next_pidmap(&init_pspace, nr);
+	} while (nr > 0);
+
+	return pid;
+}
+EXPORT_SYMBOL_GPL(find_get_pid);
+
+/*
  * The pid hash table is scaled according to the amount of memory in the
  * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
  * more.
@@ -329,10 +382,10 @@
 
 void __init pidmap_init(void)
 {
-	pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL);
+	init_pspace.pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	/* Reserve PID 0. We never call free_pidmap(0) */
-	set_bit(0, pidmap_array->page);
-	atomic_dec(&pidmap_array->nr_free);
+	set_bit(0, init_pspace.pidmap[0].page);
+	atomic_dec(&init_pspace.pidmap[0].nr_free);
 
 	pid_cachep = kmem_cache_create("pid", sizeof(struct pid),
 					__alignof__(struct pid),
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index e5ebcc1..9cbb5d1 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1,5 +1,5 @@
 /*
- * linux/kernel/posix_timers.c
+ * linux/kernel/posix-timers.c
  *
  *
  * 2002-10-15  Posix Clocks & timers
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 1b84313..99f9b7d 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -906,7 +906,7 @@
 	memset(info, 0, sizeof(struct swsusp_info));
 	info->version_code = LINUX_VERSION_CODE;
 	info->num_physpages = num_physpages;
-	memcpy(&info->uts, &system_utsname, sizeof(system_utsname));
+	memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
 	info->cpus = num_online_cpus();
 	info->image_pages = nr_copy_pages;
 	info->pages = nr_copy_pages + nr_meta_pages + 1;
@@ -1050,13 +1050,13 @@
 		reason = "kernel version";
 	if (info->num_physpages != num_physpages)
 		reason = "memory size";
-	if (strcmp(info->uts.sysname,system_utsname.sysname))
+	if (strcmp(info->uts.sysname,init_utsname()->sysname))
 		reason = "system type";
-	if (strcmp(info->uts.release,system_utsname.release))
+	if (strcmp(info->uts.release,init_utsname()->release))
 		reason = "kernel release";
-	if (strcmp(info->uts.version,system_utsname.version))
+	if (strcmp(info->uts.version,init_utsname()->version))
 		reason = "version";
-	if (strcmp(info->uts.machine,system_utsname.machine))
+	if (strcmp(info->uts.machine,init_utsname()->machine))
 		reason = "machine";
 	if (reason) {
 		printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 523e464..26bb5ff 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -71,9 +71,6 @@
 static int blimit = 10;
 static int qhimark = 10000;
 static int qlowmark = 100;
-#ifdef CONFIG_SMP
-static int rsinterval = 1000;
-#endif
 
 static atomic_t rcu_barrier_cpu_count;
 static DEFINE_MUTEX(rcu_barrier_mutex);
@@ -86,8 +83,8 @@
 	int cpu;
 	cpumask_t cpumask;
 	set_need_resched();
-	if (unlikely(rdp->qlen - rdp->last_rs_qlen > rsinterval)) {
-		rdp->last_rs_qlen = rdp->qlen;
+	if (unlikely(!rcp->signaled)) {
+		rcp->signaled = 1;
 		/*
 		 * Don't send IPI to itself. With irqs disabled,
 		 * rdp->cpu is the current cpu.
@@ -301,6 +298,7 @@
 		smp_mb();
 		cpus_andnot(rcp->cpumask, cpu_online_map, nohz_cpu_mask);
 
+		rcp->signaled = 0;
 	}
 }
 
@@ -628,9 +626,6 @@
 module_param(blimit, int, 0);
 module_param(qhimark, int, 0);
 module_param(qlowmark, int, 0);
-#ifdef CONFIG_SMP
-module_param(rsinterval, int, 0);
-#endif
 EXPORT_SYMBOL_GPL(rcu_batches_completed);
 EXPORT_SYMBOL_GPL(rcu_batches_completed_bh);
 EXPORT_SYMBOL_GPL(call_rcu);
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 4f2c427..e2bda18 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -15,9 +15,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation, 2005
+ * Copyright (C) IBM Corporation, 2005, 2006
  *
  * Authors: Paul E. McKenney <paulmck@us.ibm.com>
+ *          Josh Triplett <josh@freedesktop.org>
  *
  * See also:  Documentation/RCU/torture.txt
  */
@@ -44,19 +45,25 @@
 #include <linux/delay.h>
 #include <linux/byteorder/swabb.h>
 #include <linux/stat.h>
+#include <linux/srcu.h>
 
 MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and "
+              "Josh Triplett <josh@freedesktop.org>");
 
-static int nreaders = -1;	/* # reader threads, defaults to 4*ncpus */
+static int nreaders = -1;	/* # reader threads, defaults to 2*ncpus */
+static int nfakewriters = 4;	/* # fake writer threads */
 static int stat_interval;	/* Interval between stats, in seconds. */
 				/*  Defaults to "only at end of test". */
 static int verbose;		/* Print more debug info. */
 static int test_no_idle_hz;	/* Test RCU's support for tickless idle CPUs. */
 static int shuffle_interval = 5; /* Interval between shuffles (in sec)*/
-static char *torture_type = "rcu"; /* What to torture. */
+static char *torture_type = "rcu"; /* What RCU implementation to torture. */
 
 module_param(nreaders, int, 0);
 MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
+module_param(nfakewriters, int, 0);
+MODULE_PARM_DESC(nfakewriters, "Number of RCU fake writer threads");
 module_param(stat_interval, int, 0);
 MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
 module_param(verbose, bool, 0);
@@ -66,7 +73,7 @@
 module_param(shuffle_interval, int, 0);
 MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles");
 module_param(torture_type, charp, 0);
-MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh)");
+MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, srcu)");
 
 #define TORTURE_FLAG "-torture:"
 #define PRINTK_STRING(s) \
@@ -80,6 +87,7 @@
 
 static int nrealreaders;
 static struct task_struct *writer_task;
+static struct task_struct **fakewriter_tasks;
 static struct task_struct **reader_tasks;
 static struct task_struct *stats_task;
 static struct task_struct *shuffler_task;
@@ -104,11 +112,12 @@
 static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
 	{ 0 };
 static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
-atomic_t n_rcu_torture_alloc;
-atomic_t n_rcu_torture_alloc_fail;
-atomic_t n_rcu_torture_free;
-atomic_t n_rcu_torture_mberror;
-atomic_t n_rcu_torture_error;
+static atomic_t n_rcu_torture_alloc;
+static atomic_t n_rcu_torture_alloc_fail;
+static atomic_t n_rcu_torture_free;
+static atomic_t n_rcu_torture_mberror;
+static atomic_t n_rcu_torture_error;
+static struct list_head rcu_torture_removed;
 
 /*
  * Allocate an element from the rcu_tortures pool.
@@ -145,7 +154,7 @@
 
 struct rcu_random_state {
 	unsigned long rrs_state;
-	unsigned long rrs_count;
+	long rrs_count;
 };
 
 #define RCU_RANDOM_MULT 39916801  /* prime */
@@ -158,7 +167,7 @@
  * Crude but fast random-number generator.  Uses a linear congruential
  * generator, with occasional help from get_random_bytes().
  */
-static long
+static unsigned long
 rcu_random(struct rcu_random_state *rrsp)
 {
 	long refresh;
@@ -180,9 +189,11 @@
 	void (*init)(void);
 	void (*cleanup)(void);
 	int (*readlock)(void);
+	void (*readdelay)(struct rcu_random_state *rrsp);
 	void (*readunlock)(int idx);
 	int (*completed)(void);
 	void (*deferredfree)(struct rcu_torture *p);
+	void (*sync)(void);
 	int (*stats)(char *page);
 	char *name;
 };
@@ -198,6 +209,18 @@
 	return 0;
 }
 
+static void rcu_read_delay(struct rcu_random_state *rrsp)
+{
+	long delay;
+	const long longdelay = 200;
+
+	/* We want there to be long-running readers, but not all the time. */
+
+	delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay);
+	if (!delay)
+		udelay(longdelay);
+}
+
 static void rcu_torture_read_unlock(int idx) __releases(RCU)
 {
 	rcu_read_unlock();
@@ -239,13 +262,54 @@
 	.init = NULL,
 	.cleanup = NULL,
 	.readlock = rcu_torture_read_lock,
+	.readdelay = rcu_read_delay,
 	.readunlock = rcu_torture_read_unlock,
 	.completed = rcu_torture_completed,
 	.deferredfree = rcu_torture_deferred_free,
+	.sync = synchronize_rcu,
 	.stats = NULL,
 	.name = "rcu"
 };
 
+static void rcu_sync_torture_deferred_free(struct rcu_torture *p)
+{
+	int i;
+	struct rcu_torture *rp;
+	struct rcu_torture *rp1;
+
+	cur_ops->sync();
+	list_add(&p->rtort_free, &rcu_torture_removed);
+	list_for_each_entry_safe(rp, rp1, &rcu_torture_removed, rtort_free) {
+		i = rp->rtort_pipe_count;
+		if (i > RCU_TORTURE_PIPE_LEN)
+			i = RCU_TORTURE_PIPE_LEN;
+		atomic_inc(&rcu_torture_wcount[i]);
+		if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
+			rp->rtort_mbtest = 0;
+			list_del(&rp->rtort_free);
+			rcu_torture_free(rp);
+		}
+	}
+}
+
+static void rcu_sync_torture_init(void)
+{
+	INIT_LIST_HEAD(&rcu_torture_removed);
+}
+
+static struct rcu_torture_ops rcu_sync_ops = {
+	.init = rcu_sync_torture_init,
+	.cleanup = NULL,
+	.readlock = rcu_torture_read_lock,
+	.readdelay = rcu_read_delay,
+	.readunlock = rcu_torture_read_unlock,
+	.completed = rcu_torture_completed,
+	.deferredfree = rcu_sync_torture_deferred_free,
+	.sync = synchronize_rcu,
+	.stats = NULL,
+	.name = "rcu_sync"
+};
+
 /*
  * Definitions for rcu_bh torture testing.
  */
@@ -271,19 +335,176 @@
 	call_rcu_bh(&p->rtort_rcu, rcu_torture_cb);
 }
 
+struct rcu_bh_torture_synchronize {
+	struct rcu_head head;
+	struct completion completion;
+};
+
+static void rcu_bh_torture_wakeme_after_cb(struct rcu_head *head)
+{
+	struct rcu_bh_torture_synchronize *rcu;
+
+	rcu = container_of(head, struct rcu_bh_torture_synchronize, head);
+	complete(&rcu->completion);
+}
+
+static void rcu_bh_torture_synchronize(void)
+{
+	struct rcu_bh_torture_synchronize rcu;
+
+	init_completion(&rcu.completion);
+	call_rcu_bh(&rcu.head, rcu_bh_torture_wakeme_after_cb);
+	wait_for_completion(&rcu.completion);
+}
+
 static struct rcu_torture_ops rcu_bh_ops = {
 	.init = NULL,
 	.cleanup = NULL,
 	.readlock = rcu_bh_torture_read_lock,
+	.readdelay = rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock = rcu_bh_torture_read_unlock,
 	.completed = rcu_bh_torture_completed,
 	.deferredfree = rcu_bh_torture_deferred_free,
+	.sync = rcu_bh_torture_synchronize,
 	.stats = NULL,
 	.name = "rcu_bh"
 };
 
+static struct rcu_torture_ops rcu_bh_sync_ops = {
+	.init = rcu_sync_torture_init,
+	.cleanup = NULL,
+	.readlock = rcu_bh_torture_read_lock,
+	.readdelay = rcu_read_delay,  /* just reuse rcu's version. */
+	.readunlock = rcu_bh_torture_read_unlock,
+	.completed = rcu_bh_torture_completed,
+	.deferredfree = rcu_sync_torture_deferred_free,
+	.sync = rcu_bh_torture_synchronize,
+	.stats = NULL,
+	.name = "rcu_bh_sync"
+};
+
+/*
+ * Definitions for srcu torture testing.
+ */
+
+static struct srcu_struct srcu_ctl;
+
+static void srcu_torture_init(void)
+{
+	init_srcu_struct(&srcu_ctl);
+	rcu_sync_torture_init();
+}
+
+static void srcu_torture_cleanup(void)
+{
+	synchronize_srcu(&srcu_ctl);
+	cleanup_srcu_struct(&srcu_ctl);
+}
+
+static int srcu_torture_read_lock(void)
+{
+	return srcu_read_lock(&srcu_ctl);
+}
+
+static void srcu_read_delay(struct rcu_random_state *rrsp)
+{
+	long delay;
+	const long uspertick = 1000000 / HZ;
+	const long longdelay = 10;
+
+	/* We want there to be long-running readers, but not all the time. */
+
+	delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick);
+	if (!delay)
+		schedule_timeout_interruptible(longdelay);
+}
+
+static void srcu_torture_read_unlock(int idx)
+{
+	srcu_read_unlock(&srcu_ctl, idx);
+}
+
+static int srcu_torture_completed(void)
+{
+	return srcu_batches_completed(&srcu_ctl);
+}
+
+static void srcu_torture_synchronize(void)
+{
+	synchronize_srcu(&srcu_ctl);
+}
+
+static int srcu_torture_stats(char *page)
+{
+	int cnt = 0;
+	int cpu;
+	int idx = srcu_ctl.completed & 0x1;
+
+	cnt += sprintf(&page[cnt], "%s%s per-CPU(idx=%d):",
+		       torture_type, TORTURE_FLAG, idx);
+	for_each_possible_cpu(cpu) {
+		cnt += sprintf(&page[cnt], " %d(%d,%d)", cpu,
+			       per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx],
+			       per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]);
+	}
+	cnt += sprintf(&page[cnt], "\n");
+	return cnt;
+}
+
+static struct rcu_torture_ops srcu_ops = {
+	.init = srcu_torture_init,
+	.cleanup = srcu_torture_cleanup,
+	.readlock = srcu_torture_read_lock,
+	.readdelay = srcu_read_delay,
+	.readunlock = srcu_torture_read_unlock,
+	.completed = srcu_torture_completed,
+	.deferredfree = rcu_sync_torture_deferred_free,
+	.sync = srcu_torture_synchronize,
+	.stats = srcu_torture_stats,
+	.name = "srcu"
+};
+
+/*
+ * Definitions for sched torture testing.
+ */
+
+static int sched_torture_read_lock(void)
+{
+	preempt_disable();
+	return 0;
+}
+
+static void sched_torture_read_unlock(int idx)
+{
+	preempt_enable();
+}
+
+static int sched_torture_completed(void)
+{
+	return 0;
+}
+
+static void sched_torture_synchronize(void)
+{
+	synchronize_sched();
+}
+
+static struct rcu_torture_ops sched_ops = {
+	.init = rcu_sync_torture_init,
+	.cleanup = NULL,
+	.readlock = sched_torture_read_lock,
+	.readdelay = rcu_read_delay,  /* just reuse rcu's version. */
+	.readunlock = sched_torture_read_unlock,
+	.completed = sched_torture_completed,
+	.deferredfree = rcu_sync_torture_deferred_free,
+	.sync = sched_torture_synchronize,
+	.stats = NULL,
+	.name = "sched"
+};
+
 static struct rcu_torture_ops *torture_ops[] =
-	{ &rcu_ops, &rcu_bh_ops, NULL };
+	{ &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops, &srcu_ops,
+	  &sched_ops, NULL };
 
 /*
  * RCU torture writer kthread.  Repeatedly substitutes a new structure
@@ -330,6 +551,30 @@
 }
 
 /*
+ * RCU torture fake writer kthread.  Repeatedly calls sync, with a random
+ * delay between calls.
+ */
+static int
+rcu_torture_fakewriter(void *arg)
+{
+	DEFINE_RCU_RANDOM(rand);
+
+	VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
+	set_user_nice(current, 19);
+
+	do {
+		schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
+		udelay(rcu_random(&rand) & 0x3ff);
+		cur_ops->sync();
+	} while (!kthread_should_stop() && !fullstop);
+
+	VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task stopping");
+	while (!kthread_should_stop())
+		schedule_timeout_uninterruptible(1);
+	return 0;
+}
+
+/*
  * RCU torture reader kthread.  Repeatedly dereferences rcu_torture_current,
  * incrementing the corresponding element of the pipeline array.  The
  * counter in the element should never be greater than 1, otherwise, the
@@ -359,7 +604,7 @@
 		}
 		if (p->rtort_mbtest == 0)
 			atomic_inc(&n_rcu_torture_mberror);
-		udelay(rcu_random(&rand) & 0x7f);
+		cur_ops->readdelay(&rand);
 		preempt_disable();
 		pipe_count = p->rtort_pipe_count;
 		if (pipe_count > RCU_TORTURE_PIPE_LEN) {
@@ -483,7 +728,7 @@
 /* Shuffle tasks such that we allow @rcu_idle_cpu to become idle. A special case
  * is when @rcu_idle_cpu = -1, when we allow the tasks to run on all CPUs.
  */
-void rcu_torture_shuffle_tasks(void)
+static void rcu_torture_shuffle_tasks(void)
 {
 	cpumask_t tmp_mask = CPU_MASK_ALL;
 	int i;
@@ -507,6 +752,12 @@
 				set_cpus_allowed(reader_tasks[i], tmp_mask);
 	}
 
+	if (fakewriter_tasks != NULL) {
+		for (i = 0; i < nfakewriters; i++)
+			if (fakewriter_tasks[i])
+				set_cpus_allowed(fakewriter_tasks[i], tmp_mask);
+	}
+
 	if (writer_task)
 		set_cpus_allowed(writer_task, tmp_mask);
 
@@ -540,11 +791,12 @@
 static inline void
 rcu_torture_print_module_parms(char *tag)
 {
-	printk(KERN_ALERT "%s" TORTURE_FLAG "--- %s: nreaders=%d "
+	printk(KERN_ALERT "%s" TORTURE_FLAG
+		"--- %s: nreaders=%d nfakewriters=%d "
 		"stat_interval=%d verbose=%d test_no_idle_hz=%d "
 		"shuffle_interval = %d\n",
-		torture_type, tag, nrealreaders, stat_interval, verbose,
-		test_no_idle_hz, shuffle_interval);
+		torture_type, tag, nrealreaders, nfakewriters,
+		stat_interval, verbose, test_no_idle_hz, shuffle_interval);
 }
 
 static void
@@ -579,6 +831,19 @@
 	}
 	rcu_torture_current = NULL;
 
+	if (fakewriter_tasks != NULL) {
+		for (i = 0; i < nfakewriters; i++) {
+			if (fakewriter_tasks[i] != NULL) {
+				VERBOSE_PRINTK_STRING(
+					"Stopping rcu_torture_fakewriter task");
+				kthread_stop(fakewriter_tasks[i]);
+			}
+			fakewriter_tasks[i] = NULL;
+		}
+		kfree(fakewriter_tasks);
+		fakewriter_tasks = NULL;
+	}
+
 	if (stats_task != NULL) {
 		VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
 		kthread_stop(stats_task);
@@ -666,7 +931,25 @@
 		writer_task = NULL;
 		goto unwind;
 	}
-	reader_tasks = kmalloc(nrealreaders * sizeof(reader_tasks[0]),
+	fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
+	                           GFP_KERNEL);
+	if (fakewriter_tasks == NULL) {
+		VERBOSE_PRINTK_ERRSTRING("out of memory");
+		firsterr = -ENOMEM;
+		goto unwind;
+	}
+	for (i = 0; i < nfakewriters; i++) {
+		VERBOSE_PRINTK_STRING("Creating rcu_torture_fakewriter task");
+		fakewriter_tasks[i] = kthread_run(rcu_torture_fakewriter, NULL,
+		                                  "rcu_torture_fakewriter");
+		if (IS_ERR(fakewriter_tasks[i])) {
+			firsterr = PTR_ERR(fakewriter_tasks[i]);
+			VERBOSE_PRINTK_ERRSTRING("Failed to create fakewriter");
+			fakewriter_tasks[i] = NULL;
+			goto unwind;
+		}
+	}
+	reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]),
 			       GFP_KERNEL);
 	if (reader_tasks == NULL) {
 		VERBOSE_PRINTK_ERRSTRING("out of memory");
diff --git a/kernel/resource.c b/kernel/resource.c
index 9db38a1..6de60c1 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -193,6 +193,13 @@
 	return -EINVAL;
 }
 
+/**
+ * request_resource - request and reserve an I/O or memory resource
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns 0 for success, negative error code on error.
+ */
 int request_resource(struct resource *root, struct resource *new)
 {
 	struct resource *conflict;
@@ -205,6 +212,15 @@
 
 EXPORT_SYMBOL(request_resource);
 
+/**
+ * ____request_resource - reserve a resource, with resource conflict returned
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns:
+ * On success, NULL is returned.
+ * On error, a pointer to the conflicting resource is returned.
+ */
 struct resource *____request_resource(struct resource *root, struct resource *new)
 {
 	struct resource *conflict;
@@ -217,6 +233,10 @@
 
 EXPORT_SYMBOL(____request_resource);
 
+/**
+ * release_resource - release a previously reserved resource
+ * @old: resource pointer
+ */
 int release_resource(struct resource *old)
 {
 	int retval;
@@ -315,8 +335,16 @@
 	return -EBUSY;
 }
 
-/*
- * Allocate empty slot in the resource tree given range and alignment.
+/**
+ * allocate_resource - allocate empty slot in the resource tree given range & alignment
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ * @size: requested resource region size
+ * @min: minimum size to allocate
+ * @max: maximum size to allocate
+ * @align: alignment requested, in bytes
+ * @alignf: alignment function, optional, called if not NULL
+ * @alignf_data: arbitrary data to pass to the @alignf function
  */
 int allocate_resource(struct resource *root, struct resource *new,
 		      resource_size_t size, resource_size_t min,
@@ -407,10 +435,15 @@
 	return result;
 }
 
-/*
+/**
+ * adjust_resource - modify a resource's start and size
+ * @res: resource to modify
+ * @start: new start value
+ * @size: new size
+ *
  * Given an existing resource, change its start and size to match the
- * arguments.  Returns -EBUSY if it can't fit.  Existing children of
- * the resource are assumed to be immutable.
+ * arguments.  Returns 0 on success, -EBUSY if it can't fit.
+ * Existing children of the resource are assumed to be immutable.
  */
 int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size)
 {
@@ -456,11 +489,19 @@
  * Note how this, unlike the above, knows about
  * the IO flag meanings (busy etc).
  *
- * Request-region creates a new busy region.
+ * request_region creates a new busy region.
  *
- * Check-region returns non-zero if the area is already busy
+ * check_region returns non-zero if the area is already busy.
  *
- * Release-region releases a matching busy region.
+ * release_region releases a matching busy region.
+ */
+
+/**
+ * __request_region - create a new busy resource region
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ * @name: reserving caller's ID string
  */
 struct resource * __request_region(struct resource *parent,
 				   resource_size_t start, resource_size_t n,
@@ -497,9 +538,23 @@
 	}
 	return res;
 }
-
 EXPORT_SYMBOL(__request_region);
 
+/**
+ * __check_region - check if a resource region is busy or free
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ *
+ * Returns 0 if the region is free at the moment it is checked,
+ * returns %-EBUSY if the region is busy.
+ *
+ * NOTE:
+ * This function is deprecated because its use is racy.
+ * Even if it returns 0, a subsequent call to request_region()
+ * may fail because another driver etc. just allocated the region.
+ * Do NOT use it.  It will be removed from the kernel.
+ */
 int __check_region(struct resource *parent, resource_size_t start,
 			resource_size_t n)
 {
@@ -513,9 +568,16 @@
 	kfree(res);
 	return 0;
 }
-
 EXPORT_SYMBOL(__check_region);
 
+/**
+ * __release_region - release a previously reserved resource region
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ *
+ * The described resource region must match a currently busy region.
+ */
 void __release_region(struct resource *parent, resource_size_t start,
 			resource_size_t n)
 {
@@ -553,7 +615,6 @@
 		"<%016llx-%016llx>\n", (unsigned long long)start,
 		(unsigned long long)end);
 }
-
 EXPORT_SYMBOL(__release_region);
 
 /*
diff --git a/kernel/sched.c b/kernel/sched.c
index 2bbd948..53608a5 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1232,7 +1232,7 @@
 }
 
 /*
- * find_idlest_queue - find the idlest runqueue among the cpus in group.
+ * find_idlest_cpu - find the idlest cpu among the cpus in group.
  */
 static int
 find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
@@ -1286,21 +1286,29 @@
 	while (sd) {
 		cpumask_t span;
 		struct sched_group *group;
-		int new_cpu;
-		int weight;
+		int new_cpu, weight;
+
+		if (!(sd->flags & flag)) {
+			sd = sd->child;
+			continue;
+		}
 
 		span = sd->span;
 		group = find_idlest_group(sd, t, cpu);
-		if (!group)
-			goto nextlevel;
+		if (!group) {
+			sd = sd->child;
+			continue;
+		}
 
 		new_cpu = find_idlest_cpu(group, t, cpu);
-		if (new_cpu == -1 || new_cpu == cpu)
-			goto nextlevel;
+		if (new_cpu == -1 || new_cpu == cpu) {
+			/* Now try balancing at a lower domain level of cpu */
+			sd = sd->child;
+			continue;
+		}
 
-		/* Now try balancing at a lower domain level */
+		/* Now try balancing at a lower domain level of new_cpu */
 		cpu = new_cpu;
-nextlevel:
 		sd = NULL;
 		weight = cpus_weight(span);
 		for_each_domain(cpu, tmp) {
@@ -2533,8 +2541,14 @@
 	struct rq *busiest;
 	cpumask_t cpus = CPU_MASK_ALL;
 
+	/*
+	 * When power savings policy is enabled for the parent domain, idle
+	 * sibling can pick up load irrespective of busy siblings. In this case,
+	 * let the state of idle sibling percolate up as IDLE, instead of
+	 * portraying it as NOT_IDLE.
+	 */
 	if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER &&
-	    !sched_smt_power_savings)
+	    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 		sd_idle = 1;
 
 	schedstat_inc(sd, lb_cnt[idle]);
@@ -2630,7 +2644,7 @@
 	}
 
 	if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
-	    !sched_smt_power_savings)
+	    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 		return -1;
 	return nr_moved;
 
@@ -2646,7 +2660,7 @@
 		sd->balance_interval *= 2;
 
 	if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
-			!sched_smt_power_savings)
+	    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 		return -1;
 	return 0;
 }
@@ -2668,7 +2682,14 @@
 	int sd_idle = 0;
 	cpumask_t cpus = CPU_MASK_ALL;
 
-	if (sd->flags & SD_SHARE_CPUPOWER && !sched_smt_power_savings)
+	/*
+	 * When power savings policy is enabled for the parent domain, idle
+	 * sibling can pick up load irrespective of busy siblings. In this case,
+	 * let the state of idle sibling percolate up as IDLE, instead of
+	 * portraying it as NOT_IDLE.
+	 */
+	if (sd->flags & SD_SHARE_CPUPOWER &&
+	    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 		sd_idle = 1;
 
 	schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
@@ -2709,7 +2730,8 @@
 
 	if (!nr_moved) {
 		schedstat_inc(sd, lb_failed[NEWLY_IDLE]);
-		if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER)
+		if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
+		    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 			return -1;
 	} else
 		sd->nr_balance_failed = 0;
@@ -2719,7 +2741,7 @@
 out_balanced:
 	schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
 	if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
-					!sched_smt_power_savings)
+	    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 		return -1;
 	sd->nr_balance_failed = 0;
 
@@ -4384,7 +4406,10 @@
 
 #ifndef CONFIG_SMP
 cpumask_t cpu_online_map __read_mostly = CPU_MASK_ALL;
+EXPORT_SYMBOL(cpu_online_map);
+
 cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL;
+EXPORT_SYMBOL(cpu_possible_map);
 #endif
 
 long sched_getaffinity(pid_t pid, cpumask_t *mask)
@@ -4814,7 +4839,7 @@
  * NOTE: this function does not set the idle thread's NEED_RESCHED
  * flag, to make booting more robust.
  */
-void __devinit init_idle(struct task_struct *idle, int cpu)
+void __cpuinit init_idle(struct task_struct *idle, int cpu)
 {
 	struct rq *rq = cpu_rq(cpu);
 	unsigned long flags;
@@ -5389,7 +5414,9 @@
 	if (sd->flags & (SD_LOAD_BALANCE |
 			 SD_BALANCE_NEWIDLE |
 			 SD_BALANCE_FORK |
-			 SD_BALANCE_EXEC)) {
+			 SD_BALANCE_EXEC |
+			 SD_SHARE_CPUPOWER |
+			 SD_SHARE_PKG_RESOURCES)) {
 		if (sd->groups != sd->groups->next)
 			return 0;
 	}
@@ -5423,7 +5450,9 @@
 		pflags &= ~(SD_LOAD_BALANCE |
 				SD_BALANCE_NEWIDLE |
 				SD_BALANCE_FORK |
-				SD_BALANCE_EXEC);
+				SD_BALANCE_EXEC |
+				SD_SHARE_CPUPOWER |
+				SD_SHARE_PKG_RESOURCES);
 	}
 	if (~cflags & pflags)
 		return 0;
@@ -5445,12 +5474,18 @@
 		struct sched_domain *parent = tmp->parent;
 		if (!parent)
 			break;
-		if (sd_parent_degenerate(tmp, parent))
+		if (sd_parent_degenerate(tmp, parent)) {
 			tmp->parent = parent->parent;
+			if (parent->parent)
+				parent->parent->child = tmp;
+		}
 	}
 
-	if (sd && sd_degenerate(sd))
+	if (sd && sd_degenerate(sd)) {
 		sd = sd->parent;
+		if (sd)
+			sd->child = NULL;
+	}
 
 	sched_domain_debug(sd, cpu);
 
@@ -5458,7 +5493,7 @@
 }
 
 /* cpus with isolated domains */
-static cpumask_t __devinitdata cpu_isolated_map = CPU_MASK_NONE;
+static cpumask_t __cpuinitdata cpu_isolated_map = CPU_MASK_NONE;
 
 /* Setup the mask of cpus configured for isolated domains */
 static int __init isolated_cpu_setup(char *str)
@@ -5486,15 +5521,17 @@
  * covered by the given span, and will set each group's ->cpumask correctly,
  * and ->cpu_power to 0.
  */
-static void init_sched_build_groups(struct sched_group groups[], cpumask_t span,
-				    int (*group_fn)(int cpu))
+static void
+init_sched_build_groups(struct sched_group groups[], cpumask_t span,
+			const cpumask_t *cpu_map,
+			int (*group_fn)(int cpu, const cpumask_t *cpu_map))
 {
 	struct sched_group *first = NULL, *last = NULL;
 	cpumask_t covered = CPU_MASK_NONE;
 	int i;
 
 	for_each_cpu_mask(i, span) {
-		int group = group_fn(i);
+		int group = group_fn(i, cpu_map);
 		struct sched_group *sg = &groups[group];
 		int j;
 
@@ -5505,7 +5542,7 @@
 		sg->cpu_power = 0;
 
 		for_each_cpu_mask(j, span) {
-			if (group_fn(j) != group)
+			if (group_fn(j, cpu_map) != group)
 				continue;
 
 			cpu_set(j, covered);
@@ -5972,13 +6009,15 @@
 #endif
 		);
 	if (system_state == SYSTEM_BOOTING) {
-		printk("migration_cost=");
-		for (distance = 0; distance <= max_distance; distance++) {
-			if (distance)
-				printk(",");
-			printk("%ld", (long)migration_cost[distance] / 1000);
+		if (num_online_cpus() > 1) {
+			printk("migration_cost=");
+			for (distance = 0; distance <= max_distance; distance++) {
+				if (distance)
+					printk(",");
+				printk("%ld", (long)migration_cost[distance] / 1000);
+			}
+			printk("\n");
 		}
-		printk("\n");
 	}
 	j1 = jiffies;
 	if (migration_debug)
@@ -6081,7 +6120,7 @@
 static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
 static struct sched_group sched_group_cpus[NR_CPUS];
 
-static int cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map)
 {
 	return cpu;
 }
@@ -6092,31 +6131,36 @@
  */
 #ifdef CONFIG_SCHED_MC
 static DEFINE_PER_CPU(struct sched_domain, core_domains);
-static struct sched_group *sched_group_core_bycpu[NR_CPUS];
+static struct sched_group sched_group_core[NR_CPUS];
 #endif
 
 #if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
-static int cpu_to_core_group(int cpu)
+static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map)
 {
-	return first_cpu(cpu_sibling_map[cpu]);
+	cpumask_t mask = cpu_sibling_map[cpu];
+	cpus_and(mask, mask, *cpu_map);
+	return first_cpu(mask);
 }
 #elif defined(CONFIG_SCHED_MC)
-static int cpu_to_core_group(int cpu)
+static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map)
 {
 	return cpu;
 }
 #endif
 
 static DEFINE_PER_CPU(struct sched_domain, phys_domains);
-static struct sched_group *sched_group_phys_bycpu[NR_CPUS];
+static struct sched_group sched_group_phys[NR_CPUS];
 
-static int cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu, const cpumask_t *cpu_map)
 {
 #ifdef CONFIG_SCHED_MC
 	cpumask_t mask = cpu_coregroup_map(cpu);
+	cpus_and(mask, mask, *cpu_map);
 	return first_cpu(mask);
 #elif defined(CONFIG_SCHED_SMT)
-	return first_cpu(cpu_sibling_map[cpu]);
+	cpumask_t mask = cpu_sibling_map[cpu];
+	cpus_and(mask, mask, *cpu_map);
+	return first_cpu(mask);
 #else
 	return cpu;
 #endif
@@ -6134,7 +6178,7 @@
 static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
 static struct sched_group *sched_group_allnodes_bycpu[NR_CPUS];
 
-static int cpu_to_allnodes_group(int cpu)
+static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map)
 {
 	return cpu_to_node(cpu);
 }
@@ -6166,12 +6210,11 @@
 }
 #endif
 
+#ifdef CONFIG_NUMA
 /* Free memory allocated for various sched_group structures */
 static void free_sched_groups(const cpumask_t *cpu_map)
 {
-	int cpu;
-#ifdef CONFIG_NUMA
-	int i;
+	int cpu, i;
 
 	for_each_cpu_mask(cpu, *cpu_map) {
 		struct sched_group *sched_group_allnodes
@@ -6208,19 +6251,63 @@
 		kfree(sched_group_nodes);
 		sched_group_nodes_bycpu[cpu] = NULL;
 	}
+}
+#else
+static void free_sched_groups(const cpumask_t *cpu_map)
+{
+}
 #endif
-	for_each_cpu_mask(cpu, *cpu_map) {
-		if (sched_group_phys_bycpu[cpu]) {
-			kfree(sched_group_phys_bycpu[cpu]);
-			sched_group_phys_bycpu[cpu] = NULL;
-		}
-#ifdef CONFIG_SCHED_MC
-		if (sched_group_core_bycpu[cpu]) {
-			kfree(sched_group_core_bycpu[cpu]);
-			sched_group_core_bycpu[cpu] = NULL;
-		}
-#endif
+
+/*
+ * Initialize sched groups cpu_power.
+ *
+ * cpu_power indicates the capacity of sched group, which is used while
+ * distributing the load between different sched groups in a sched domain.
+ * Typically cpu_power for all the groups in a sched domain will be same unless
+ * there are asymmetries in the topology. If there are asymmetries, group
+ * having more cpu_power will pickup more load compared to the group having
+ * less cpu_power.
+ *
+ * cpu_power will be a multiple of SCHED_LOAD_SCALE. This multiple represents
+ * the maximum number of tasks a group can handle in the presence of other idle
+ * or lightly loaded groups in the same sched domain.
+ */
+static void init_sched_groups_power(int cpu, struct sched_domain *sd)
+{
+	struct sched_domain *child;
+	struct sched_group *group;
+
+	WARN_ON(!sd || !sd->groups);
+
+	if (cpu != first_cpu(sd->groups->cpumask))
+		return;
+
+	child = sd->child;
+
+	/*
+	 * For perf policy, if the groups in child domain share resources
+	 * (for example cores sharing some portions of the cache hierarchy
+	 * or SMT), then set this domain groups cpu_power such that each group
+	 * can handle only one task, when there are other idle groups in the
+	 * same sched domain.
+	 */
+	if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
+		       (child->flags &
+			(SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)))) {
+		sd->groups->cpu_power = SCHED_LOAD_SCALE;
+		return;
 	}
+
+	sd->groups->cpu_power = 0;
+
+	/*
+	 * add cpu_power of each child group to this groups cpu_power
+	 */
+	group = child->groups;
+	do {
+		sd->groups->cpu_power += group->cpu_power;
+		group = group->next;
+	} while (group != child->groups);
 }
 
 /*
@@ -6230,10 +6317,7 @@
 static int build_sched_domains(const cpumask_t *cpu_map)
 {
 	int i;
-	struct sched_group *sched_group_phys = NULL;
-#ifdef CONFIG_SCHED_MC
-	struct sched_group *sched_group_core = NULL;
-#endif
+	struct sched_domain *sd;
 #ifdef CONFIG_NUMA
 	struct sched_group **sched_group_nodes = NULL;
 	struct sched_group *sched_group_allnodes = NULL;
@@ -6265,9 +6349,10 @@
 				> SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
 			if (!sched_group_allnodes) {
 				sched_group_allnodes
-					= kmalloc(sizeof(struct sched_group)
-							* MAX_NUMNODES,
-						  GFP_KERNEL);
+					= kmalloc_node(sizeof(struct sched_group)
+						  	* MAX_NUMNODES,
+						  GFP_KERNEL,
+						  cpu_to_node(i));
 				if (!sched_group_allnodes) {
 					printk(KERN_WARNING
 					"Can not alloc allnodes sched group\n");
@@ -6279,7 +6364,7 @@
 			sd = &per_cpu(allnodes_domains, i);
 			*sd = SD_ALLNODES_INIT;
 			sd->span = *cpu_map;
-			group = cpu_to_allnodes_group(i);
+			group = cpu_to_allnodes_group(i, cpu_map);
 			sd->groups = &sched_group_allnodes[group];
 			p = sd;
 		} else
@@ -6289,60 +6374,42 @@
 		*sd = SD_NODE_INIT;
 		sd->span = sched_domain_node_span(cpu_to_node(i));
 		sd->parent = p;
+		if (p)
+			p->child = sd;
 		cpus_and(sd->span, sd->span, *cpu_map);
 #endif
 
-		if (!sched_group_phys) {
-			sched_group_phys
-				= kmalloc(sizeof(struct sched_group) * NR_CPUS,
-					  GFP_KERNEL);
-			if (!sched_group_phys) {
-				printk (KERN_WARNING "Can not alloc phys sched"
-						     "group\n");
-				goto error;
-			}
-			sched_group_phys_bycpu[i] = sched_group_phys;
-		}
-
 		p = sd;
 		sd = &per_cpu(phys_domains, i);
-		group = cpu_to_phys_group(i);
+		group = cpu_to_phys_group(i, cpu_map);
 		*sd = SD_CPU_INIT;
 		sd->span = nodemask;
 		sd->parent = p;
+		if (p)
+			p->child = sd;
 		sd->groups = &sched_group_phys[group];
 
 #ifdef CONFIG_SCHED_MC
-		if (!sched_group_core) {
-			sched_group_core
-				= kmalloc(sizeof(struct sched_group) * NR_CPUS,
-					  GFP_KERNEL);
-			if (!sched_group_core) {
-				printk (KERN_WARNING "Can not alloc core sched"
-						     "group\n");
-				goto error;
-			}
-			sched_group_core_bycpu[i] = sched_group_core;
-		}
-
 		p = sd;
 		sd = &per_cpu(core_domains, i);
-		group = cpu_to_core_group(i);
+		group = cpu_to_core_group(i, cpu_map);
 		*sd = SD_MC_INIT;
 		sd->span = cpu_coregroup_map(i);
 		cpus_and(sd->span, sd->span, *cpu_map);
 		sd->parent = p;
+		p->child = sd;
 		sd->groups = &sched_group_core[group];
 #endif
 
 #ifdef CONFIG_SCHED_SMT
 		p = sd;
 		sd = &per_cpu(cpu_domains, i);
-		group = cpu_to_cpu_group(i);
+		group = cpu_to_cpu_group(i, cpu_map);
 		*sd = SD_SIBLING_INIT;
 		sd->span = cpu_sibling_map[i];
 		cpus_and(sd->span, sd->span, *cpu_map);
 		sd->parent = p;
+		p->child = sd;
 		sd->groups = &sched_group_cpus[group];
 #endif
 	}
@@ -6356,7 +6423,7 @@
 			continue;
 
 		init_sched_build_groups(sched_group_cpus, this_sibling_map,
-						&cpu_to_cpu_group);
+					cpu_map, &cpu_to_cpu_group);
 	}
 #endif
 
@@ -6368,7 +6435,7 @@
 		if (i != first_cpu(this_core_map))
 			continue;
 		init_sched_build_groups(sched_group_core, this_core_map,
-					&cpu_to_core_group);
+					cpu_map, &cpu_to_core_group);
 	}
 #endif
 
@@ -6382,14 +6449,14 @@
 			continue;
 
 		init_sched_build_groups(sched_group_phys, nodemask,
-						&cpu_to_phys_group);
+					cpu_map, &cpu_to_phys_group);
 	}
 
 #ifdef CONFIG_NUMA
 	/* Set up node groups */
 	if (sched_group_allnodes)
 		init_sched_build_groups(sched_group_allnodes, *cpu_map,
-					&cpu_to_allnodes_group);
+					cpu_map, &cpu_to_allnodes_group);
 
 	for (i = 0; i < MAX_NUMNODES; i++) {
 		/* Set up node groups */
@@ -6461,72 +6528,20 @@
 	/* Calculate CPU power for physical packages and nodes */
 #ifdef CONFIG_SCHED_SMT
 	for_each_cpu_mask(i, *cpu_map) {
-		struct sched_domain *sd;
 		sd = &per_cpu(cpu_domains, i);
-		sd->groups->cpu_power = SCHED_LOAD_SCALE;
+		init_sched_groups_power(i, sd);
 	}
 #endif
 #ifdef CONFIG_SCHED_MC
 	for_each_cpu_mask(i, *cpu_map) {
-		int power;
-		struct sched_domain *sd;
 		sd = &per_cpu(core_domains, i);
-		if (sched_smt_power_savings)
-			power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask);
-		else
-			power = SCHED_LOAD_SCALE + (cpus_weight(sd->groups->cpumask)-1)
-					    * SCHED_LOAD_SCALE / 10;
-		sd->groups->cpu_power = power;
+		init_sched_groups_power(i, sd);
 	}
 #endif
 
 	for_each_cpu_mask(i, *cpu_map) {
-		struct sched_domain *sd;
-#ifdef CONFIG_SCHED_MC
 		sd = &per_cpu(phys_domains, i);
-		if (i != first_cpu(sd->groups->cpumask))
-			continue;
-
-		sd->groups->cpu_power = 0;
-		if (sched_mc_power_savings || sched_smt_power_savings) {
-			int j;
-
- 			for_each_cpu_mask(j, sd->groups->cpumask) {
-				struct sched_domain *sd1;
- 				sd1 = &per_cpu(core_domains, j);
- 				/*
- 			 	 * for each core we will add once
- 				 * to the group in physical domain
- 			 	 */
-  	 			if (j != first_cpu(sd1->groups->cpumask))
- 					continue;
-
- 				if (sched_smt_power_savings)
-   					sd->groups->cpu_power += sd1->groups->cpu_power;
- 				else
-   					sd->groups->cpu_power += SCHED_LOAD_SCALE;
-   			}
- 		} else
- 			/*
- 			 * This has to be < 2 * SCHED_LOAD_SCALE
- 			 * Lets keep it SCHED_LOAD_SCALE, so that
- 			 * while calculating NUMA group's cpu_power
- 			 * we can simply do
- 			 *  numa_group->cpu_power += phys_group->cpu_power;
- 			 *
- 			 * See "only add power once for each physical pkg"
- 			 * comment below
- 			 */
- 			sd->groups->cpu_power = SCHED_LOAD_SCALE;
-#else
-		int power;
-		sd = &per_cpu(phys_domains, i);
-		if (sched_smt_power_savings)
-			power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask);
-		else
-			power = SCHED_LOAD_SCALE;
-		sd->groups->cpu_power = power;
-#endif
+		init_sched_groups_power(i, sd);
 	}
 
 #ifdef CONFIG_NUMA
@@ -6534,7 +6549,7 @@
 		init_numa_sched_groups_power(sched_group_nodes[i]);
 
 	if (sched_group_allnodes) {
-		int group = cpu_to_allnodes_group(first_cpu(*cpu_map));
+		int group = cpu_to_allnodes_group(first_cpu(*cpu_map), cpu_map);
 		struct sched_group *sg = &sched_group_allnodes[group];
 
 		init_numa_sched_groups_power(sg);
@@ -6560,9 +6575,11 @@
 
 	return 0;
 
+#ifdef CONFIG_NUMA
 error:
 	free_sched_groups(cpu_map);
 	return -ENOMEM;
+#endif
 }
 /*
  * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
@@ -6744,11 +6761,20 @@
 
 void __init sched_init_smp(void)
 {
+	cpumask_t non_isolated_cpus;
+
 	lock_cpu_hotplug();
 	arch_init_sched_domains(&cpu_online_map);
+	cpus_andnot(non_isolated_cpus, cpu_online_map, cpu_isolated_map);
+	if (cpus_empty(non_isolated_cpus))
+		cpu_set(smp_processor_id(), non_isolated_cpus);
 	unlock_cpu_hotplug();
 	/* XXX: Theoretical race here - CPU may be hotplugged now */
 	hotcpu_notifier(update_sched_domains, 0);
+
+	/* Move init over to a non-isolated CPU */
+	if (set_cpus_allowed(current, non_isolated_cpus) < 0)
+		BUG();
 }
 #else
 void __init sched_init_smp(void)
diff --git a/kernel/signal.c b/kernel/signal.c
index fb5da6d..7ed8d53 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1055,28 +1055,44 @@
 }
 
 /*
- * kill_pg_info() sends a signal to a process group: this is what the tty
+ * kill_pgrp_info() sends a signal to a process group: this is what the tty
  * control characters do (^C, ^Z etc)
  */
 
-int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
+int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
 {
 	struct task_struct *p = NULL;
 	int retval, success;
 
-	if (pgrp <= 0)
-		return -EINVAL;
-
 	success = 0;
 	retval = -ESRCH;
-	do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
+	do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
 		int err = group_send_sig_info(sig, info, p);
 		success |= !err;
 		retval = err;
-	} while_each_task_pid(pgrp, PIDTYPE_PGID, p);
+	} while_each_pid_task(pgrp, PIDTYPE_PGID, p);
 	return success ? 0 : retval;
 }
 
+int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
+{
+	int retval;
+
+	read_lock(&tasklist_lock);
+	retval = __kill_pgrp_info(sig, info, pgrp);
+	read_unlock(&tasklist_lock);
+
+	return retval;
+}
+
+int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
+{
+	if (pgrp <= 0)
+		return -EINVAL;
+
+	return __kill_pgrp_info(sig, info, find_pid(pgrp));
+}
+
 int
 kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
 {
@@ -1089,8 +1105,7 @@
 	return retval;
 }
 
-int
-kill_proc_info(int sig, struct siginfo *info, pid_t pid)
+int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
 {
 	int error;
 	int acquired_tasklist_lock = 0;
@@ -1101,7 +1116,7 @@
 		read_lock(&tasklist_lock);
 		acquired_tasklist_lock = 1;
 	}
-	p = find_task_by_pid(pid);
+	p = pid_task(pid, PIDTYPE_PID);
 	error = -ESRCH;
 	if (p)
 		error = group_send_sig_info(sig, info, p);
@@ -1111,8 +1126,18 @@
 	return error;
 }
 
-/* like kill_proc_info(), but doesn't use uid/euid of "current" */
-int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
+int
+kill_proc_info(int sig, struct siginfo *info, pid_t pid)
+{
+	int error;
+	rcu_read_lock();
+	error = kill_pid_info(sig, info, find_pid(pid));
+	rcu_read_unlock();
+	return error;
+}
+
+/* like kill_pid_info(), but doesn't use uid/euid of "current" */
+int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
 		      uid_t uid, uid_t euid, u32 secid)
 {
 	int ret = -EINVAL;
@@ -1122,7 +1147,7 @@
 		return ret;
 
 	read_lock(&tasklist_lock);
-	p = find_task_by_pid(pid);
+	p = pid_task(pid, PIDTYPE_PID);
 	if (!p) {
 		ret = -ESRCH;
 		goto out_unlock;
@@ -1146,7 +1171,7 @@
 	read_unlock(&tasklist_lock);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);
+EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1264,6 +1289,18 @@
 	return 0;
 }
 
+int kill_pgrp(struct pid *pid, int sig, int priv)
+{
+	return kill_pgrp_info(sig, __si_special(priv), pid);
+}
+EXPORT_SYMBOL(kill_pgrp);
+
+int kill_pid(struct pid *pid, int sig, int priv)
+{
+	return kill_pid_info(sig, __si_special(priv), pid);
+}
+EXPORT_SYMBOL(kill_pid);
+
 int
 kill_pg(pid_t pgrp, int sig, int priv)
 {
diff --git a/kernel/srcu.c b/kernel/srcu.c
new file mode 100644
index 0000000..3507cab
--- /dev/null
+++ b/kernel/srcu.c
@@ -0,0 +1,258 @@
+/*
+ * Sleepable Read-Copy Update mechanism for mutual exclusion.
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Paul McKenney <paulmck@us.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ * 		Documentation/RCU/ *.txt
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/percpu.h>
+#include <linux/preempt.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/srcu.h>
+
+/**
+ * init_srcu_struct - initialize a sleep-RCU structure
+ * @sp: structure to initialize.
+ *
+ * Must invoke this on a given srcu_struct before passing that srcu_struct
+ * to any other function.  Each srcu_struct represents a separate domain
+ * of SRCU protection.
+ */
+int init_srcu_struct(struct srcu_struct *sp)
+{
+	sp->completed = 0;
+	mutex_init(&sp->mutex);
+	sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
+	return (sp->per_cpu_ref ? 0 : -ENOMEM);
+}
+
+/*
+ * srcu_readers_active_idx -- returns approximate number of readers
+ *	active on the specified rank of per-CPU counters.
+ */
+
+static int srcu_readers_active_idx(struct srcu_struct *sp, int idx)
+{
+	int cpu;
+	int sum;
+
+	sum = 0;
+	for_each_possible_cpu(cpu)
+		sum += per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx];
+	return sum;
+}
+
+/**
+ * srcu_readers_active - returns approximate number of readers.
+ * @sp: which srcu_struct to count active readers (holding srcu_read_lock).
+ *
+ * Note that this is not an atomic primitive, and can therefore suffer
+ * severe errors when invoked on an active srcu_struct.  That said, it
+ * can be useful as an error check at cleanup time.
+ */
+int srcu_readers_active(struct srcu_struct *sp)
+{
+	return srcu_readers_active_idx(sp, 0) + srcu_readers_active_idx(sp, 1);
+}
+
+/**
+ * cleanup_srcu_struct - deconstruct a sleep-RCU structure
+ * @sp: structure to clean up.
+ *
+ * Must invoke this after you are finished using a given srcu_struct that
+ * was initialized via init_srcu_struct(), else you leak memory.
+ */
+void cleanup_srcu_struct(struct srcu_struct *sp)
+{
+	int sum;
+
+	sum = srcu_readers_active(sp);
+	WARN_ON(sum);  /* Leakage unless caller handles error. */
+	if (sum != 0)
+		return;
+	free_percpu(sp->per_cpu_ref);
+	sp->per_cpu_ref = NULL;
+}
+
+/**
+ * srcu_read_lock - register a new reader for an SRCU-protected structure.
+ * @sp: srcu_struct in which to register the new reader.
+ *
+ * Counts the new reader in the appropriate per-CPU element of the
+ * srcu_struct.  Must be called from process context.
+ * Returns an index that must be passed to the matching srcu_read_unlock().
+ */
+int srcu_read_lock(struct srcu_struct *sp)
+{
+	int idx;
+
+	preempt_disable();
+	idx = sp->completed & 0x1;
+	barrier();  /* ensure compiler looks -once- at sp->completed. */
+	per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]++;
+	srcu_barrier();  /* ensure compiler won't misorder critical section. */
+	preempt_enable();
+	return idx;
+}
+
+/**
+ * srcu_read_unlock - unregister a old reader from an SRCU-protected structure.
+ * @sp: srcu_struct in which to unregister the old reader.
+ * @idx: return value from corresponding srcu_read_lock().
+ *
+ * Removes the count for the old reader from the appropriate per-CPU
+ * element of the srcu_struct.  Note that this may well be a different
+ * CPU than that which was incremented by the corresponding srcu_read_lock().
+ * Must be called from process context.
+ */
+void srcu_read_unlock(struct srcu_struct *sp, int idx)
+{
+	preempt_disable();
+	srcu_barrier();  /* ensure compiler won't misorder critical section. */
+	per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--;
+	preempt_enable();
+}
+
+/**
+ * synchronize_srcu - wait for prior SRCU read-side critical-section completion
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Flip the completed counter, and wait for the old count to drain to zero.
+ * As with classic RCU, the updater must use some separate means of
+ * synchronizing concurrent updates.  Can block; must be called from
+ * process context.
+ *
+ * Note that it is illegal to call synchornize_srcu() from the corresponding
+ * SRCU read-side critical section; doing so will result in deadlock.
+ * However, it is perfectly legal to call synchronize_srcu() on one
+ * srcu_struct from some other srcu_struct's read-side critical section.
+ */
+void synchronize_srcu(struct srcu_struct *sp)
+{
+	int idx;
+
+	idx = sp->completed;
+	mutex_lock(&sp->mutex);
+
+	/*
+	 * Check to see if someone else did the work for us while we were
+	 * waiting to acquire the lock.  We need -two- advances of
+	 * the counter, not just one.  If there was but one, we might have
+	 * shown up -after- our helper's first synchronize_sched(), thus
+	 * having failed to prevent CPU-reordering races with concurrent
+	 * srcu_read_unlock()s on other CPUs (see comment below).  So we
+	 * either (1) wait for two or (2) supply the second ourselves.
+	 */
+
+	if ((sp->completed - idx) >= 2) {
+		mutex_unlock(&sp->mutex);
+		return;
+	}
+
+	synchronize_sched();  /* Force memory barrier on all CPUs. */
+
+	/*
+	 * The preceding synchronize_sched() ensures that any CPU that
+	 * sees the new value of sp->completed will also see any preceding
+	 * changes to data structures made by this CPU.  This prevents
+	 * some other CPU from reordering the accesses in its SRCU
+	 * read-side critical section to precede the corresponding
+	 * srcu_read_lock() -- ensuring that such references will in
+	 * fact be protected.
+	 *
+	 * So it is now safe to do the flip.
+	 */
+
+	idx = sp->completed & 0x1;
+	sp->completed++;
+
+	synchronize_sched();  /* Force memory barrier on all CPUs. */
+
+	/*
+	 * At this point, because of the preceding synchronize_sched(),
+	 * all srcu_read_lock() calls using the old counters have completed.
+	 * Their corresponding critical sections might well be still
+	 * executing, but the srcu_read_lock() primitives themselves
+	 * will have finished executing.
+	 */
+
+	while (srcu_readers_active_idx(sp, idx))
+		schedule_timeout_interruptible(1);
+
+	synchronize_sched();  /* Force memory barrier on all CPUs. */
+
+	/*
+	 * The preceding synchronize_sched() forces all srcu_read_unlock()
+	 * primitives that were executing concurrently with the preceding
+	 * for_each_possible_cpu() loop to have completed by this point.
+	 * More importantly, it also forces the corresponding SRCU read-side
+	 * critical sections to have also completed, and the corresponding
+	 * references to SRCU-protected data items to be dropped.
+	 *
+	 * Note:
+	 *
+	 *	Despite what you might think at first glance, the
+	 *	preceding synchronize_sched() -must- be within the
+	 *	critical section ended by the following mutex_unlock().
+	 *	Otherwise, a task taking the early exit can race
+	 *	with a srcu_read_unlock(), which might have executed
+	 *	just before the preceding srcu_readers_active() check,
+	 *	and whose CPU might have reordered the srcu_read_unlock()
+	 *	with the preceding critical section.  In this case, there
+	 *	is nothing preventing the synchronize_sched() task that is
+	 *	taking the early exit from freeing a data structure that
+	 *	is still being referenced (out of order) by the task
+	 *	doing the srcu_read_unlock().
+	 *
+	 *	Alternatively, the comparison with "2" on the early exit
+	 *	could be changed to "3", but this increases synchronize_srcu()
+	 *	latency for bulk loads.  So the current code is preferred.
+	 */
+
+	mutex_unlock(&sp->mutex);
+}
+
+/**
+ * srcu_batches_completed - return batches completed.
+ * @sp: srcu_struct on which to report batch completion.
+ *
+ * Report the number of batches, correlated with, but not necessarily
+ * precisely the same as, the number of grace periods that have elapsed.
+ */
+
+long srcu_batches_completed(struct srcu_struct *sp)
+{
+	return sp->completed;
+}
+
+EXPORT_SYMBOL_GPL(init_srcu_struct);
+EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
+EXPORT_SYMBOL_GPL(srcu_read_lock);
+EXPORT_SYMBOL_GPL(srcu_read_unlock);
+EXPORT_SYMBOL_GPL(synchronize_srcu);
+EXPORT_SYMBOL_GPL(srcu_batches_completed);
+EXPORT_SYMBOL_GPL(srcu_readers_active);
diff --git a/kernel/sys.c b/kernel/sys.c
index 2460581..98489d8 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -92,7 +92,8 @@
  */
 
 int C_A_D = 1;
-int cad_pid = 1;
+struct pid *cad_pid;
+EXPORT_SYMBOL(cad_pid);
 
 /*
  *	Notifier list for kernel code which wants to be called
@@ -152,7 +153,7 @@
 
 /*
  *	Atomic notifier chain routines.  Registration and unregistration
- *	use a mutex, and call_chain is synchronized by RCU (no locks).
+ *	use a spinlock, and call_chain is synchronized by RCU (no locks).
  */
 
 /**
@@ -221,7 +222,7 @@
  *	of the last notifier function called.
  */
  
-int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
 		unsigned long val, void *v)
 {
 	int ret;
@@ -400,6 +401,129 @@
 
 EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
 
+/*
+ *	SRCU notifier chain routines.    Registration and unregistration
+ *	use a mutex, and call_chain is synchronized by SRCU (no locks).
+ */
+
+/**
+ *	srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
+ *	@nh: Pointer to head of the SRCU notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to an SRCU notifier chain.
+ *	Must be called in process context.
+ *
+ *	Currently always returns zero.
+ */
+
+int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
+		struct notifier_block *n)
+{
+	int ret;
+
+	/*
+	 * This code gets used during boot-up, when task switching is
+	 * not yet working and interrupts must remain disabled.  At
+	 * such times we must not call mutex_lock().
+	 */
+	if (unlikely(system_state == SYSTEM_BOOTING))
+		return notifier_chain_register(&nh->head, n);
+
+	mutex_lock(&nh->mutex);
+	ret = notifier_chain_register(&nh->head, n);
+	mutex_unlock(&nh->mutex);
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
+
+/**
+ *	srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
+ *	@nh: Pointer to head of the SRCU notifier chain
+ *	@n: Entry to remove from notifier chain
+ *
+ *	Removes a notifier from an SRCU notifier chain.
+ *	Must be called from process context.
+ *
+ *	Returns zero on success or %-ENOENT on failure.
+ */
+int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
+		struct notifier_block *n)
+{
+	int ret;
+
+	/*
+	 * This code gets used during boot-up, when task switching is
+	 * not yet working and interrupts must remain disabled.  At
+	 * such times we must not call mutex_lock().
+	 */
+	if (unlikely(system_state == SYSTEM_BOOTING))
+		return notifier_chain_unregister(&nh->head, n);
+
+	mutex_lock(&nh->mutex);
+	ret = notifier_chain_unregister(&nh->head, n);
+	mutex_unlock(&nh->mutex);
+	synchronize_srcu(&nh->srcu);
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
+
+/**
+ *	srcu_notifier_call_chain - Call functions in an SRCU notifier chain
+ *	@nh: Pointer to head of the SRCU notifier chain
+ *	@val: Value passed unmodified to notifier function
+ *	@v: Pointer passed unmodified to notifier function
+ *
+ *	Calls each function in a notifier chain in turn.  The functions
+ *	run in a process context, so they are allowed to block.
+ *
+ *	If the return value of the notifier can be and'ed
+ *	with %NOTIFY_STOP_MASK then srcu_notifier_call_chain
+ *	will return immediately, with the return value of
+ *	the notifier function which halted execution.
+ *	Otherwise the return value is the return value
+ *	of the last notifier function called.
+ */
+
+int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+		unsigned long val, void *v)
+{
+	int ret;
+	int idx;
+
+	idx = srcu_read_lock(&nh->srcu);
+	ret = notifier_call_chain(&nh->head, val, v);
+	srcu_read_unlock(&nh->srcu, idx);
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
+
+/**
+ *	srcu_init_notifier_head - Initialize an SRCU notifier head
+ *	@nh: Pointer to head of the srcu notifier chain
+ *
+ *	Unlike other sorts of notifier heads, SRCU notifier heads require
+ *	dynamic initialization.  Be sure to call this routine before
+ *	calling any of the other SRCU notifier routines for this head.
+ *
+ *	If an SRCU notifier head is deallocated, it must first be cleaned
+ *	up by calling srcu_cleanup_notifier_head().  Otherwise the head's
+ *	per-cpu data (used by the SRCU mechanism) will leak.
+ */
+
+void srcu_init_notifier_head(struct srcu_notifier_head *nh)
+{
+	mutex_init(&nh->mutex);
+	if (init_srcu_struct(&nh->srcu) < 0)
+		BUG();
+	nh->head = NULL;
+}
+
+EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
+
 /**
  *	register_reboot_notifier - Register function to be called at reboot time
  *	@nb: Info about notifier function to be called
@@ -773,10 +897,9 @@
 	if (C_A_D)
 		schedule_work(&cad_work);
 	else
-		kill_proc(cad_pid, SIGINT, 1);
+		kill_cad_pid(SIGINT, 1);
 }
 	
-
 /*
  * Unprivileged users may change the real gid to the effective gid
  * or vice versa.  (BSD-style)
@@ -1655,7 +1778,7 @@
 	int errno = 0;
 
 	down_read(&uts_sem);
-	if (copy_to_user(name,&system_utsname,sizeof *name))
+	if (copy_to_user(name, utsname(), sizeof *name))
 		errno = -EFAULT;
 	up_read(&uts_sem);
 	return errno;
@@ -1673,8 +1796,8 @@
 	down_write(&uts_sem);
 	errno = -EFAULT;
 	if (!copy_from_user(tmp, name, len)) {
-		memcpy(system_utsname.nodename, tmp, len);
-		system_utsname.nodename[len] = 0;
+		memcpy(utsname()->nodename, tmp, len);
+		utsname()->nodename[len] = 0;
 		errno = 0;
 	}
 	up_write(&uts_sem);
@@ -1690,11 +1813,11 @@
 	if (len < 0)
 		return -EINVAL;
 	down_read(&uts_sem);
-	i = 1 + strlen(system_utsname.nodename);
+	i = 1 + strlen(utsname()->nodename);
 	if (i > len)
 		i = len;
 	errno = 0;
-	if (copy_to_user(name, system_utsname.nodename, i))
+	if (copy_to_user(name, utsname()->nodename, i))
 		errno = -EFAULT;
 	up_read(&uts_sem);
 	return errno;
@@ -1719,8 +1842,8 @@
 	down_write(&uts_sem);
 	errno = -EFAULT;
 	if (!copy_from_user(tmp, name, len)) {
-		memcpy(system_utsname.domainname, tmp, len);
-		system_utsname.domainname[len] = 0;
+		memcpy(utsname()->domainname, tmp, len);
+		utsname()->domainname[len] = 0;
 		errno = 0;
 	}
 	up_write(&uts_sem);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ba42694..8020fb2 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -68,7 +68,6 @@
 extern int core_uses_pid;
 extern int suid_dumpable;
 extern char core_pattern[];
-extern int cad_pid;
 extern int pid_max;
 extern int min_free_kbytes;
 extern int printk_ratelimit_jiffies;
@@ -92,13 +91,8 @@
 extern int sg_big_buff;
 #endif
 #ifdef CONFIG_SYSVIPC
-extern size_t shm_ctlmax;
-extern size_t shm_ctlall;
-extern int shm_ctlmni;
-extern int msg_ctlmax;
-extern int msg_ctlmnb;
-extern int msg_ctlmni;
-extern int sem_ctls[];
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+		void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
 #ifdef __sparc__
@@ -139,7 +133,10 @@
 		void __user *, size_t, ctl_table *, void **);
 #endif
 
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+		  void __user *buffer, size_t *lenp, loff_t *ppos);
+
+static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos);
 
 static ctl_table root_table[];
@@ -229,51 +226,100 @@
 };
 
 static ctl_table kern_table[] = {
+#ifndef CONFIG_UTS_NS
 	{
 		.ctl_name	= KERN_OSTYPE,
 		.procname	= "ostype",
-		.data		= system_utsname.sysname,
-		.maxlen		= sizeof(system_utsname.sysname),
+		.data		= init_uts_ns.name.sysname,
+		.maxlen		= sizeof(init_uts_ns.name.sysname),
 		.mode		= 0444,
-		.proc_handler	= &proc_doutsstring,
+		.proc_handler	= &proc_do_uts_string,
 		.strategy	= &sysctl_string,
 	},
 	{
 		.ctl_name	= KERN_OSRELEASE,
 		.procname	= "osrelease",
-		.data		= system_utsname.release,
-		.maxlen		= sizeof(system_utsname.release),
+		.data		= init_uts_ns.name.release,
+		.maxlen		= sizeof(init_uts_ns.name.release),
 		.mode		= 0444,
-		.proc_handler	= &proc_doutsstring,
+		.proc_handler	= &proc_do_uts_string,
 		.strategy	= &sysctl_string,
 	},
 	{
 		.ctl_name	= KERN_VERSION,
 		.procname	= "version",
-		.data		= system_utsname.version,
-		.maxlen		= sizeof(system_utsname.version),
+		.data		= init_uts_ns.name.version,
+		.maxlen		= sizeof(init_uts_ns.name.version),
 		.mode		= 0444,
-		.proc_handler	= &proc_doutsstring,
+		.proc_handler	= &proc_do_uts_string,
 		.strategy	= &sysctl_string,
 	},
 	{
 		.ctl_name	= KERN_NODENAME,
 		.procname	= "hostname",
-		.data		= system_utsname.nodename,
-		.maxlen		= sizeof(system_utsname.nodename),
+		.data		= init_uts_ns.name.nodename,
+		.maxlen		= sizeof(init_uts_ns.name.nodename),
 		.mode		= 0644,
-		.proc_handler	= &proc_doutsstring,
+		.proc_handler	= &proc_do_uts_string,
 		.strategy	= &sysctl_string,
 	},
 	{
 		.ctl_name	= KERN_DOMAINNAME,
 		.procname	= "domainname",
-		.data		= system_utsname.domainname,
-		.maxlen		= sizeof(system_utsname.domainname),
+		.data		= init_uts_ns.name.domainname,
+		.maxlen		= sizeof(init_uts_ns.name.domainname),
 		.mode		= 0644,
-		.proc_handler	= &proc_doutsstring,
+		.proc_handler	= &proc_do_uts_string,
 		.strategy	= &sysctl_string,
 	},
+#else  /* !CONFIG_UTS_NS */
+	{
+		.ctl_name	= KERN_OSTYPE,
+		.procname	= "ostype",
+		.data		= NULL,
+		/* could maybe use __NEW_UTS_LEN here? */
+		.maxlen		= FIELD_SIZEOF(struct new_utsname, sysname),
+		.mode		= 0444,
+		.proc_handler	= &proc_do_uts_string,
+		.strategy	= &sysctl_string,
+	},
+	{
+		.ctl_name	= KERN_OSRELEASE,
+		.procname	= "osrelease",
+		.data		= NULL,
+		.maxlen		= FIELD_SIZEOF(struct new_utsname, release),
+		.mode		= 0444,
+		.proc_handler	= &proc_do_uts_string,
+		.strategy	= &sysctl_string,
+	},
+	{
+		.ctl_name	= KERN_VERSION,
+		.procname	= "version",
+		.data		= NULL,
+		.maxlen		= FIELD_SIZEOF(struct new_utsname, version),
+		.mode		= 0444,
+		.proc_handler	= &proc_do_uts_string,
+		.strategy	= &sysctl_string,
+	},
+	{
+		.ctl_name	= KERN_NODENAME,
+		.procname	= "hostname",
+		.data		= NULL,
+		.maxlen		= FIELD_SIZEOF(struct new_utsname, nodename),
+		.mode		= 0644,
+		.proc_handler	= &proc_do_uts_string,
+		.strategy	= &sysctl_string,
+	},
+	{
+		.ctl_name	= KERN_DOMAINNAME,
+		.procname	= "domainname",
+		.data		= NULL,
+		.maxlen		= FIELD_SIZEOF(struct new_utsname, domainname),
+		.mode		= 0644,
+		.proc_handler	= &proc_do_uts_string,
+		.strategy	= &sysctl_string,
+	},
+#endif /* !CONFIG_UTS_NS */
 	{
 		.ctl_name	= KERN_PANIC,
 		.procname	= "panic",
@@ -432,58 +478,58 @@
 	{
 		.ctl_name	= KERN_SHMMAX,
 		.procname	= "shmmax",
-		.data		= &shm_ctlmax,
+		.data		= NULL,
 		.maxlen		= sizeof (size_t),
 		.mode		= 0644,
-		.proc_handler	= &proc_doulongvec_minmax,
+		.proc_handler	= &proc_do_ipc_string,
 	},
 	{
 		.ctl_name	= KERN_SHMALL,
 		.procname	= "shmall",
-		.data		= &shm_ctlall,
+		.data		= NULL,
 		.maxlen		= sizeof (size_t),
 		.mode		= 0644,
-		.proc_handler	= &proc_doulongvec_minmax,
+		.proc_handler	= &proc_do_ipc_string,
 	},
 	{
 		.ctl_name	= KERN_SHMMNI,
 		.procname	= "shmmni",
-		.data		= &shm_ctlmni,
+		.data		= NULL,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_do_ipc_string,
 	},
 	{
 		.ctl_name	= KERN_MSGMAX,
 		.procname	= "msgmax",
-		.data		= &msg_ctlmax,
+		.data		= NULL,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_do_ipc_string,
 	},
 	{
 		.ctl_name	= KERN_MSGMNI,
 		.procname	= "msgmni",
-		.data		= &msg_ctlmni,
+		.data		= NULL,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_do_ipc_string,
 	},
 	{
 		.ctl_name	= KERN_MSGMNB,
 		.procname	=  "msgmnb",
-		.data		= &msg_ctlmnb,
+		.data		= NULL,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_do_ipc_string,
 	},
 	{
 		.ctl_name	= KERN_SEM,
 		.procname	= "sem",
-		.data		= &sem_ctls,
+		.data		= NULL,
 		.maxlen		= 4*sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_do_ipc_string,
 	},
 #endif
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -499,10 +545,10 @@
 	{
 		.ctl_name	= KERN_CADPID,
 		.procname	= "cad_pid",
-		.data		= &cad_pid,
+		.data		= NULL,
 		.maxlen		= sizeof (int),
 		.mode		= 0600,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_do_cad_pid,
 	},
 	{
 		.ctl_name	= KERN_MAX_THREADS,
@@ -1624,6 +1670,56 @@
 	return do_rw_proc(1, file, (char __user *) buf, count, ppos);
 }
 
+static int _proc_do_string(void* data, int maxlen, int write,
+			   struct file *filp, void __user *buffer,
+			   size_t *lenp, loff_t *ppos)
+{
+	size_t len;
+	char __user *p;
+	char c;
+	
+	if (!data || !maxlen || !*lenp ||
+	    (*ppos && !write)) {
+		*lenp = 0;
+		return 0;
+	}
+	
+	if (write) {
+		len = 0;
+		p = buffer;
+		while (len < *lenp) {
+			if (get_user(c, p++))
+				return -EFAULT;
+			if (c == 0 || c == '\n')
+				break;
+			len++;
+		}
+		if (len >= maxlen)
+			len = maxlen-1;
+		if(copy_from_user(data, buffer, len))
+			return -EFAULT;
+		((char *) data)[len] = 0;
+		*ppos += *lenp;
+	} else {
+		len = strlen(data);
+		if (len > maxlen)
+			len = maxlen;
+		if (len > *lenp)
+			len = *lenp;
+		if (len)
+			if(copy_to_user(buffer, data, len))
+				return -EFAULT;
+		if (len < *lenp) {
+			if(put_user('\n', ((char __user *) buffer) + len))
+				return -EFAULT;
+			len++;
+		}
+		*lenp = len;
+		*ppos += len;
+	}
+	return 0;
+}
+
 /**
  * proc_dostring - read a string sysctl
  * @table: the sysctl table
@@ -1645,50 +1741,8 @@
 int proc_dostring(ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	size_t len;
-	char __user *p;
-	char c;
-	
-	if (!table->data || !table->maxlen || !*lenp ||
-	    (*ppos && !write)) {
-		*lenp = 0;
-		return 0;
-	}
-	
-	if (write) {
-		len = 0;
-		p = buffer;
-		while (len < *lenp) {
-			if (get_user(c, p++))
-				return -EFAULT;
-			if (c == 0 || c == '\n')
-				break;
-			len++;
-		}
-		if (len >= table->maxlen)
-			len = table->maxlen-1;
-		if(copy_from_user(table->data, buffer, len))
-			return -EFAULT;
-		((char *) table->data)[len] = 0;
-		*ppos += *lenp;
-	} else {
-		len = strlen(table->data);
-		if (len > table->maxlen)
-			len = table->maxlen;
-		if (len > *lenp)
-			len = *lenp;
-		if (len)
-			if(copy_to_user(buffer, table->data, len))
-				return -EFAULT;
-		if (len < *lenp) {
-			if(put_user('\n', ((char __user *) buffer) + len))
-				return -EFAULT;
-			len++;
-		}
-		*lenp = len;
-		*ppos += len;
-	}
-	return 0;
+	return _proc_do_string(table->data, table->maxlen, write, filp,
+			       buffer, lenp, ppos);
 }
 
 /*
@@ -1696,7 +1750,8 @@
  *	to observe. Should this be in kernel/sys.c ????
  */
  
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
+#ifndef CONFIG_UTS_NS
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	int r;
@@ -1712,6 +1767,48 @@
 	}
 	return r;
 }
+#else /* !CONFIG_UTS_NS */
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+		  void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	int r;
+	struct uts_namespace* uts_ns = current->nsproxy->uts_ns;
+	char* which;
+
+	switch (table->ctl_name) {
+	case KERN_OSTYPE:
+		which = uts_ns->name.sysname;
+		break;
+	case KERN_NODENAME:
+		which = uts_ns->name.nodename;
+		break;
+	case KERN_OSRELEASE:
+		which = uts_ns->name.release;
+		break;
+	case KERN_VERSION:
+		which = uts_ns->name.version;
+		break;
+	case KERN_DOMAINNAME:
+		which = uts_ns->name.domainname;
+		break;
+	default:
+		r = -EINVAL;
+		goto out;
+	}
+
+	if (!write) {
+		down_read(&uts_sem);
+		r=_proc_do_string(which,table->maxlen,0,filp,buffer,lenp, ppos);
+		up_read(&uts_sem);
+	} else {
+		down_write(&uts_sem);
+		r=_proc_do_string(which,table->maxlen,1,filp,buffer,lenp, ppos);
+		up_write(&uts_sem);
+	}
+ out:
+	return r;
+}
+#endif /* !CONFIG_UTS_NS */
 
 static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
 				 int *valp,
@@ -1732,8 +1829,9 @@
 	return 0;
 }
 
-static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
-		  void __user *buffer, size_t *lenp, loff_t *ppos,
+static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
+		  int write, struct file *filp, void __user *buffer,
+		  size_t *lenp, loff_t *ppos,
 		  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
 			      int write, void *data),
 		  void *data)
@@ -1746,13 +1844,13 @@
 	char buf[TMPBUFLEN], *p;
 	char __user *s = buffer;
 	
-	if (!table->data || !table->maxlen || !*lenp ||
+	if (!tbl_data || !table->maxlen || !*lenp ||
 	    (*ppos && !write)) {
 		*lenp = 0;
 		return 0;
 	}
 	
-	i = (int *) table->data;
+	i = (int *) tbl_data;
 	vleft = table->maxlen / sizeof(*i);
 	left = *lenp;
 
@@ -1841,6 +1939,16 @@
 #undef TMPBUFLEN
 }
 
+static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
+		  void __user *buffer, size_t *lenp, loff_t *ppos,
+		  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
+			      int write, void *data),
+		  void *data)
+{
+	return __do_proc_dointvec(table->data, table, write, filp,
+			buffer, lenp, ppos, conv, data);
+}
+
 /**
  * proc_dointvec - read a vector of integers
  * @table: the sysctl table
@@ -1974,7 +2082,7 @@
 				do_proc_dointvec_minmax_conv, &param);
 }
 
-static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
 				     struct file *filp,
 				     void __user *buffer,
 				     size_t *lenp, loff_t *ppos,
@@ -1988,13 +2096,13 @@
 	char buf[TMPBUFLEN], *p;
 	char __user *s = buffer;
 	
-	if (!table->data || !table->maxlen || !*lenp ||
+	if (!data || !table->maxlen || !*lenp ||
 	    (*ppos && !write)) {
 		*lenp = 0;
 		return 0;
 	}
 	
-	i = (unsigned long *) table->data;
+	i = (unsigned long *) data;
 	min = (unsigned long *) table->extra1;
 	max = (unsigned long *) table->extra2;
 	vleft = table->maxlen / sizeof(unsigned long);
@@ -2079,6 +2187,17 @@
 #undef TMPBUFLEN
 }
 
+static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+				     struct file *filp,
+				     void __user *buffer,
+				     size_t *lenp, loff_t *ppos,
+				     unsigned long convmul,
+				     unsigned long convdiv)
+{
+	return __do_proc_doulongvec_minmax(table->data, table, write,
+			filp, buffer, lenp, ppos, convmul, convdiv);
+}
+
 /**
  * proc_doulongvec_minmax - read a vector of long integers with min/max values
  * @table: the sysctl table
@@ -2267,6 +2386,71 @@
 				do_proc_dointvec_ms_jiffies_conv, NULL);
 }
 
+#ifdef CONFIG_SYSVIPC
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+		void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	void *data;
+	struct ipc_namespace *ns;
+
+	ns = current->nsproxy->ipc_ns;
+
+	switch (table->ctl_name) {
+	case KERN_SHMMAX:
+		data = &ns->shm_ctlmax;
+		goto proc_minmax;
+	case KERN_SHMALL:
+		data = &ns->shm_ctlall;
+		goto proc_minmax;
+	case KERN_SHMMNI:
+		data = &ns->shm_ctlmni;
+		break;
+	case KERN_MSGMAX:
+		data = &ns->msg_ctlmax;
+		break;
+	case KERN_MSGMNI:
+		data = &ns->msg_ctlmni;
+		break;
+	case KERN_MSGMNB:
+		data = &ns->msg_ctlmnb;
+		break;
+	case KERN_SEM:
+		data = &ns->sem_ctls;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return __do_proc_dointvec(data, table, write, filp, buffer,
+			lenp, ppos, NULL, NULL);
+proc_minmax:
+	return __do_proc_doulongvec_minmax(data, table, write, filp, buffer,
+			lenp, ppos, 1l, 1l);
+}
+#endif
+
+static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+			   void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	struct pid *new_pid;
+	pid_t tmp;
+	int r;
+
+	tmp = pid_nr(cad_pid);
+
+	r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
+			       lenp, ppos, NULL, NULL);
+	if (r || !write)
+		return r;
+
+	new_pid = find_get_pid(tmp);
+	if (!new_pid)
+		return -ESRCH;
+
+	put_pid(xchg(&cad_pid, new_pid));
+	return 0;
+}
+
 #else /* CONFIG_PROC_FS */
 
 int proc_dostring(ctl_table *table, int write, struct file *filp,
@@ -2275,12 +2459,20 @@
 	return -ENOSYS;
 }
 
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
-			    void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+		void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
+#ifdef CONFIG_SYSVIPC
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+		void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	return -ENOSYS;
+}
+#endif
+
 int proc_dointvec(ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
diff --git a/kernel/utsname.c b/kernel/utsname.c
new file mode 100644
index 0000000..c859164
--- /dev/null
+++ b/kernel/utsname.c
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (C) 2004 IBM Corporation
+ *
+ *  Author: Serge Hallyn <serue@us.ibm.com>
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License as
+ *  published by the Free Software Foundation, version 2 of the
+ *  License.
+ */
+
+#include <linux/module.h>
+#include <linux/uts.h>
+#include <linux/utsname.h>
+#include <linux/version.h>
+
+/*
+ * Clone a new ns copying an original utsname, setting refcount to 1
+ * @old_ns: namespace to clone
+ * Return NULL on error (failure to kmalloc), new ns otherwise
+ */
+static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)
+{
+	struct uts_namespace *ns;
+
+	ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
+	if (ns) {
+		memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
+		kref_init(&ns->kref);
+	}
+	return ns;
+}
+
+/*
+ * unshare the current process' utsname namespace.
+ * called only in sys_unshare()
+ */
+int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts)
+{
+	if (unshare_flags & CLONE_NEWUTS) {
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		*new_uts = clone_uts_ns(current->nsproxy->uts_ns);
+		if (!*new_uts)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/*
+ * Copy task tsk's utsname namespace, or clone it if flags
+ * specifies CLONE_NEWUTS.  In latter case, changes to the
+ * utsname of this process won't be seen by parent, and vice
+ * versa.
+ */
+int copy_utsname(int flags, struct task_struct *tsk)
+{
+	struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
+	struct uts_namespace *new_ns;
+	int err = 0;
+
+	if (!old_ns)
+		return 0;
+
+	get_uts_ns(old_ns);
+
+	if (!(flags & CLONE_NEWUTS))
+		return 0;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		err = -EPERM;
+		goto out;
+	}
+
+	new_ns = clone_uts_ns(old_ns);
+	if (!new_ns) {
+		err = -ENOMEM;
+		goto out;
+	}
+	tsk->nsproxy->uts_ns = new_ns;
+
+out:
+	put_uts_ns(old_ns);
+	return err;
+}
+
+void free_uts_ns(struct kref *kref)
+{
+	struct uts_namespace *ns;
+
+	ns = container_of(kref, struct uts_namespace, kref);
+	kfree(ns);
+}
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 835fe28..cfc737b 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -34,7 +34,7 @@
  * possible cpu).
  *
  * The sequence counters are for flush_scheduled_work().  It wants to wait
- * until until all currently-scheduled works are completed, but it doesn't
+ * until all currently-scheduled works are completed, but it doesn't
  * want to be livelocked by new, incoming ones.  So it waits until
  * remove_sequence is >= the insert_sequence which pertained when
  * flush_scheduled_work() was called.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index f9ae75c..756a908 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -384,3 +384,17 @@
 	  at boot time (you probably don't).
 	  Say M if you want the RCU torture tests to build as a module.
 	  Say N if you are unsure.
+
+config LKDTM
+	tristate "Linux Kernel Dump Test Tool Module"
+	depends on KPROBES
+	default n
+	help
+	This module enables testing of the different dumping mechanisms by
+	inducing system failures at predefined crash points.
+	If you don't need it: say N
+	Choose M here to compile this code as a module. The module will be
+	called lkdtm.
+
+	Documentation on how to use the module can be found in
+	drivers/misc/lkdtm.c
diff --git a/lib/Makefile b/lib/Makefile
index ddf3e67..b036175 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -2,7 +2,7 @@
 # Makefile for some libs needed in the kernel.
 #
 
-lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
+lib-y := ctype.o string.o vsprintf.o cmdline.o \
 	 bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
 	 idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
 	 sha1.o
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 3a67dc5..7a2a73f 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -43,3 +43,19 @@
 	return cpu;
 }
 EXPORT_SYMBOL(__any_online_cpu);
+
+#if MAX_NUMNODES > 1
+/*
+ * Find the highest possible node id.
+ */
+int highest_possible_node_id(void)
+{
+	unsigned int node;
+	unsigned int highest = 0;
+
+	for_each_node_mask(node, node_possible_map)
+		highest = node;
+	return highest;
+}
+EXPORT_SYMBOL(highest_possible_node_id);
+#endif
diff --git a/lib/errno.c b/lib/errno.c
deleted file mode 100644
index 41cb9d7..0000000
--- a/lib/errno.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- *  linux/lib/errno.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-int errno;
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 71338b4..75ae68c 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -14,11 +14,13 @@
 #include <linux/genalloc.h>
 
 
-/*
- * Create a new special memory pool.
- *
+/**
+ * gen_pool_create - create a new special memory pool
  * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents
  * @nid: node id of the node the pool structure should be allocated on, or -1
+ *
+ * Create a new special memory pool that can be used to manage special purpose
+ * memory not managed by the regular kmalloc/kfree interface.
  */
 struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
 {
@@ -34,15 +36,15 @@
 }
 EXPORT_SYMBOL(gen_pool_create);
 
-
-/*
- * Add a new chunk of memory to the specified pool.
- *
+/**
+ * gen_pool_add - add a new chunk of special memory to the pool
  * @pool: pool to add new memory chunk to
  * @addr: starting address of memory chunk to add to pool
  * @size: size in bytes of the memory chunk to add to pool
  * @nid: node id of the node the chunk structure and bitmap should be
  *       allocated on, or -1
+ *
+ * Add a new chunk of special memory to the specified pool.
  */
 int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
 		 int nid)
@@ -69,13 +71,44 @@
 }
 EXPORT_SYMBOL(gen_pool_add);
 
-
-/*
- * Allocate the requested number of bytes from the specified pool.
- * Uses a first-fit algorithm.
+/**
+ * gen_pool_destroy - destroy a special memory pool
+ * @pool: pool to destroy
  *
+ * Destroy the specified special memory pool. Verifies that there are no
+ * outstanding allocations.
+ */
+void gen_pool_destroy(struct gen_pool *pool)
+{
+	struct list_head *_chunk, *_next_chunk;
+	struct gen_pool_chunk *chunk;
+	int order = pool->min_alloc_order;
+	int bit, end_bit;
+
+
+	write_lock(&pool->lock);
+	list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
+		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+		list_del(&chunk->next_chunk);
+
+		end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+		bit = find_next_bit(chunk->bits, end_bit, 0);
+		BUG_ON(bit < end_bit);
+
+		kfree(chunk);
+	}
+	kfree(pool);
+	return;
+}
+EXPORT_SYMBOL(gen_pool_destroy);
+
+/**
+ * gen_pool_alloc - allocate special memory from the pool
  * @pool: pool to allocate from
  * @size: number of bytes to allocate from the pool
+ *
+ * Allocate the requested number of bytes from the specified pool.
+ * Uses a first-fit algorithm.
  */
 unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
 {
@@ -127,13 +160,13 @@
 }
 EXPORT_SYMBOL(gen_pool_alloc);
 
-
-/*
- * Free the specified memory back to the specified pool.
- *
+/**
+ * gen_pool_free - free allocated special memory back to the pool
  * @pool: pool to free to
  * @addr: starting address of memory to free back to pool
  * @size: size in bytes of memory to free
+ *
+ * Free previously allocated special memory back to the specified pool.
  */
 void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
 {
diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
index 2cc11fa..a4b730a 100644
--- a/lib/reed_solomon/reed_solomon.c
+++ b/lib/reed_solomon/reed_solomon.c
@@ -1,5 +1,5 @@
 /*
- * lib/reed_solomon/rslib.c
+ * lib/reed_solomon/reed_solomon.c
  *
  * Overview:
  *   Generic Reed Solomon encoder / decoder library
diff --git a/lib/sort.c b/lib/sort.c
index 5f3b51f..488788b 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -49,15 +49,15 @@
 	  void (*swap)(void *, void *, int size))
 {
 	/* pre-scale counters for performance */
-	int i = (num/2) * size, n = num * size, c, r;
+	int i = (num/2 - 1) * size, n = num * size, c, r;
 
 	if (!swap)
 		swap = (size == 4 ? u32_swap : generic_swap);
 
 	/* heapify */
 	for ( ; i >= 0; i -= size) {
-		for (r = i; r * 2 < n; r  = c) {
-			c = r * 2;
+		for (r = i; r * 2 + size < n; r  = c) {
+			c = r * 2 + size;
 			if (c < n - size && cmp(base + c, base + c + size) < 0)
 				c += size;
 			if (cmp(base + r, base + c) >= 0)
@@ -69,8 +69,8 @@
 	/* sort */
 	for (i = n - size; i >= 0; i -= size) {
 		swap(base, base + i, size);
-		for (r = 0; r * 2 < i; r = c) {
-			c = r * 2;
+		for (r = 0; r * 2 + size < i; r = c) {
+			c = r * 2 + size;
 			if (c < i - size && cmp(base + c, base + c + size) < 0)
 				c += size;
 			if (cmp(base + r, base + c) >= 0)
diff --git a/mm/Kconfig b/mm/Kconfig
index 5d88489..db7c55d 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -92,7 +92,7 @@
 
 #
 # SPARSEMEM_EXTREME (which is the default) does some bootmem
-# allocations when memory_present() is called.  If this can not
+# allocations when memory_present() is called.  If this cannot
 # be done on your architecture, select this option.  However,
 # statically allocating the mem_section[] array can potentially
 # consume vast quantities of .bss, so be careful.
@@ -104,7 +104,7 @@
 	def_bool n
 
 #
-# Architectecture platforms which require a two level mem_section in SPARSEMEM
+# Architecture platforms which require a two level mem_section in SPARSEMEM
 # must select this option. This is usually for architecture platforms with
 # an extremely sparse physical address space.
 #
diff --git a/mm/filemap.c b/mm/filemap.c
index fef7d87..3464b68 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1139,11 +1139,11 @@
 }
 
 /**
- * __generic_file_aio_read - generic filesystem read routine
+ * generic_file_aio_read - generic filesystem read routine
  * @iocb:	kernel I/O control block
  * @iov:	io vector request
  * @nr_segs:	number of segments in the iovec
- * @ppos:	current file position
+ * @pos:	current file position
  *
  * This is the "read()" routine for all filesystems
  * that can use the page cache directly.
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 7c7d03d..1d709ff 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -364,6 +364,8 @@
 	pte_t *ptep;
 	pte_t pte;
 	struct page *page;
+	struct page *tmp;
+	LIST_HEAD(page_list);
 
 	WARN_ON(!is_vm_hugetlb_page(vma));
 	BUG_ON(start & ~HPAGE_MASK);
@@ -384,12 +386,16 @@
 			continue;
 
 		page = pte_page(pte);
-		put_page(page);
+		list_add(&page->lru, &page_list);
 		add_mm_counter(mm, file_rss, (int) -(HPAGE_SIZE / PAGE_SIZE));
 	}
 
 	spin_unlock(&mm->page_table_lock);
 	flush_tlb_range(vma, start, end);
+	list_for_each_entry_safe(page, tmp, &page_list, lru) {
+		list_del(&page->lru);
+		put_page(page);
+	}
 }
 
 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
diff --git a/mm/nommu.c b/mm/nommu.c
index 3650195..8bdde95 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -221,7 +221,7 @@
  *	Allocate enough pages to cover @size from the page level
  *	allocator and map them into continguos kernel virtual space.
  *
- *	For tight cotrol over page level allocator and protection flags
+ *	For tight control over page level allocator and protection flags
  *	use __vmalloc() instead.
  */
 void *vmalloc(unsigned long size)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index c0d4ce1..a0f3390 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1,5 +1,5 @@
 /*
- * mm/page-writeback.c.
+ * mm/page-writeback.c
  *
  * Copyright (C) 2002, Linus Torvalds.
  *
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 4f59d90..a8c003e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -900,7 +900,8 @@
 		      int classzone_idx, int alloc_flags)
 {
 	/* free_pages my go negative - that's OK */
-	long min = mark, free_pages = z->free_pages - (1 << order) + 1;
+	unsigned long min = mark;
+	long free_pages = z->free_pages - (1 << order) + 1;
 	int o;
 
 	if (alloc_flags & ALLOC_HIGH)
@@ -2050,8 +2051,8 @@
 
 /**
  * free_bootmem_with_active_regions - Call free_bootmem_node for each active range
- * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed
- * @max_low_pfn: The highest PFN that till be passed to free_bootmem_node
+ * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed.
+ * @max_low_pfn: The highest PFN that will be passed to free_bootmem_node
  *
  * If an architecture guarantees that all ranges registered with
  * add_active_ranges() contain no holes and may be freed, this
@@ -2081,11 +2082,11 @@
 
 /**
  * sparse_memory_present_with_active_regions - Call memory_present for each active range
- * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used
+ * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used.
  *
  * If an architecture guarantees that all ranges registered with
  * add_active_ranges() contain no holes and may be freed, this
- * this function may be used instead of calling memory_present() manually.
+ * function may be used instead of calling memory_present() manually.
  */
 void __init sparse_memory_present_with_active_regions(int nid)
 {
@@ -2155,14 +2156,14 @@
 
 /**
  * get_pfn_range_for_nid - Return the start and end page frames for a node
- * @nid: The nid to return the range for. If MAX_NUMNODES, the min and max PFN are returned
- * @start_pfn: Passed by reference. On return, it will have the node start_pfn
- * @end_pfn: Passed by reference. On return, it will have the node end_pfn
+ * @nid: The nid to return the range for. If MAX_NUMNODES, the min and max PFN are returned.
+ * @start_pfn: Passed by reference. On return, it will have the node start_pfn.
+ * @end_pfn: Passed by reference. On return, it will have the node end_pfn.
  *
  * It returns the start and end page frame of a node based on information
  * provided by an arch calling add_active_range(). If called for a node
  * with no available memory, a warning is printed and the start and end
- * PFNs will be 0
+ * PFNs will be 0.
  */
 void __init get_pfn_range_for_nid(unsigned int nid,
 			unsigned long *start_pfn, unsigned long *end_pfn)
@@ -2215,7 +2216,7 @@
 
 /*
  * Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
- * then all holes in the requested range will be accounted for
+ * then all holes in the requested range will be accounted for.
  */
 unsigned long __init __absent_pages_in_range(int nid,
 				unsigned long range_start_pfn,
@@ -2268,7 +2269,7 @@
  * @start_pfn: The start PFN to start searching for holes
  * @end_pfn: The end PFN to stop searching for holes
  *
- * It returns the number of pages frames in memory holes within a range
+ * It returns the number of pages frames in memory holes within a range.
  */
 unsigned long __init absent_pages_in_range(unsigned long start_pfn,
 							unsigned long end_pfn)
@@ -2582,11 +2583,12 @@
 
 /**
  * remove_all_active_ranges - Remove all currently registered regions
+ *
  * During discovery, it may be found that a table like SRAT is invalid
  * and an alternative discovery method must be used. This function removes
  * all currently registered regions.
  */
-void __init remove_all_active_ranges()
+void __init remove_all_active_ranges(void)
 {
 	memset(early_node_map, 0, sizeof(early_node_map));
 	nr_nodemap_entries = 0;
@@ -2636,7 +2638,7 @@
  * find_min_pfn_with_active_regions - Find the minimum PFN registered
  *
  * It returns the minimum PFN based on information provided via
- * add_active_range()
+ * add_active_range().
  */
 unsigned long __init find_min_pfn_with_active_regions(void)
 {
@@ -2647,7 +2649,7 @@
  * find_max_pfn_with_active_regions - Find the maximum PFN registered
  *
  * It returns the maximum PFN based on information provided via
- * add_active_range()
+ * add_active_range().
  */
 unsigned long __init find_max_pfn_with_active_regions(void)
 {
@@ -2662,10 +2664,7 @@
 
 /**
  * free_area_init_nodes - Initialise all pg_data_t and zone data
- * @arch_max_dma_pfn: The maximum PFN usable for ZONE_DMA
- * @arch_max_dma32_pfn: The maximum PFN usable for ZONE_DMA32
- * @arch_max_low_pfn: The maximum PFN usable for ZONE_NORMAL
- * @arch_max_high_pfn: The maximum PFN usable for ZONE_HIGHMEM
+ * @max_zone_pfn: an array of max PFNs for each zone
  *
  * This will call free_area_init_node() for each active node in the system.
  * Using the page ranges provided by add_active_range(), the size of each
@@ -2723,14 +2722,15 @@
 #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
 
 /**
- * set_dma_reserve - Account the specified number of pages reserved in ZONE_DMA
- * @new_dma_reserve - The number of pages to mark reserved
+ * set_dma_reserve - set the specified number of pages reserved in the first zone
+ * @new_dma_reserve: The number of pages to mark reserved
  *
  * The per-cpu batchsize and zone watermarks are determined by present_pages.
  * In the DMA zone, a significant percentage may be consumed by kernel image
  * and other unfreeable allocations which can skew the watermarks badly. This
- * function may optionally be used to account for unfreeable pages in
- * ZONE_DMA. The effect will be lower watermarks and smaller per-cpu batchsize
+ * function may optionally be used to account for unfreeable pages in the
+ * first zone (e.g., ZONE_DMA). The effect will be lower watermarks and
+ * smaller per-cpu batchsize.
  */
 void __init set_dma_reserve(unsigned long new_dma_reserve)
 {
@@ -2843,10 +2843,11 @@
 	calculate_totalreserve_pages();
 }
 
-/*
- * setup_per_zone_pages_min - called when min_free_kbytes changes.  Ensures 
- *	that the pages_{min,low,high} values for each zone are set correctly 
- *	with respect to min_free_kbytes.
+/**
+ * setup_per_zone_pages_min - called when min_free_kbytes changes.
+ *
+ * Ensures that the pages_{min,low,high} values for each zone are set correctly
+ * with respect to min_free_kbytes.
  */
 void setup_per_zone_pages_min(void)
 {
diff --git a/mm/slab.c b/mm/slab.c
index 3dbd6f4..c23b992 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3488,22 +3488,25 @@
 }
 
 
+#ifdef CONFIG_DEBUG_SLAB
 void *__kmalloc(size_t size, gfp_t flags)
 {
-#ifndef CONFIG_DEBUG_SLAB
-	return __do_kmalloc(size, flags, NULL);
-#else
 	return __do_kmalloc(size, flags, __builtin_return_address(0));
-#endif
 }
 EXPORT_SYMBOL(__kmalloc);
 
-#ifdef CONFIG_DEBUG_SLAB
 void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller)
 {
 	return __do_kmalloc(size, flags, caller);
 }
 EXPORT_SYMBOL(__kmalloc_track_caller);
+
+#else
+void *__kmalloc(size_t size, gfp_t flags)
+{
+	return __do_kmalloc(size, flags, NULL);
+}
+EXPORT_SYMBOL(__kmalloc);
 #endif
 
 /**
diff --git a/mm/util.c b/mm/util.c
index e14fa84..ace2aea 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -11,7 +11,7 @@
  */
 void *__kzalloc(size_t size, gfp_t flags)
 {
-	void *ret = ____kmalloc(size, flags);
+	void *ret = kmalloc_track_caller(size, flags);
 	if (ret)
 		memset(ret, 0, size);
 	return ret;
@@ -33,7 +33,7 @@
 		return NULL;
 
 	len = strlen(s) + 1;
-	buf = ____kmalloc(len, gfp);
+	buf = kmalloc_track_caller(len, gfp);
 	if (buf)
 		memcpy(buf, s, len);
 	return buf;
@@ -51,7 +51,7 @@
 {
 	void *p;
 
-	p = ____kmalloc(len, gfp);
+	p = kmalloc_track_caller(len, gfp);
 	if (p)
 		memcpy(p, src, len);
 	return p;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1ac191c..750ab6e 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -503,7 +503,7 @@
  *	Allocate enough pages to cover @size from the page level
  *	allocator and map them into contiguous kernel virtual space.
  *
- *	For tight cotrol over page level allocator and protection flags
+ *	For tight control over page level allocator and protection flags
  *	use __vmalloc() instead.
  */
 void *vmalloc(unsigned long size)
@@ -542,7 +542,7 @@
  *	Allocate enough pages to cover @size from the page level
  *	allocator and map them into contiguous kernel virtual space.
  *
- *	For tight cotrol over page level allocator and protection flags
+ *	For tight control over page level allocator and protection flags
  *	use __vmalloc() instead.
  */
 void *vmalloc_node(unsigned long size, int node)
@@ -563,7 +563,7 @@
  *	the page level allocator and map them into contiguous and
  *	executable kernel virtual space.
  *
- *	For tight cotrol over page level allocator and protection flags
+ *	For tight control over page level allocator and protection flags
  *	use __vmalloc() instead.
  */
 
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 26f3227..1958ad1 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -1011,7 +1011,7 @@
 
 /* ---- TTY structure ---- */
 
-static struct tty_operations rfcomm_ops = {
+static const struct tty_operations rfcomm_ops = {
 	.open			= rfcomm_tty_open,
 	.close			= rfcomm_tty_close,
 	.write			= rfcomm_tty_write,
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index 770c0df..b54306a 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -22,24 +22,37 @@
    const void *data, unsigned int datalen)
 {
 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+	int action = info->target & -16;
 
-	if ((*pskb)->nfmark != info->mark)
+	if (action == MARK_SET_VALUE)
 		(*pskb)->nfmark = info->mark;
+	else if (action == MARK_OR_VALUE)
+		(*pskb)->nfmark |= info->mark;
+	else if (action == MARK_AND_VALUE)
+		(*pskb)->nfmark &= info->mark;
+	else
+		(*pskb)->nfmark ^= info->mark;
 
-	return info->target;
+	return info->target | -16;
 }
 
 static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+	int tmp;
 
 	if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
 		return -EINVAL;
-	if (BASE_CHAIN && info->target == EBT_RETURN)
+	tmp = info->target | -16;
+	if (BASE_CHAIN && tmp == EBT_RETURN)
 		return -EINVAL;
 	CLEAR_BASE_CHAIN_BIT;
-	if (INVALID_TARGET)
+	if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
+		return -EINVAL;
+	tmp = info->target & -16;
+	if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
+	    tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
 		return -EINVAL;
 	return 0;
 }
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 8ce8c47..b4b4783 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -344,12 +344,12 @@
 {
 	struct neighbour *n;
 	int key_len = tbl->key_len;
-	u32 hash_val = tbl->hash(pkey, dev) & tbl->hash_mask;
+	u32 hash_val = tbl->hash(pkey, dev);
 	
 	NEIGH_CACHE_STAT_INC(tbl, lookups);
 
 	read_lock_bh(&tbl->lock);
-	for (n = tbl->hash_buckets[hash_val]; n; n = n->next) {
+	for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
 		if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
 			neigh_hold(n);
 			NEIGH_CACHE_STAT_INC(tbl, hits);
@@ -364,12 +364,12 @@
 {
 	struct neighbour *n;
 	int key_len = tbl->key_len;
-	u32 hash_val = tbl->hash(pkey, NULL) & tbl->hash_mask;
+	u32 hash_val = tbl->hash(pkey, NULL);
 
 	NEIGH_CACHE_STAT_INC(tbl, lookups);
 
 	read_lock_bh(&tbl->lock);
-	for (n = tbl->hash_buckets[hash_val]; n; n = n->next) {
+	for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
 		if (!memcmp(n->primary_key, pkey, key_len)) {
 			neigh_hold(n);
 			NEIGH_CACHE_STAT_INC(tbl, hits);
@@ -1998,12 +1998,12 @@
 	int rc, h, s_h = cb->args[1];
 	int idx, s_idx = idx = cb->args[2];
 
+	read_lock_bh(&tbl->lock);
 	for (h = 0; h <= tbl->hash_mask; h++) {
 		if (h < s_h)
 			continue;
 		if (h > s_h)
 			s_idx = 0;
-		read_lock_bh(&tbl->lock);
 		for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next, idx++) {
 			if (idx < s_idx)
 				continue;
@@ -2016,8 +2016,8 @@
 				goto out;
 			}
 		}
-		read_unlock_bh(&tbl->lock);
 	}
+	read_unlock_bh(&tbl->lock);
 	rc = skb->len;
 out:
 	cb->args[1] = h;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index c448c7f..3c23760 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -156,7 +156,8 @@
 
 	/* Get the DATA. Size must match skb_add_mtu(). */
 	size = SKB_DATA_ALIGN(size);
-	data = ____kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+	data = kmalloc_track_caller(size + sizeof(struct skb_shared_info),
+			gfp_mask);
 	if (!data)
 		goto nodata;
 
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 30af4a4..5572071 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -64,7 +64,7 @@
 config IP_FIB_TRIE
 	bool "FIB_TRIE"
 	---help---
-	Use new experimental LC-trie as FIB lookup algoritm. 
+	Use new experimental LC-trie as FIB lookup algorithm. 
         This improves lookup performance if you have a large
 	number of routes.
 
@@ -434,6 +434,15 @@
 
 	  If unsure, say Y.
 
+config INET_XFRM_MODE_BEET
+	tristate "IP: IPsec BEET mode"
+	default y
+	select XFRM
+	---help---
+	  Support for IPsec BEET mode.
+
+	  If unsure, say Y.
+
 config INET_DIAG
 	tristate "INET: socket monitoring interface"
 	default y
@@ -526,7 +535,7 @@
 	---help---
 	TCP-Hybla is a sender-side only change that eliminates penalization of
 	long-RTT, large-bandwidth connections, like when satellite legs are
-	involved, expecially when sharing a common bottleneck with normal
+	involved, especially when sharing a common bottleneck with normal
 	terrestrial connections.
 
 config TCP_CONG_VEGAS
@@ -556,7 +565,7 @@
 	default n
 	---help---
 	TCP Low Priority (TCP-LP), a distributed algorithm whose goal is
-	to utiliza only the excess network bandwidth as compared to the
+	to utilize only the excess network bandwidth as compared to the
 	``fair share`` of bandwidth as targeted by TCP.
 	See http://www-ece.rice.edu/networks/TCP-LP/
 
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f66049e..15645c5 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -23,6 +23,7 @@
 obj-$(CONFIG_INET_ESP) += esp4.o
 obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
 obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o
+obj-$(CONFIG_INET_XFRM_MODE_BEET) += xfrm4_mode_beet.o
 obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
 obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
 obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index cfe5c84..cfb5d3d 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1,4 +1,4 @@
-/* linux/net/inet/arp.c
+/* linux/net/ipv4/arp.c
  *
  * Version:	$Id: arp.c,v 1.99 2001/08/30 22:55:42 davem Exp $
  *
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 13b2936..b5c205b 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -253,7 +253,8 @@
 		 *    as per draft-ietf-ipsec-udp-encaps-06,
 		 *    section 3.1.2
 		 */
-		if (x->props.mode == XFRM_MODE_TRANSPORT)
+		if (x->props.mode == XFRM_MODE_TRANSPORT ||
+		    x->props.mode == XFRM_MODE_BEET)
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
 
@@ -271,17 +272,28 @@
 {
 	struct esp_data *esp = x->data;
 	u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
+	int enclen = 0;
 
-	if (x->props.mode == XFRM_MODE_TUNNEL) {
-		mtu = ALIGN(mtu + 2, blksize);
-	} else {
-		/* The worst case. */
+	switch (x->props.mode) {
+	case XFRM_MODE_TUNNEL:
+		mtu = ALIGN(mtu +2, blksize);
+		break;
+	default:
+	case XFRM_MODE_TRANSPORT:
+		/* The worst case */
 		mtu = ALIGN(mtu + 2, 4) + blksize - 4;
+		break;
+	case XFRM_MODE_BEET:
+ 		/* The worst case. */
+		enclen = IPV4_BEET_PHMAXLEN;
+		mtu = ALIGN(mtu + enclen + 2, blksize);
+		break;
 	}
+
 	if (esp->conf.padlen)
 		mtu = ALIGN(mtu, esp->conf.padlen);
 
-	return mtu + x->props.header_len + esp->auth.icv_trunc_len;
+	return mtu + x->props.header_len + esp->auth.icv_trunc_len - enclen;
 }
 
 static void esp4_err(struct sk_buff *skb, u32 info)
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 2017d36..3839b70 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -206,6 +206,7 @@
 static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
 {
 	struct xfrm_state *t;
+	u8 mode = XFRM_MODE_TUNNEL;
 	
 	t = xfrm_state_alloc();
 	if (t == NULL)
@@ -216,7 +217,9 @@
 	t->id.daddr.a4 = x->id.daddr.a4;
 	memcpy(&t->sel, &x->sel, sizeof(t->sel));
 	t->props.family = AF_INET;
-	t->props.mode = XFRM_MODE_TUNNEL;
+	if (x->props.mode == XFRM_MODE_BEET)
+		mode = x->props.mode;
+	t->props.mode = mode;
 	t->props.saddr.a4 = x->props.saddr.a4;
 	t->props.flags = x->props.flags;
 
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 1fbb384..f8ce847 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -366,7 +366,7 @@
 	 */
 	 
 	if (!ic_host_name_set)
-		sprintf(system_utsname.nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
+		sprintf(init_utsname()->nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
 
 	if (root_server_addr == INADDR_NONE)
 		root_server_addr = ic_servaddr;
@@ -805,7 +805,7 @@
 			}
 			break;
 		case 12:	/* Host name */
-			ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
+			ic_bootp_string(utsname()->nodename, ext+1, *ext, __NEW_UTS_LEN);
 			ic_host_name_set = 1;
 			break;
 		case 15:	/* Domain name (DNS) */
@@ -816,7 +816,7 @@
 				ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
 			break;
 		case 40:	/* NIS Domain name (_not_ DNS) */
-			ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
+			ic_bootp_string(utsname()->domainname, ext+1, *ext, __NEW_UTS_LEN);
 			break;
 	}
 }
@@ -1368,7 +1368,7 @@
 	printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
 	printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
 	printk(",\n     host=%s, domain=%s, nis-domain=%s",
-	       system_utsname.nodename, ic_domain, system_utsname.domainname);
+	       utsname()->nodename, ic_domain, utsname()->domainname);
 	printk(",\n     bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr));
 	printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr));
 	printk(", rootpath=%s", root_server_path);
@@ -1478,11 +1478,11 @@
 			case 4:
 				if ((dp = strchr(ip, '.'))) {
 					*dp++ = '\0';
-					strlcpy(system_utsname.domainname, dp,
-						sizeof(system_utsname.domainname));
+					strlcpy(utsname()->domainname, dp,
+						sizeof(utsname()->domainname));
 				}
-				strlcpy(system_utsname.nodename, ip,
-					sizeof(system_utsname.nodename));
+				strlcpy(utsname()->nodename, ip,
+					sizeof(utsname()->nodename));
 				ic_host_name_set = 1;
 				break;
 			case 5:
diff --git a/net/ipv4/ipvs/Kconfig b/net/ipv4/ipvs/Kconfig
index c9820bf..891b935 100644
--- a/net/ipv4/ipvs/Kconfig
+++ b/net/ipv4/ipvs/Kconfig
@@ -81,7 +81,7 @@
 	bool "ESP load balancing support"
 	depends on IP_VS
 	---help---
-	  This option enables support for load balancing ESP (Encapsultion
+	  This option enables support for load balancing ESP (Encapsulation
 	  Security Payload) transport protocol. Say Y if unsure.
 
 config	IP_VS_PROTO_AH
@@ -204,7 +204,7 @@
 	  connections to the server with the shortest expected delay. The 
 	  expected delay that the job will experience is (Ci + 1) / Ui if 
 	  sent to the ith server, in which Ci is the number of connections
-	  on the the ith server and Ui is the fixed service rate (weight)
+	  on the ith server and Ui is the fixed service rate (weight)
 	  of the ith server.
 
 	  If you want to compile it in kernel, say Y. To compile it as a
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 6dee039..1445bb4 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -813,6 +813,16 @@
 	skb->nh.iph->saddr = cp->vaddr;
 	ip_send_check(skb->nh.iph);
 
+ 	/* For policy routing, packets originating from this
+ 	 * machine itself may be routed differently to packets
+ 	 * passing through.  We want this packet to be routed as
+ 	 * if it came from this machine itself.  So re-compute
+ 	 * the routing information.
+ 	 */
+ 	if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
+ 		goto drop;
+	skb = *pskb;
+
 	IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
 
 	ip_vs_out_stats(cp, skb);
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 5ac1537..e2005c6 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -8,7 +8,7 @@
 #include <net/ip.h>
 
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
-int ip_route_me_harder(struct sk_buff **pskb)
+int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
 {
 	struct iphdr *iph = (*pskb)->nh.iph;
 	struct rtable *rt;
@@ -16,10 +16,13 @@
 	struct dst_entry *odst;
 	unsigned int hh_len;
 
+	if (addr_type == RTN_UNSPEC)
+		addr_type = inet_addr_type(iph->saddr);
+
 	/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
 	 * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
 	 */
-	if (inet_addr_type(iph->saddr) == RTN_LOCAL) {
+	if (addr_type == RTN_LOCAL) {
 		fl.nl_u.ip4_u.daddr = iph->daddr;
 		fl.nl_u.ip4_u.saddr = iph->saddr;
 		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
@@ -156,7 +159,7 @@
 		if (!(iph->tos == rt_info->tos
 		      && iph->daddr == rt_info->daddr
 		      && iph->saddr == rt_info->saddr))
-			return ip_route_me_harder(pskb);
+			return ip_route_me_harder(pskb, RTN_UNSPEC);
 	}
 	return 0;
 }
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index a55b8ff..d88c292 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -373,7 +373,7 @@
 	  daemon using netlink multicast sockets; unlike the LOG target
 	  which can only be viewed through syslog.
 
-	  The apropriate userspace logging daemon (ulogd) may be obtained from
+	  The appropriate userspace logging daemon (ulogd) may be obtained from
 	  <http://www.gnumonks.org/projects/ulogd/>
 
 	  To compile it as a module, choose M here.  If unsure, say N.
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 021395b..d85d2de 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -265,7 +265,8 @@
 		       ct->tuplehash[!dir].tuple.src.u.all
 #endif
 		    )
-			return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+			if (ip_route_me_harder(pskb, RTN_UNSPEC))
+				ret = NF_DROP;
 	}
 	return ret;
 }
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index fd0c05e..ad0312d 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -38,76 +38,16 @@
 #define DEBUGP(format, args...)
 #endif
 
-static inline struct rtable *route_reverse(struct sk_buff *skb, 
-					   struct tcphdr *tcph, int hook)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct dst_entry *odst;
-	struct flowi fl = {};
-	struct rtable *rt;
-
-	/* We don't require ip forwarding to be enabled to be able to
-	 * send a RST reply for bridged traffic. */
-	if (hook != NF_IP_FORWARD
-#ifdef CONFIG_BRIDGE_NETFILTER
-	    || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED)
-#endif
-	   ) {
-		fl.nl_u.ip4_u.daddr = iph->saddr;
-		if (hook == NF_IP_LOCAL_IN)
-			fl.nl_u.ip4_u.saddr = iph->daddr;
-		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
-
-		if (ip_route_output_key(&rt, &fl) != 0)
-			return NULL;
-	} else {
-		/* non-local src, find valid iif to satisfy
-		 * rp-filter when calling ip_route_input. */
-		fl.nl_u.ip4_u.daddr = iph->daddr;
-		if (ip_route_output_key(&rt, &fl) != 0)
-			return NULL;
-
-		odst = skb->dst;
-		if (ip_route_input(skb, iph->saddr, iph->daddr,
-		                   RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
-			dst_release(&rt->u.dst);
-			return NULL;
-		}
-		dst_release(&rt->u.dst);
-		rt = (struct rtable *)skb->dst;
-		skb->dst = odst;
-
-		fl.nl_u.ip4_u.daddr = iph->saddr;
-		fl.nl_u.ip4_u.saddr = iph->daddr;
-		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
-	}
-
-	if (rt->u.dst.error) {
-		dst_release(&rt->u.dst);
-		return NULL;
-	}
-
-	fl.proto = IPPROTO_TCP;
-	fl.fl_ip_sport = tcph->dest;
-	fl.fl_ip_dport = tcph->source;
-	security_skb_classify_flow(skb, &fl);
-
-	xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
-
-	return rt;
-}
-
 /* Send RST reply */
 static void send_reset(struct sk_buff *oldskb, int hook)
 {
 	struct sk_buff *nskb;
 	struct iphdr *iph = oldskb->nh.iph;
 	struct tcphdr _otcph, *oth, *tcph;
-	struct rtable *rt;
 	__be16 tmp_port;
 	__be32 tmp_addr;
 	int needs_ack;
-	int hh_len;
+	unsigned int addr_type;
 
 	/* IP header checks: fragment. */
 	if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
@@ -126,23 +66,13 @@
 	if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))
 		return;
 
-	if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
-		return;
-
-	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
-
 	/* We need a linear, writeable skb.  We also need to expand
 	   headroom in case hh_len of incoming interface < hh_len of
 	   outgoing interface */
-	nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
+	nskb = skb_copy_expand(oldskb, LL_MAX_HEADER, skb_tailroom(oldskb),
 			       GFP_ATOMIC);
-	if (!nskb) {
-		dst_release(&rt->u.dst);
+	if (!nskb)
 		return;
-	}
-
-	dst_release(nskb->dst);
-	nskb->dst = &rt->u.dst;
 
 	/* This packet will not be the same as the other: clear nf fields */
 	nf_reset(nskb);
@@ -184,6 +114,21 @@
 	tcph->window = 0;
 	tcph->urg_ptr = 0;
 
+	/* Set DF, id = 0 */
+	nskb->nh.iph->frag_off = htons(IP_DF);
+	nskb->nh.iph->id = 0;
+
+	addr_type = RTN_UNSPEC;
+	if (hook != NF_IP_FORWARD
+#ifdef CONFIG_BRIDGE_NETFILTER
+	    || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
+#endif
+	   )
+		addr_type = RTN_LOCAL;
+
+	if (ip_route_me_harder(&nskb, addr_type))
+		goto free_nskb;
+
 	/* Adjust TCP checksum */
 	nskb->ip_summed = CHECKSUM_NONE;
 	tcph->check = 0;
@@ -192,12 +137,8 @@
 				   nskb->nh.iph->daddr,
 				   csum_partial((char *)tcph,
 						sizeof(struct tcphdr), 0));
-
-	/* Adjust IP TTL, DF */
+	/* Adjust IP TTL */
 	nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
-	/* Set DF, id = 0 */
-	nskb->nh.iph->frag_off = htons(IP_DF);
-	nskb->nh.iph->id = 0;
 
 	/* Adjust IP checksum */
 	nskb->nh.iph->check = 0;
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index e62ea2b..b91f358 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -157,7 +157,8 @@
 		|| (*pskb)->nfmark != nfmark
 #endif
 		|| (*pskb)->nh.iph->tos != tos))
-		return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+		if (ip_route_me_harder(pskb, RTN_UNSPEC))
+			ret = NF_DROP;
 
 	return ret;
 }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3f884ce..cf06acc 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2259,7 +2259,7 @@
 	u32 pkts_acked = 0;
 	void (*rtt_sample)(struct sock *sk, u32 usrtt)
 		= icsk->icsk_ca_ops->rtt_sample;
-	struct timeval tv;
+	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
 
 	while ((skb = skb_peek(&sk->sk_write_queue)) &&
 	       skb != sk->sk_send_head) {
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index dab37d2..4be336f 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -99,8 +99,10 @@
 }
 
 static struct jprobe tcp_send_probe = {
-	.kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, },
-	.entry = (kprobe_opcode_t *) &jtcp_sendmsg,
+	.kp = {
+		.symbol_name	= "tcp_sendmsg",
+	},
+	.entry	= JPROBE_ENTRY(jtcp_sendmsg),
 };
 
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 6d6142f..865d752 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -675,6 +675,8 @@
 		udp_flush_pending_frames(sk);
 	else if (!corkreq)
 		err = udp_push_pending_frames(sk, up);
+	else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
+		up->pending = 0;
 	release_sock(sk);
 
 out:
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
new file mode 100644
index 0000000..89cf59e
--- /dev/null
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -0,0 +1,139 @@
+/*
+ * xfrm4_mode_beet.c - BEET mode encapsulation for IPv4.
+ *
+ * Copyright (c) 2006 Diego Beltrami <diego.beltrami@gmail.com>
+ *                    Miika Komu     <miika@iki.fi>
+ *                    Herbert Xu     <herbert@gondor.apana.org.au>
+ *                    Abhinav Pathak <abhinav.pathak@hiit.fi>
+ *                    Jeff Ahrenholz <ahrenholz@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dst.h>
+#include <net/ip.h>
+#include <net/xfrm.h>
+
+/* Add encapsulation header.
+ *
+ * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
+ * The following fields in it shall be filled in by x->type->output:
+ *      tot_len
+ *      check
+ *
+ * On exit, skb->h will be set to the start of the payload to be processed
+ * by x->type->output and skb->nh will be set to the top IP header.
+ */
+static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+	struct iphdr *iph, *top_iph = NULL;
+	int hdrlen, optlen;
+
+	iph = skb->nh.iph;
+	skb->h.ipiph = iph;
+
+	hdrlen = 0;
+	optlen = iph->ihl * 4 - sizeof(*iph);
+	if (unlikely(optlen))
+		hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
+
+	skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen);
+	top_iph = skb->nh.iph;
+	hdrlen = iph->ihl * 4 - optlen;
+	skb->h.raw += hdrlen;
+
+	memmove(top_iph, iph, hdrlen);
+	if (unlikely(optlen)) {
+		struct ip_beet_phdr *ph;
+
+		BUG_ON(optlen < 0);
+
+		ph = (struct ip_beet_phdr *)skb->h.raw;
+		ph->padlen = 4 - (optlen & 4);
+		ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;
+		ph->nexthdr = top_iph->protocol;
+
+		top_iph->protocol = IPPROTO_BEETPH;
+		top_iph->ihl = sizeof(struct iphdr) / 4;
+	}
+
+	top_iph->saddr = x->props.saddr.a4;
+	top_iph->daddr = x->id.daddr.a4;
+
+	return 0;
+}
+
+static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	struct iphdr *iph = skb->nh.iph;
+	int phlen = 0;
+	int optlen = 0;
+	__u8 ph_nexthdr = 0, protocol = 0;
+	int err = -EINVAL;
+
+	protocol = iph->protocol;
+
+	if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
+		struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1);
+
+		if (!pskb_may_pull(skb, sizeof(*ph)))
+			goto out;
+
+		phlen = ph->hdrlen * 8;
+		optlen = phlen - ph->padlen - sizeof(*ph);
+		if (optlen < 0 || optlen & 3 || optlen > 250)
+			goto out;
+
+		if (!pskb_may_pull(skb, phlen))
+			goto out;
+
+		ph_nexthdr = ph->nexthdr;
+	}
+
+	skb_push(skb, sizeof(*iph) - phlen + optlen);
+	memmove(skb->data, skb->nh.raw, sizeof(*iph));
+	skb->nh.raw = skb->data;
+
+	iph = skb->nh.iph;
+	iph->ihl = (sizeof(*iph) + optlen) / 4;
+	iph->tot_len = htons(skb->len);
+	iph->daddr = x->sel.daddr.a4;
+	iph->saddr = x->sel.saddr.a4;
+	if (ph_nexthdr)
+		iph->protocol = ph_nexthdr;
+	else
+		iph->protocol = protocol;
+	iph->check = 0;
+	iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
+	err = 0;
+out:
+	return err;
+}
+
+static struct xfrm_mode xfrm4_beet_mode = {
+	.input = xfrm4_beet_input,
+	.output = xfrm4_beet_output,
+	.owner = THIS_MODULE,
+	.encap = XFRM_MODE_BEET,
+};
+
+static int __init xfrm4_beet_init(void)
+{
+	return xfrm_register_mode(&xfrm4_beet_mode, AF_INET);
+}
+
+static void __exit xfrm4_beet_exit(void)
+{
+	int err;
+
+	err = xfrm_unregister_mode(&xfrm4_beet_mode, AF_INET);
+	BUG_ON(err);
+}
+
+module_init(xfrm4_beet_init);
+module_exit(xfrm4_beet_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_BEET);
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index a2d211d..a460e81 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -136,6 +136,16 @@
 
 	  If unsure, say Y.
 
+config INET6_XFRM_MODE_BEET
+	tristate "IPv6: IPsec BEET mode"
+	depends on IPV6
+	default IPV6
+	select XFRM
+	---help---
+	  Support for IPsec BEET mode.
+
+	  If unsure, say Y.
+
 config INET6_XFRM_MODE_ROUTEOPTIMIZATION
 	tristate "IPv6: MIPv6 route optimization mode (EXPERIMENTAL)"
 	depends on IPV6 && EXPERIMENTAL
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 0213c66..87274e4 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -26,6 +26,7 @@
 obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o
 obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
 obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
+obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
 obj-$(CONFIG_NETFILTER)	+= netfilter/
 
 obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index a2860e3..71f59f1 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -199,6 +199,7 @@
 static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
 {
 	struct xfrm_state *t = NULL;
+	u8 mode = XFRM_MODE_TUNNEL;
 
 	t = xfrm_state_alloc();
 	if (!t)
@@ -212,7 +213,9 @@
 	memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
 	memcpy(&t->sel, &x->sel, sizeof(t->sel));
 	t->props.family = AF_INET6;
-	t->props.mode = XFRM_MODE_TUNNEL;
+	if (x->props.mode == XFRM_MODE_BEET)
+		mode = x->props.mode;
+	t->props.mode = mode;
 	memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
 
 	if (xfrm_init_state(t))
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 9662561..e0c3934 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -546,7 +546,7 @@
 	struct in6_addr *daddr, *final_p = NULL, final;
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
-	struct flowi *fl = &inet->cork.fl;
+	struct flowi fl;
 	struct dst_entry *dst;
 	int addr_len = msg->msg_namelen;
 	int ulen = len;
@@ -626,19 +626,19 @@
 	}
 	ulen += sizeof(struct udphdr);
 
-	memset(fl, 0, sizeof(*fl));
+	memset(&fl, 0, sizeof(fl));
 
 	if (sin6) {
 		if (sin6->sin6_port == 0)
 			return -EINVAL;
 
-		fl->fl_ip_dport = sin6->sin6_port;
+		fl.fl_ip_dport = sin6->sin6_port;
 		daddr = &sin6->sin6_addr;
 
 		if (np->sndflow) {
-			fl->fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
-			if (fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
-				flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
+			fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+			if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+				flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
 				if (flowlabel == NULL)
 					return -EINVAL;
 				daddr = &flowlabel->dst;
@@ -656,32 +656,32 @@
 		if (addr_len >= sizeof(struct sockaddr_in6) &&
 		    sin6->sin6_scope_id &&
 		    ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
-			fl->oif = sin6->sin6_scope_id;
+			fl.oif = sin6->sin6_scope_id;
 	} else {
 		if (sk->sk_state != TCP_ESTABLISHED)
 			return -EDESTADDRREQ;
 
-		fl->fl_ip_dport = inet->dport;
+		fl.fl_ip_dport = inet->dport;
 		daddr = &np->daddr;
-		fl->fl6_flowlabel = np->flow_label;
+		fl.fl6_flowlabel = np->flow_label;
 		connected = 1;
 	}
 
-	if (!fl->oif)
-		fl->oif = sk->sk_bound_dev_if;
+	if (!fl.oif)
+		fl.oif = sk->sk_bound_dev_if;
 
 	if (msg->msg_controllen) {
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 		opt->tot_len = sizeof(*opt);
 
-		err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
+		err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
 		}
-		if ((fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
-			flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
+		if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
 			if (flowlabel == NULL)
 				return -EINVAL;
 		}
@@ -695,39 +695,39 @@
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
 
-	fl->proto = IPPROTO_UDP;
-	ipv6_addr_copy(&fl->fl6_dst, daddr);
-	if (ipv6_addr_any(&fl->fl6_src) && !ipv6_addr_any(&np->saddr))
-		ipv6_addr_copy(&fl->fl6_src, &np->saddr);
-	fl->fl_ip_sport = inet->sport;
+	fl.proto = IPPROTO_UDP;
+	ipv6_addr_copy(&fl.fl6_dst, daddr);
+	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
+		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+	fl.fl_ip_sport = inet->sport;
 	
 	/* merge ip6_build_xmit from ip6_output */
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		ipv6_addr_copy(&final, &fl->fl6_dst);
-		ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
+		ipv6_addr_copy(&final, &fl.fl6_dst);
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 		final_p = &final;
 		connected = 0;
 	}
 
-	if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst)) {
-		fl->oif = np->mcast_oif;
+	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) {
+		fl.oif = np->mcast_oif;
 		connected = 0;
 	}
 
-	security_sk_classify_flow(sk, fl);
+	security_sk_classify_flow(sk, &fl);
 
-	err = ip6_sk_dst_lookup(sk, &dst, fl);
+	err = ip6_sk_dst_lookup(sk, &dst, &fl);
 	if (err)
 		goto out;
 	if (final_p)
-		ipv6_addr_copy(&fl->fl6_dst, final_p);
+		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
 		goto out;
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl->fl6_dst))
+		if (ipv6_addr_is_multicast(&fl.fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -763,21 +763,23 @@
 do_append_data:
 	up->len += ulen;
 	err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
-		sizeof(struct udphdr), hlimit, tclass, opt, fl,
+		sizeof(struct udphdr), hlimit, tclass, opt, &fl,
 		(struct rt6_info*)dst,
 		corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
 	if (err)
 		udp_v6_flush_pending_frames(sk);
 	else if (!corkreq)
 		err = udp_v6_push_pending_frames(sk, up);
+	else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
+		up->pending = 0;
 
 	if (dst) {
 		if (connected) {
 			ip6_dst_store(sk, dst,
-				      ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ?
+				      ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ?
 				      &np->daddr : NULL,
 #ifdef CONFIG_IPV6_SUBTREES
-				      ipv6_addr_equal(&fl->fl6_src, &np->saddr) ?
+				      ipv6_addr_equal(&fl.fl6_src, &np->saddr) ?
 				      &np->saddr :
 #endif
 				      NULL);
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
new file mode 100644
index 0000000..edcfffa
--- /dev/null
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -0,0 +1,107 @@
+/*
+ * xfrm6_mode_beet.c - BEET mode encapsulation for IPv6.
+ *
+ * Copyright (c) 2006 Diego Beltrami <diego.beltrami@gmail.com>
+ *                    Miika Komu     <miika@iki.fi>
+ *                    Herbert Xu     <herbert@gondor.apana.org.au>
+ *                    Abhinav Pathak <abhinav.pathak@hiit.fi>
+ *                    Jeff Ahrenholz <ahrenholz@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dsfield.h>
+#include <net/dst.h>
+#include <net/inet_ecn.h>
+#include <net/ipv6.h>
+#include <net/xfrm.h>
+
+/* Add encapsulation header.
+ *
+ * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
+ * The following fields in it shall be filled in by x->type->output:
+ *	payload_len
+ *
+ * On exit, skb->h will be set to the start of the encapsulation header to be
+ * filled in by x->type->output and skb->nh will be set to the nextheader field
+ * of the extension header directly preceding the encapsulation header, or in
+ * its absence, that of the top IP header.  The value of skb->data will always
+ * point to the top IP header.
+ */
+static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+	struct ipv6hdr *iph, *top_iph;
+	u8 *prevhdr;
+	int hdr_len;
+
+	skb_push(skb, x->props.header_len);
+	iph = skb->nh.ipv6h;
+
+	hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+	skb->nh.raw = prevhdr - x->props.header_len;
+	skb->h.raw = skb->data + hdr_len;
+	memmove(skb->data, iph, hdr_len);
+
+	skb->nh.raw = skb->data;
+	top_iph = skb->nh.ipv6h;
+	skb->nh.raw = &top_iph->nexthdr;
+	skb->h.ipv6h = top_iph + 1;
+
+	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+
+	return 0;
+}
+
+static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	struct ipv6hdr *ip6h;
+	int size = sizeof(struct ipv6hdr);
+	int err = -EINVAL;
+
+	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+		goto out;
+
+	skb_push(skb, size);
+	memmove(skb->data, skb->nh.raw, size);
+	skb->nh.raw = skb->data;
+
+	skb->mac.raw = memmove(skb->data - skb->mac_len,
+			       skb->mac.raw, skb->mac_len);
+
+	ip6h = skb->nh.ipv6h;
+	ip6h->payload_len = htons(skb->len - size);
+	ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6);
+	ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *) &x->sel.saddr.a6);
+	err = 0;
+out:
+	return err;
+}
+
+static struct xfrm_mode xfrm6_beet_mode = {
+	.input = xfrm6_beet_input,
+	.output = xfrm6_beet_output,
+	.owner = THIS_MODULE,
+	.encap = XFRM_MODE_BEET,
+};
+
+static int __init xfrm6_beet_init(void)
+{
+	return xfrm_register_mode(&xfrm6_beet_mode, AF_INET6);
+}
+
+static void __exit xfrm6_beet_exit(void)
+{
+	int err;
+
+	err = xfrm_unregister_mode(&xfrm6_beet_mode, AF_INET6);
+	BUG_ON(err);
+}
+
+module_init(xfrm6_beet_init);
+module_exit(xfrm6_beet_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_BEET);
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 3bcdb46..d50a020 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -79,7 +79,7 @@
 
 hashbin_t *ircomm_tty = NULL;
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
 	.open            = ircomm_tty_open,
 	.close           = ircomm_tty_close,
 	.write           = ircomm_tty_write,
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 0a28d2c..ce94732 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -365,7 +365,7 @@
 
 config NETFILTER_XT_MATCH_PHYSDEV
 	tristate '"physdev" match support'
-	depends on NETFILTER_XTABLES && BRIDGE_NETFILTER
+	depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER
 	help
 	  Physdev packet matching matches against the physical bridge ports
 	  the IP packet arrived on or will leave by.
diff --git a/net/sched/estimator.c b/net/sched/estimator.c
deleted file mode 100644
index 0ebc98e..0000000
--- a/net/sched/estimator.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * net/sched/estimator.c	Simple rate estimator.
- *
- *		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.
- *
- * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- */
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.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/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/rtnetlink.h>
-#include <linux/init.h>
-#include <net/sock.h>
-#include <net/pkt_sched.h>
-
-/*
-   This code is NOT intended to be used for statistics collection,
-   its purpose is to provide a base for statistical multiplexing
-   for controlled load service.
-   If you need only statistics, run a user level daemon which
-   periodically reads byte counters.
-
-   Unfortunately, rate estimation is not a very easy task.
-   F.e. I did not find a simple way to estimate the current peak rate
-   and even failed to formulate the problem 8)8)
-
-   So I preferred not to built an estimator into the scheduler,
-   but run this task separately.
-   Ideally, it should be kernel thread(s), but for now it runs
-   from timers, which puts apparent top bounds on the number of rated
-   flows, has minimal overhead on small, but is enough
-   to handle controlled load service, sets of aggregates.
-
-   We measure rate over A=(1<<interval) seconds and evaluate EWMA:
-
-   avrate = avrate*(1-W) + rate*W
-
-   where W is chosen as negative power of 2: W = 2^(-ewma_log)
-
-   The resulting time constant is:
-
-   T = A/(-ln(1-W))
-
-
-   NOTES.
-
-   * The stored value for avbps is scaled by 2^5, so that maximal
-     rate is ~1Gbit, avpps is scaled by 2^10.
-
-   * Minimal interval is HZ/4=250msec (it is the greatest common divisor
-     for HZ=100 and HZ=1024 8)), maximal interval
-     is (HZ*2^EST_MAX_INTERVAL)/4 = 8sec. Shorter intervals
-     are too expensive, longer ones can be implemented
-     at user level painlessly.
- */
-
-#define EST_MAX_INTERVAL	5
-
-struct qdisc_estimator
-{
-	struct qdisc_estimator	*next;
-	struct tc_stats		*stats;
-	spinlock_t		*stats_lock;
-	unsigned		interval;
-	int			ewma_log;
-	u64			last_bytes;
-	u32			last_packets;
-	u32			avpps;
-	u32			avbps;
-};
-
-struct qdisc_estimator_head
-{
-	struct timer_list	timer;
-	struct qdisc_estimator	*list;
-};
-
-static struct qdisc_estimator_head elist[EST_MAX_INTERVAL+1];
-
-/* Estimator array lock */
-static DEFINE_RWLOCK(est_lock);
-
-static void est_timer(unsigned long arg)
-{
-	int idx = (int)arg;
-	struct qdisc_estimator *e;
-
-	read_lock(&est_lock);
-	for (e = elist[idx].list; e; e = e->next) {
-		struct tc_stats *st = e->stats;
-		u64 nbytes;
-		u32 npackets;
-		u32 rate;
-
-		spin_lock(e->stats_lock);
-		nbytes = st->bytes;
-		npackets = st->packets;
-		rate = (nbytes - e->last_bytes)<<(7 - idx);
-		e->last_bytes = nbytes;
-		e->avbps += ((long)rate - (long)e->avbps) >> e->ewma_log;
-		st->bps = (e->avbps+0xF)>>5;
-
-		rate = (npackets - e->last_packets)<<(12 - idx);
-		e->last_packets = npackets;
-		e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log;
-		e->stats->pps = (e->avpps+0x1FF)>>10;
-		spin_unlock(e->stats_lock);
-	}
-
-	mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
-	read_unlock(&est_lock);
-}
-
-int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, struct rtattr *opt)
-{
-	struct qdisc_estimator *est;
-	struct tc_estimator *parm = RTA_DATA(opt);
-
-	if (RTA_PAYLOAD(opt) < sizeof(*parm))
-		return -EINVAL;
-
-	if (parm->interval < -2 || parm->interval > 3)
-		return -EINVAL;
-
-	est = kzalloc(sizeof(*est), GFP_KERNEL);
-	if (est == NULL)
-		return -ENOBUFS;
-
-	est->interval = parm->interval + 2;
-	est->stats = stats;
-	est->stats_lock = stats_lock;
-	est->ewma_log = parm->ewma_log;
-	est->last_bytes = stats->bytes;
-	est->avbps = stats->bps<<5;
-	est->last_packets = stats->packets;
-	est->avpps = stats->pps<<10;
-
-	est->next = elist[est->interval].list;
-	if (est->next == NULL) {
-		init_timer(&elist[est->interval].timer);
-		elist[est->interval].timer.data = est->interval;
-		elist[est->interval].timer.expires = jiffies + ((HZ<<est->interval)/4);
-		elist[est->interval].timer.function = est_timer;
-		add_timer(&elist[est->interval].timer);
-	}
-	write_lock_bh(&est_lock);
-	elist[est->interval].list = est;
-	write_unlock_bh(&est_lock);
-	return 0;
-}
-
-void qdisc_kill_estimator(struct tc_stats *stats)
-{
-	int idx;
-	struct qdisc_estimator *est, **pest;
-
-	for (idx=0; idx <= EST_MAX_INTERVAL; idx++) {
-		int killed = 0;
-		pest = &elist[idx].list;
-		while ((est=*pest) != NULL) {
-			if (est->stats != stats) {
-				pest = &est->next;
-				continue;
-			}
-
-			write_lock_bh(&est_lock);
-			*pest = est->next;
-			write_unlock_bh(&est_lock);
-
-			kfree(est);
-			killed++;
-		}
-		if (killed && elist[idx].list == NULL)
-			del_timer(&elist[idx].timer);
-	}
-}
-
-EXPORT_SYMBOL(qdisc_kill_estimator);
-EXPORT_SYMBOL(qdisc_new_estimator);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 6c058e3..bb3ddd4 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -391,7 +391,7 @@
 /* If this triggers, it is a bug in this code, but it need not be fatal */
 static void htb_safe_rb_erase(struct rb_node *rb, struct rb_root *root)
 {
-	if (!RB_EMPTY_NODE(rb)) {
+	if (RB_EMPTY_NODE(rb)) {
 		WARN_ON(1);
 	} else {
 		rb_erase(rb, root);
diff --git a/net/socket.c b/net/socket.c
index 01918f7..6c9b9b3 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -825,7 +825,7 @@
 			break;
 		case FIOGETOWN:
 		case SIOCGPGRP:
-			err = put_user(sock->file->f_owner.pid,
+			err = put_user(f_getown(sock->file),
 				       (int __user *)argp);
 			break;
 		case SIOCGIFBR:
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index a6ed2d2..b36b946 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1,5 +1,5 @@
 /*
- * linux/net/sunrpc/auth_gss.c
+ * linux/net/sunrpc/auth_gss/auth_gss.c
  *
  * RPCSEC_GSS client authentication.
  * 
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 638c0b5..447d9ae 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -903,9 +903,9 @@
 struct gss_svc_data {
 	/* decoded gss client cred: */
 	struct rpc_gss_wire_cred	clcred;
-	/* pointer to the beginning of the procedure-specific results,
-	 * which may be encrypted/checksummed in svcauth_gss_release: */
-	__be32				*body_start;
+	/* save a pointer to the beginning of the encoded verifier,
+	 * for use in encryption/checksumming in svcauth_gss_release: */
+	__be32				*verf_start;
 	struct rsc			*rsci;
 };
 
@@ -968,7 +968,7 @@
 	if (!svcdata)
 		goto auth_err;
 	rqstp->rq_auth_data = svcdata;
-	svcdata->body_start = NULL;
+	svcdata->verf_start = NULL;
 	svcdata->rsci = NULL;
 	gc = &svcdata->clcred;
 
@@ -1097,6 +1097,7 @@
 		goto complete;
 	case RPC_GSS_PROC_DATA:
 		*authp = rpcsec_gsserr_ctxproblem;
+		svcdata->verf_start = resv->iov_base + resv->iov_len;
 		if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
 			goto auth_err;
 		rqstp->rq_cred = rsci->cred;
@@ -1110,7 +1111,6 @@
 					gc->gc_seq, rsci->mechctx))
 				goto auth_err;
 			/* placeholders for length and seq. number: */
-			svcdata->body_start = resv->iov_base + resv->iov_len;
 			svc_putnl(resv, 0);
 			svc_putnl(resv, 0);
 			break;
@@ -1119,7 +1119,6 @@
 					gc->gc_seq, rsci->mechctx))
 				goto auth_err;
 			/* placeholders for length and seq. number: */
-			svcdata->body_start = resv->iov_base + resv->iov_len;
 			svc_putnl(resv, 0);
 			svc_putnl(resv, 0);
 			break;
@@ -1147,6 +1146,32 @@
 	return ret;
 }
 
+u32 *
+svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd)
+{
+	u32 *p, verf_len;
+
+	p = gsd->verf_start;
+	gsd->verf_start = NULL;
+
+	/* If the reply stat is nonzero, don't wrap: */
+	if (*(p-1) != rpc_success)
+		return NULL;
+	/* Skip the verifier: */
+	p += 1;
+	verf_len = ntohl(*p++);
+	p += XDR_QUADLEN(verf_len);
+	/* move accept_stat to right place: */
+	memcpy(p, p + 2, 4);
+	/* Also don't wrap if the accept stat is nonzero: */
+	if (*p != rpc_success) {
+		resbuf->head[0].iov_len -= 2 * 4;
+		return NULL;
+	}
+	p++;
+	return p;
+}
+
 static inline int
 svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
 {
@@ -1160,17 +1185,9 @@
 	int integ_offset, integ_len;
 	int stat = -EINVAL;
 
-	p = gsd->body_start;
-	gsd->body_start = NULL;
-	/* move accept_stat to right place: */
-	memcpy(p, p + 2, 4);
-	/* Don't wrap in failure case: */
-	/* Counting on not getting here if call was not even accepted! */
-	if (*p != rpc_success) {
-		resbuf->head[0].iov_len -= 2 * 4;
+	p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
+	if (p == NULL)
 		goto out;
-	}
-	p++;
 	integ_offset = (u8 *)(p + 1) - (u8 *)resbuf->head[0].iov_base;
 	integ_len = resbuf->len - integ_offset;
 	BUG_ON(integ_len % 4);
@@ -1191,7 +1208,6 @@
 		resbuf->tail[0].iov_base = resbuf->head[0].iov_base
 						+ resbuf->head[0].iov_len;
 		resbuf->tail[0].iov_len = 0;
-		rqstp->rq_restailpage = 0;
 		resv = &resbuf->tail[0];
 	} else {
 		resv = &resbuf->tail[0];
@@ -1223,24 +1239,16 @@
 	int offset;
 	int pad;
 
-	p = gsd->body_start;
-	gsd->body_start = NULL;
-	/* move accept_stat to right place: */
-	memcpy(p, p + 2, 4);
-	/* Don't wrap in failure case: */
-	/* Counting on not getting here if call was not even accepted! */
-	if (*p != rpc_success) {
-		resbuf->head[0].iov_len -= 2 * 4;
+	p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
+	if (p == NULL)
 		return 0;
-	}
-	p++;
 	len = p++;
 	offset = (u8 *)p - (u8 *)resbuf->head[0].iov_base;
 	*p++ = htonl(gc->gc_seq);
 	inpages = resbuf->pages;
 	/* XXX: Would be better to write some xdr helper functions for
 	 * nfs{2,3,4}xdr.c that place the data right, instead of copying: */
-	if (resbuf->tail[0].iov_base && rqstp->rq_restailpage == 0) {
+	if (resbuf->tail[0].iov_base) {
 		BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base
 							+ PAGE_SIZE);
 		BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base);
@@ -1258,7 +1266,6 @@
 		resbuf->tail[0].iov_base = resbuf->head[0].iov_base
 			+ resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE;
 		resbuf->tail[0].iov_len = 0;
-		rqstp->rq_restailpage = 0;
 	}
 	if (gss_wrap(gsd->rsci->mechctx, offset, resbuf, inpages))
 		return -ENOMEM;
@@ -1282,7 +1289,7 @@
 	if (gc->gc_proc != RPC_GSS_PROC_DATA)
 		goto out;
 	/* Release can be called twice, but we only wrap once. */
-	if (gsd->body_start == NULL)
+	if (gsd->verf_start == NULL)
 		goto out;
 	/* normally not set till svc_send, but we need it here: */
 	/* XXX: what for?  Do we mess it up the moment we call svc_putu32
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 124ff0c..78696f2 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -161,10 +161,10 @@
 	}
 
 	/* save the nodename */
-	clnt->cl_nodelen = strlen(system_utsname.nodename);
+	clnt->cl_nodelen = strlen(utsname()->nodename);
 	if (clnt->cl_nodelen > UNX_MAXNODENAME)
 		clnt->cl_nodelen = UNX_MAXNODENAME;
-	memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
+	memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
 	return clnt;
 
 out_no_auth:
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 26c0531..192dff5 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -70,6 +70,8 @@
 /* RPC server stuff */
 EXPORT_SYMBOL(svc_create);
 EXPORT_SYMBOL(svc_create_thread);
+EXPORT_SYMBOL(svc_create_pooled);
+EXPORT_SYMBOL(svc_set_num_threads);
 EXPORT_SYMBOL(svc_exit_thread);
 EXPORT_SYMBOL(svc_destroy);
 EXPORT_SYMBOL(svc_drop);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 44b8d9d..c2c8bb2 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -4,6 +4,10 @@
  * High-level RPC service routines
  *
  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ *
+ * Multiple threads pools and NUMAisation
+ * Copyright (c) 2006 Silicon Graphics, Inc.
+ * by Greg Banks <gnb@melbourne.sgi.com>
  */
 
 #include <linux/linkage.h>
@@ -12,6 +16,8 @@
 #include <linux/net.h>
 #include <linux/in.h>
 #include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
@@ -23,14 +29,252 @@
 #define RPC_PARANOIA 1
 
 /*
+ * Mode for mapping cpus to pools.
+ */
+enum {
+	SVC_POOL_NONE = -1,	/* uninitialised, choose one of the others */
+	SVC_POOL_GLOBAL,	/* no mapping, just a single global pool
+				 * (legacy & UP mode) */
+	SVC_POOL_PERCPU,	/* one pool per cpu */
+	SVC_POOL_PERNODE	/* one pool per numa node */
+};
+
+/*
+ * Structure for mapping cpus to pools and vice versa.
+ * Setup once during sunrpc initialisation.
+ */
+static struct svc_pool_map {
+	int mode;			/* Note: int not enum to avoid
+					 * warnings about "enumeration value
+					 * not handled in switch" */
+	unsigned int npools;
+	unsigned int *pool_to;		/* maps pool id to cpu or node */
+	unsigned int *to_pool;		/* maps cpu or node to pool id */
+} svc_pool_map = {
+	.mode = SVC_POOL_NONE
+};
+
+
+/*
+ * Detect best pool mapping mode heuristically,
+ * according to the machine's topology.
+ */
+static int
+svc_pool_map_choose_mode(void)
+{
+	unsigned int node;
+
+	if (num_online_nodes() > 1) {
+		/*
+		 * Actually have multiple NUMA nodes,
+		 * so split pools on NUMA node boundaries
+		 */
+		return SVC_POOL_PERNODE;
+	}
+
+	node = any_online_node(node_online_map);
+	if (nr_cpus_node(node) > 2) {
+		/*
+		 * Non-trivial SMP, or CONFIG_NUMA on
+		 * non-NUMA hardware, e.g. with a generic
+		 * x86_64 kernel on Xeons.  In this case we
+		 * want to divide the pools on cpu boundaries.
+		 */
+		return SVC_POOL_PERCPU;
+	}
+
+	/* default: one global pool */
+	return SVC_POOL_GLOBAL;
+}
+
+/*
+ * Allocate the to_pool[] and pool_to[] arrays.
+ * Returns 0 on success or an errno.
+ */
+static int
+svc_pool_map_alloc_arrays(struct svc_pool_map *m, unsigned int maxpools)
+{
+	m->to_pool = kcalloc(maxpools, sizeof(unsigned int), GFP_KERNEL);
+	if (!m->to_pool)
+		goto fail;
+	m->pool_to = kcalloc(maxpools, sizeof(unsigned int), GFP_KERNEL);
+	if (!m->pool_to)
+		goto fail_free;
+
+	return 0;
+
+fail_free:
+	kfree(m->to_pool);
+fail:
+	return -ENOMEM;
+}
+
+/*
+ * Initialise the pool map for SVC_POOL_PERCPU mode.
+ * Returns number of pools or <0 on error.
+ */
+static int
+svc_pool_map_init_percpu(struct svc_pool_map *m)
+{
+	unsigned int maxpools = highest_possible_processor_id()+1;
+	unsigned int pidx = 0;
+	unsigned int cpu;
+	int err;
+
+	err = svc_pool_map_alloc_arrays(m, maxpools);
+	if (err)
+		return err;
+
+	for_each_online_cpu(cpu) {
+		BUG_ON(pidx > maxpools);
+		m->to_pool[cpu] = pidx;
+		m->pool_to[pidx] = cpu;
+		pidx++;
+	}
+	/* cpus brought online later all get mapped to pool0, sorry */
+
+	return pidx;
+};
+
+
+/*
+ * Initialise the pool map for SVC_POOL_PERNODE mode.
+ * Returns number of pools or <0 on error.
+ */
+static int
+svc_pool_map_init_pernode(struct svc_pool_map *m)
+{
+	unsigned int maxpools = highest_possible_node_id()+1;
+	unsigned int pidx = 0;
+	unsigned int node;
+	int err;
+
+	err = svc_pool_map_alloc_arrays(m, maxpools);
+	if (err)
+		return err;
+
+	for_each_node_with_cpus(node) {
+		/* some architectures (e.g. SN2) have cpuless nodes */
+		BUG_ON(pidx > maxpools);
+		m->to_pool[node] = pidx;
+		m->pool_to[pidx] = node;
+		pidx++;
+	}
+	/* nodes brought online later all get mapped to pool0, sorry */
+
+	return pidx;
+}
+
+
+/*
+ * Build the global map of cpus to pools and vice versa.
+ */
+static unsigned int
+svc_pool_map_init(void)
+{
+	struct svc_pool_map *m = &svc_pool_map;
+	int npools = -1;
+
+	if (m->mode != SVC_POOL_NONE)
+		return m->npools;
+
+	m->mode = svc_pool_map_choose_mode();
+
+	switch (m->mode) {
+	case SVC_POOL_PERCPU:
+		npools = svc_pool_map_init_percpu(m);
+		break;
+	case SVC_POOL_PERNODE:
+		npools = svc_pool_map_init_pernode(m);
+		break;
+	}
+
+	if (npools < 0) {
+		/* default, or memory allocation failure */
+		npools = 1;
+		m->mode = SVC_POOL_GLOBAL;
+	}
+	m->npools = npools;
+
+	return m->npools;
+}
+
+/*
+ * Set the current thread's cpus_allowed mask so that it
+ * will only run on cpus in the given pool.
+ *
+ * Returns 1 and fills in oldmask iff a cpumask was applied.
+ */
+static inline int
+svc_pool_map_set_cpumask(unsigned int pidx, cpumask_t *oldmask)
+{
+	struct svc_pool_map *m = &svc_pool_map;
+	unsigned int node; /* or cpu */
+
+	/*
+	 * The caller checks for sv_nrpools > 1, which
+	 * implies that we've been initialized and the
+	 * map mode is not NONE.
+	 */
+	BUG_ON(m->mode == SVC_POOL_NONE);
+
+	switch (m->mode)
+	{
+	default:
+		return 0;
+	case SVC_POOL_PERCPU:
+		node = m->pool_to[pidx];
+		*oldmask = current->cpus_allowed;
+		set_cpus_allowed(current, cpumask_of_cpu(node));
+		return 1;
+	case SVC_POOL_PERNODE:
+		node = m->pool_to[pidx];
+		*oldmask = current->cpus_allowed;
+		set_cpus_allowed(current, node_to_cpumask(node));
+		return 1;
+	}
+}
+
+/*
+ * Use the mapping mode to choose a pool for a given CPU.
+ * Used when enqueueing an incoming RPC.  Always returns
+ * a non-NULL pool pointer.
+ */
+struct svc_pool *
+svc_pool_for_cpu(struct svc_serv *serv, int cpu)
+{
+	struct svc_pool_map *m = &svc_pool_map;
+	unsigned int pidx = 0;
+
+	/*
+	 * SVC_POOL_NONE happens in a pure client when
+	 * lockd is brought up, so silently treat it the
+	 * same as SVC_POOL_GLOBAL.
+	 */
+
+	switch (m->mode) {
+	case SVC_POOL_PERCPU:
+		pidx = m->to_pool[cpu];
+		break;
+	case SVC_POOL_PERNODE:
+		pidx = m->to_pool[cpu_to_node(cpu)];
+		break;
+	}
+	return &serv->sv_pools[pidx % serv->sv_nrpools];
+}
+
+
+/*
  * Create an RPC service
  */
-struct svc_serv *
-svc_create(struct svc_program *prog, unsigned int bufsize)
+static struct svc_serv *
+__svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
+	   void (*shutdown)(struct svc_serv *serv))
 {
 	struct svc_serv	*serv;
 	int vers;
 	unsigned int xdrsize;
+	unsigned int i;
 
 	if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
 		return NULL;
@@ -39,6 +283,7 @@
 	serv->sv_nrthreads = 1;
 	serv->sv_stats     = prog->pg_stats;
 	serv->sv_bufsz	   = bufsize? bufsize : 4096;
+	serv->sv_shutdown  = shutdown;
 	xdrsize = 0;
 	while (prog) {
 		prog->pg_lovers = prog->pg_nvers-1;
@@ -53,20 +298,68 @@
 		prog = prog->pg_next;
 	}
 	serv->sv_xdrsize   = xdrsize;
-	INIT_LIST_HEAD(&serv->sv_threads);
-	INIT_LIST_HEAD(&serv->sv_sockets);
 	INIT_LIST_HEAD(&serv->sv_tempsocks);
 	INIT_LIST_HEAD(&serv->sv_permsocks);
+	init_timer(&serv->sv_temptimer);
 	spin_lock_init(&serv->sv_lock);
 
+	serv->sv_nrpools = npools;
+	serv->sv_pools =
+		kcalloc(sizeof(struct svc_pool), serv->sv_nrpools,
+			GFP_KERNEL);
+	if (!serv->sv_pools) {
+		kfree(serv);
+		return NULL;
+	}
+
+	for (i = 0; i < serv->sv_nrpools; i++) {
+		struct svc_pool *pool = &serv->sv_pools[i];
+
+		dprintk("initialising pool %u for %s\n",
+				i, serv->sv_name);
+
+		pool->sp_id = i;
+		INIT_LIST_HEAD(&pool->sp_threads);
+		INIT_LIST_HEAD(&pool->sp_sockets);
+		INIT_LIST_HEAD(&pool->sp_all_threads);
+		spin_lock_init(&pool->sp_lock);
+	}
+
+
 	/* Remove any stale portmap registrations */
 	svc_register(serv, 0, 0);
 
 	return serv;
 }
 
+struct svc_serv *
+svc_create(struct svc_program *prog, unsigned int bufsize,
+		void (*shutdown)(struct svc_serv *serv))
+{
+	return __svc_create(prog, bufsize, /*npools*/1, shutdown);
+}
+
+struct svc_serv *
+svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
+		void (*shutdown)(struct svc_serv *serv),
+		  svc_thread_fn func, int sig, struct module *mod)
+{
+	struct svc_serv *serv;
+	unsigned int npools = svc_pool_map_init();
+
+	serv = __svc_create(prog, bufsize, npools, shutdown);
+
+	if (serv != NULL) {
+		serv->sv_function = func;
+		serv->sv_kill_signal = sig;
+		serv->sv_module = mod;
+	}
+
+	return serv;
+}
+
 /*
- * Destroy an RPC service
+ * Destroy an RPC service.  Should be called with the BKL held
  */
 void
 svc_destroy(struct svc_serv *serv)
@@ -85,12 +378,17 @@
 	} else
 		printk("svc_destroy: no threads for serv=%p!\n", serv);
 
+	del_timer_sync(&serv->sv_temptimer);
+
 	while (!list_empty(&serv->sv_tempsocks)) {
 		svsk = list_entry(serv->sv_tempsocks.next,
 				  struct svc_sock,
 				  sk_list);
 		svc_delete_socket(svsk);
 	}
+	if (serv->sv_shutdown)
+		serv->sv_shutdown(serv);
+
 	while (!list_empty(&serv->sv_permsocks)) {
 		svsk = list_entry(serv->sv_permsocks.next,
 				  struct svc_sock,
@@ -102,6 +400,7 @@
 
 	/* Unregister service with the portmapper */
 	svc_register(serv, 0, 0);
+	kfree(serv->sv_pools);
 	kfree(serv);
 }
 
@@ -118,18 +417,15 @@
 	if (size > RPCSVC_MAXPAYLOAD)
 		size = RPCSVC_MAXPAYLOAD;
 	pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE;
-	rqstp->rq_argused = 0;
-	rqstp->rq_resused = 0;
 	arghi = 0;
 	BUG_ON(pages > RPCSVC_MAXPAGES);
 	while (pages) {
 		struct page *p = alloc_page(GFP_KERNEL);
 		if (!p)
 			break;
-		rqstp->rq_argpages[arghi++] = p;
+		rqstp->rq_pages[arghi++] = p;
 		pages--;
 	}
-	rqstp->rq_arghi = arghi;
 	return ! pages;
 }
 
@@ -139,24 +435,25 @@
 static void
 svc_release_buffer(struct svc_rqst *rqstp)
 {
-	while (rqstp->rq_arghi)
-		put_page(rqstp->rq_argpages[--rqstp->rq_arghi]);
-	while (rqstp->rq_resused) {
-		if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
-			continue;
-		put_page(rqstp->rq_respages[rqstp->rq_resused]);
-	}
-	rqstp->rq_argused = 0;
+	int i;
+	for (i=0; i<ARRAY_SIZE(rqstp->rq_pages); i++)
+		if (rqstp->rq_pages[i])
+			put_page(rqstp->rq_pages[i]);
 }
 
 /*
- * Create a server thread
+ * Create a thread in the given pool.  Caller must hold BKL.
+ * On a NUMA or SMP machine, with a multi-pool serv, the thread
+ * will be restricted to run on the cpus belonging to the pool.
  */
-int
-svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
+static int
+__svc_create_thread(svc_thread_fn func, struct svc_serv *serv,
+		    struct svc_pool *pool)
 {
 	struct svc_rqst	*rqstp;
 	int		error = -ENOMEM;
+	int		have_oldmask = 0;
+	cpumask_t	oldmask;
 
 	rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL);
 	if (!rqstp)
@@ -170,8 +467,21 @@
 		goto out_thread;
 
 	serv->sv_nrthreads++;
+	spin_lock_bh(&pool->sp_lock);
+	pool->sp_nrthreads++;
+	list_add(&rqstp->rq_all, &pool->sp_all_threads);
+	spin_unlock_bh(&pool->sp_lock);
 	rqstp->rq_server = serv;
+	rqstp->rq_pool = pool;
+
+	if (serv->sv_nrpools > 1)
+		have_oldmask = svc_pool_map_set_cpumask(pool->sp_id, &oldmask);
+
 	error = kernel_thread((int (*)(void *)) func, rqstp, 0);
+
+	if (have_oldmask)
+		set_cpus_allowed(current, oldmask);
+
 	if (error < 0)
 		goto out_thread;
 	svc_sock_update_bufs(serv);
@@ -185,17 +495,136 @@
 }
 
 /*
- * Destroy an RPC server thread
+ * Create a thread in the default pool.  Caller must hold BKL.
+ */
+int
+svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
+{
+	return __svc_create_thread(func, serv, &serv->sv_pools[0]);
+}
+
+/*
+ * Choose a pool in which to create a new thread, for svc_set_num_threads
+ */
+static inline struct svc_pool *
+choose_pool(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
+{
+	if (pool != NULL)
+		return pool;
+
+ 	return &serv->sv_pools[(*state)++ % serv->sv_nrpools];
+}
+
+/*
+ * Choose a thread to kill, for svc_set_num_threads
+ */
+static inline struct task_struct *
+choose_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
+{
+	unsigned int i;
+	struct task_struct *task = NULL;
+
+	if (pool != NULL) {
+		spin_lock_bh(&pool->sp_lock);
+	} else {
+		/* choose a pool in round-robin fashion */
+ 		for (i = 0; i < serv->sv_nrpools; i++) {
+ 			pool = &serv->sv_pools[--(*state) % serv->sv_nrpools];
+			spin_lock_bh(&pool->sp_lock);
+ 			if (!list_empty(&pool->sp_all_threads))
+ 				goto found_pool;
+			spin_unlock_bh(&pool->sp_lock);
+ 		}
+		return NULL;
+	}
+
+found_pool:
+	if (!list_empty(&pool->sp_all_threads)) {
+		struct svc_rqst *rqstp;
+
+		/*
+		 * Remove from the pool->sp_all_threads list
+		 * so we don't try to kill it again.
+		 */
+		rqstp = list_entry(pool->sp_all_threads.next, struct svc_rqst, rq_all);
+		list_del_init(&rqstp->rq_all);
+		task = rqstp->rq_task;
+    	}
+	spin_unlock_bh(&pool->sp_lock);
+
+	return task;
+}
+
+/*
+ * Create or destroy enough new threads to make the number
+ * of threads the given number.  If `pool' is non-NULL, applies
+ * only to threads in that pool, otherwise round-robins between
+ * all pools.  Must be called with a svc_get() reference and
+ * the BKL held.
+ *
+ * Destroying threads relies on the service threads filling in
+ * rqstp->rq_task, which only the nfs ones do.  Assumes the serv
+ * has been created using svc_create_pooled().
+ *
+ * Based on code that used to be in nfsd_svc() but tweaked
+ * to be pool-aware.
+ */
+int
+svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
+{
+	struct task_struct *victim;
+	int error = 0;
+	unsigned int state = serv->sv_nrthreads-1;
+
+	if (pool == NULL) {
+		/* The -1 assumes caller has done a svc_get() */
+		nrservs -= (serv->sv_nrthreads-1);
+	} else {
+		spin_lock_bh(&pool->sp_lock);
+		nrservs -= pool->sp_nrthreads;
+		spin_unlock_bh(&pool->sp_lock);
+	}
+
+	/* create new threads */
+	while (nrservs > 0) {
+		nrservs--;
+		__module_get(serv->sv_module);
+		error = __svc_create_thread(serv->sv_function, serv,
+					    choose_pool(serv, pool, &state));
+		if (error < 0) {
+			module_put(serv->sv_module);
+			break;
+		}
+	}
+	/* destroy old threads */
+	while (nrservs < 0 &&
+	       (victim = choose_victim(serv, pool, &state)) != NULL) {
+		send_sig(serv->sv_kill_signal, victim, 1);
+		nrservs++;
+	}
+
+	return error;
+}
+
+/*
+ * Called from a server thread as it's exiting.  Caller must hold BKL.
  */
 void
 svc_exit_thread(struct svc_rqst *rqstp)
 {
 	struct svc_serv	*serv = rqstp->rq_server;
+	struct svc_pool	*pool = rqstp->rq_pool;
 
 	svc_release_buffer(rqstp);
 	kfree(rqstp->rq_resp);
 	kfree(rqstp->rq_argp);
 	kfree(rqstp->rq_auth_data);
+
+	spin_lock_bh(&pool->sp_lock);
+	pool->sp_nrthreads--;
+	list_del(&rqstp->rq_all);
+	spin_unlock_bh(&pool->sp_lock);
+
 	kfree(rqstp);
 
 	/* Release the server */
@@ -215,23 +644,32 @@
 	unsigned long		flags;
 	int			i, error = 0, dummy;
 
-	progp = serv->sv_program;
-
-	dprintk("RPC: svc_register(%s, %s, %d)\n",
-		progp->pg_name, proto == IPPROTO_UDP? "udp" : "tcp", port);
-
 	if (!port)
 		clear_thread_flag(TIF_SIGPENDING);
 
-	for (i = 0; i < progp->pg_nvers; i++) {
-		if (progp->pg_vers[i] == NULL)
-			continue;
-		error = rpc_register(progp->pg_prog, i, proto, port, &dummy);
-		if (error < 0)
-			break;
-		if (port && !dummy) {
-			error = -EACCES;
-			break;
+	for (progp = serv->sv_program; progp; progp = progp->pg_next) {
+		for (i = 0; i < progp->pg_nvers; i++) {
+			if (progp->pg_vers[i] == NULL)
+				continue;
+
+			dprintk("RPC: svc_register(%s, %s, %d, %d)%s\n",
+					progp->pg_name,
+					proto == IPPROTO_UDP?  "udp" : "tcp",
+					port,
+					i,
+					progp->pg_vers[i]->vs_hidden?
+						" (but not telling portmap)" : "");
+
+			if (progp->pg_vers[i]->vs_hidden)
+				continue;
+
+			error = rpc_register(progp->pg_prog, i, proto, port, &dummy);
+			if (error < 0)
+				break;
+			if (port && !dummy) {
+				error = -EACCES;
+				break;
+			}
 		}
 	}
 
@@ -248,19 +686,20 @@
  * Process the RPC request.
  */
 int
-svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_process(struct svc_rqst *rqstp)
 {
 	struct svc_program	*progp;
 	struct svc_version	*versp = NULL;	/* compiler food */
 	struct svc_procedure	*procp = NULL;
 	struct kvec *		argv = &rqstp->rq_arg.head[0];
 	struct kvec *		resv = &rqstp->rq_res.head[0];
+	struct svc_serv		*serv = rqstp->rq_server;
 	kxdrproc_t		xdr;
 	__be32			*statp;
 	u32			dir, prog, vers, proc;
 	__be32			auth_stat, rpc_stat;
 	int			auth_res;
-	__be32			*accept_statp;
+	__be32			*reply_statp;
 
 	rpc_stat = rpc_success;
 
@@ -270,10 +709,10 @@
 	/* setup response xdr_buf.
 	 * Initially it has just one page 
 	 */
-	svc_take_page(rqstp); /* must succeed */
+	rqstp->rq_resused = 1;
 	resv->iov_base = page_address(rqstp->rq_respages[0]);
 	resv->iov_len = 0;
-	rqstp->rq_res.pages = rqstp->rq_respages+1;
+	rqstp->rq_res.pages = rqstp->rq_respages + 1;
 	rqstp->rq_res.len = 0;
 	rqstp->rq_res.page_base = 0;
 	rqstp->rq_res.page_len = 0;
@@ -301,7 +740,7 @@
 		goto err_bad_rpc;
 
 	/* Save position in case we later decide to reject: */
-	accept_statp = resv->iov_base + resv->iov_len;
+	reply_statp = resv->iov_base + resv->iov_len;
 
 	svc_putnl(resv, 0);		/* ACCEPT */
 
@@ -449,7 +888,7 @@
 	dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat));
 	serv->sv_stats->rpcbadauth++;
 	/* Restore write pointer to location of accept status: */
-	xdr_ressize_check(rqstp, accept_statp);
+	xdr_ressize_check(rqstp, reply_statp);
 	svc_putnl(resv, 1);	/* REJECT */
 	svc_putnl(resv, 1);	/* AUTH_ERROR */
 	svc_putnl(resv, ntohl(auth_stat));	/* status */
@@ -489,3 +928,18 @@
 	svc_putnl(resv, ntohl(rpc_stat));
 	goto sendit;
 }
+
+/*
+ * Return (transport-specific) limit on the rpc payload.
+ */
+u32 svc_max_payload(const struct svc_rqst *rqstp)
+{
+	int max = RPCSVC_MAXPAYLOAD_TCP;
+
+	if (rqstp->rq_sock->sk_sock->type == SOCK_DGRAM)
+		max = RPCSVC_MAXPAYLOAD_UDP;
+	if (rqstp->rq_server->sv_bufsz < max)
+		max = rqstp->rq_server->sv_bufsz;
+	return max;
+}
+EXPORT_SYMBOL_GPL(svc_max_payload);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 1020d54..e1bd933 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -9,6 +9,7 @@
 #include <linux/seq_file.h>
 #include <linux/hash.h>
 #include <linux/string.h>
+#include <net/sock.h>
 
 #define RPCDBG_FACILITY	RPCDBG_AUTH
 
@@ -348,12 +349,9 @@
 
 struct auth_domain *auth_unix_lookup(struct in_addr addr)
 {
-	struct ip_map key, *ipm;
+	struct ip_map *ipm;
 	struct auth_domain *rv;
 
-	strcpy(key.m_class, "nfsd");
-	key.m_addr = addr;
-
 	ipm = ip_map_lookup("nfsd", addr);
 
 	if (!ipm)
@@ -378,6 +376,44 @@
 	cache_purge(&ip_map_cache);
 }
 
+static inline struct ip_map *
+ip_map_cached_get(struct svc_rqst *rqstp)
+{
+	struct ip_map *ipm = rqstp->rq_sock->sk_info_authunix;
+	if (ipm != NULL) {
+		if (!cache_valid(&ipm->h)) {
+			/*
+			 * The entry has been invalidated since it was
+			 * remembered, e.g. by a second mount from the
+			 * same IP address.
+			 */
+			rqstp->rq_sock->sk_info_authunix = NULL;
+			cache_put(&ipm->h, &ip_map_cache);
+			return NULL;
+		}
+		cache_get(&ipm->h);
+	}
+	return ipm;
+}
+
+static inline void
+ip_map_cached_put(struct svc_rqst *rqstp, struct ip_map *ipm)
+{
+	struct svc_sock *svsk = rqstp->rq_sock;
+
+	if (svsk->sk_sock->type == SOCK_STREAM && svsk->sk_info_authunix == NULL)
+		svsk->sk_info_authunix = ipm;	/* newly cached, keep the reference */
+	else
+		cache_put(&ipm->h, &ip_map_cache);
+}
+
+void
+svcauth_unix_info_release(void *info)
+{
+	struct ip_map *ipm = info;
+	cache_put(&ipm->h, &ip_map_cache);
+}
+
 static int
 svcauth_unix_set_client(struct svc_rqst *rqstp)
 {
@@ -387,8 +423,10 @@
 	if (rqstp->rq_proc == 0)
 		return SVC_OK;
 
-	ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
-			    rqstp->rq_addr.sin_addr);
+	ipm = ip_map_cached_get(rqstp);
+	if (ipm == NULL)
+		ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
+				    rqstp->rq_addr.sin_addr);
 
 	if (ipm == NULL)
 		return SVC_DENIED;
@@ -403,7 +441,7 @@
 		case 0:
 			rqstp->rq_client = &ipm->m_client->h;
 			kref_get(&rqstp->rq_client->ref);
-			cache_put(&ipm->h, &ip_map_cache);
+			ip_map_cached_put(rqstp, ipm);
 			break;
 	}
 	return SVC_OK;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 5b0fe1b..b39e7e2 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/file.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -45,13 +46,16 @@
 
 /* SMP locking strategy:
  *
- * 	svc_serv->sv_lock protects most stuff for that service.
+ *	svc_pool->sp_lock protects most of the fields of that pool.
+ * 	svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt.
+ *	when both need to be taken (rare), svc_serv->sv_lock is first.
+ *	BKL protects svc_serv->sv_nrthread.
+ *	svc_sock->sk_defer_lock protects the svc_sock->sk_deferred list
+ *	svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply.
  *
  *	Some flags can be set to certain values at any time
  *	providing that certain rules are followed:
  *
- *	SK_BUSY  can be set to 0 at any time.  
- *		svc_sock_enqueue must be called afterwards
  *	SK_CONN, SK_DATA, can be set or cleared at any time.
  *		after a set, svc_sock_enqueue must be called.	
  *		after a clear, the socket must be read/accepted
@@ -73,23 +77,30 @@
 static int svc_deferred_recv(struct svc_rqst *rqstp);
 static struct cache_deferred_req *svc_defer(struct cache_req *req);
 
+/* apparently the "standard" is that clients close
+ * idle connections after 5 minutes, servers after
+ * 6 minutes
+ *   http://www.connectathon.org/talks96/nfstcp.pdf
+ */
+static int svc_conn_age_period = 6*60;
+
 /*
- * Queue up an idle server thread.  Must have serv->sv_lock held.
+ * Queue up an idle server thread.  Must have pool->sp_lock held.
  * Note: this is really a stack rather than a queue, so that we only
- * use as many different threads as we need, and the rest don't polute
+ * use as many different threads as we need, and the rest don't pollute
  * the cache.
  */
 static inline void
-svc_serv_enqueue(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_thread_enqueue(struct svc_pool *pool, struct svc_rqst *rqstp)
 {
-	list_add(&rqstp->rq_list, &serv->sv_threads);
+	list_add(&rqstp->rq_list, &pool->sp_threads);
 }
 
 /*
- * Dequeue an nfsd thread.  Must have serv->sv_lock held.
+ * Dequeue an nfsd thread.  Must have pool->sp_lock held.
  */
 static inline void
-svc_serv_dequeue(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp)
 {
 	list_del(&rqstp->rq_list);
 }
@@ -140,7 +151,9 @@
 svc_sock_enqueue(struct svc_sock *svsk)
 {
 	struct svc_serv	*serv = svsk->sk_server;
+	struct svc_pool *pool;
 	struct svc_rqst	*rqstp;
+	int cpu;
 
 	if (!(svsk->sk_flags &
 	      ( (1<<SK_CONN)|(1<<SK_DATA)|(1<<SK_CLOSE)|(1<<SK_DEFERRED)) ))
@@ -148,10 +161,14 @@
 	if (test_bit(SK_DEAD, &svsk->sk_flags))
 		return;
 
-	spin_lock_bh(&serv->sv_lock);
+	cpu = get_cpu();
+	pool = svc_pool_for_cpu(svsk->sk_server, cpu);
+	put_cpu();
 
-	if (!list_empty(&serv->sv_threads) && 
-	    !list_empty(&serv->sv_sockets))
+	spin_lock_bh(&pool->sp_lock);
+
+	if (!list_empty(&pool->sp_threads) &&
+	    !list_empty(&pool->sp_sockets))
 		printk(KERN_ERR
 			"svc_sock_enqueue: threads and sockets both waiting??\n");
 
@@ -161,73 +178,79 @@
 		goto out_unlock;
 	}
 
-	if (test_bit(SK_BUSY, &svsk->sk_flags)) {
-		/* Don't enqueue socket while daemon is receiving */
+	/* Mark socket as busy. It will remain in this state until the
+	 * server has processed all pending data and put the socket back
+	 * on the idle list.  We update SK_BUSY atomically because
+	 * it also guards against trying to enqueue the svc_sock twice.
+	 */
+	if (test_and_set_bit(SK_BUSY, &svsk->sk_flags)) {
+		/* Don't enqueue socket while already enqueued */
 		dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk);
 		goto out_unlock;
 	}
+	BUG_ON(svsk->sk_pool != NULL);
+	svsk->sk_pool = pool;
 
 	set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
-	if (((svsk->sk_reserved + serv->sv_bufsz)*2
+	if (((atomic_read(&svsk->sk_reserved) + serv->sv_bufsz)*2
 	     > svc_sock_wspace(svsk))
 	    && !test_bit(SK_CLOSE, &svsk->sk_flags)
 	    && !test_bit(SK_CONN, &svsk->sk_flags)) {
 		/* Don't enqueue while not enough space for reply */
 		dprintk("svc: socket %p  no space, %d*2 > %ld, not enqueued\n",
-			svsk->sk_sk, svsk->sk_reserved+serv->sv_bufsz,
+			svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_bufsz,
 			svc_sock_wspace(svsk));
+		svsk->sk_pool = NULL;
+		clear_bit(SK_BUSY, &svsk->sk_flags);
 		goto out_unlock;
 	}
 	clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
 
-	/* Mark socket as busy. It will remain in this state until the
-	 * server has processed all pending data and put the socket back
-	 * on the idle list.
-	 */
-	set_bit(SK_BUSY, &svsk->sk_flags);
 
-	if (!list_empty(&serv->sv_threads)) {
-		rqstp = list_entry(serv->sv_threads.next,
+	if (!list_empty(&pool->sp_threads)) {
+		rqstp = list_entry(pool->sp_threads.next,
 				   struct svc_rqst,
 				   rq_list);
 		dprintk("svc: socket %p served by daemon %p\n",
 			svsk->sk_sk, rqstp);
-		svc_serv_dequeue(serv, rqstp);
+		svc_thread_dequeue(pool, rqstp);
 		if (rqstp->rq_sock)
 			printk(KERN_ERR 
 				"svc_sock_enqueue: server %p, rq_sock=%p!\n",
 				rqstp, rqstp->rq_sock);
 		rqstp->rq_sock = svsk;
-		svsk->sk_inuse++;
+		atomic_inc(&svsk->sk_inuse);
 		rqstp->rq_reserved = serv->sv_bufsz;
-		svsk->sk_reserved += rqstp->rq_reserved;
+		atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
+		BUG_ON(svsk->sk_pool != pool);
 		wake_up(&rqstp->rq_wait);
 	} else {
 		dprintk("svc: socket %p put into queue\n", svsk->sk_sk);
-		list_add_tail(&svsk->sk_ready, &serv->sv_sockets);
+		list_add_tail(&svsk->sk_ready, &pool->sp_sockets);
+		BUG_ON(svsk->sk_pool != pool);
 	}
 
 out_unlock:
-	spin_unlock_bh(&serv->sv_lock);
+	spin_unlock_bh(&pool->sp_lock);
 }
 
 /*
- * Dequeue the first socket.  Must be called with the serv->sv_lock held.
+ * Dequeue the first socket.  Must be called with the pool->sp_lock held.
  */
 static inline struct svc_sock *
-svc_sock_dequeue(struct svc_serv *serv)
+svc_sock_dequeue(struct svc_pool *pool)
 {
 	struct svc_sock	*svsk;
 
-	if (list_empty(&serv->sv_sockets))
+	if (list_empty(&pool->sp_sockets))
 		return NULL;
 
-	svsk = list_entry(serv->sv_sockets.next,
+	svsk = list_entry(pool->sp_sockets.next,
 			  struct svc_sock, sk_ready);
 	list_del_init(&svsk->sk_ready);
 
 	dprintk("svc: socket %p dequeued, inuse=%d\n",
-		svsk->sk_sk, svsk->sk_inuse);
+		svsk->sk_sk, atomic_read(&svsk->sk_inuse));
 
 	return svsk;
 }
@@ -241,6 +264,7 @@
 static inline void
 svc_sock_received(struct svc_sock *svsk)
 {
+	svsk->sk_pool = NULL;
 	clear_bit(SK_BUSY, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
 }
@@ -262,10 +286,8 @@
 
 	if (space < rqstp->rq_reserved) {
 		struct svc_sock *svsk = rqstp->rq_sock;
-		spin_lock_bh(&svsk->sk_server->sv_lock);
-		svsk->sk_reserved -= (rqstp->rq_reserved - space);
+		atomic_sub((rqstp->rq_reserved - space), &svsk->sk_reserved);
 		rqstp->rq_reserved = space;
-		spin_unlock_bh(&svsk->sk_server->sv_lock);
 
 		svc_sock_enqueue(svsk);
 	}
@@ -277,17 +299,11 @@
 static inline void
 svc_sock_put(struct svc_sock *svsk)
 {
-	struct svc_serv *serv = svsk->sk_server;
-
-	spin_lock_bh(&serv->sv_lock);
-	if (!--(svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
-		spin_unlock_bh(&serv->sv_lock);
+	if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
 		dprintk("svc: releasing dead socket\n");
 		sock_release(svsk->sk_sock);
 		kfree(svsk);
 	}
-	else
-		spin_unlock_bh(&serv->sv_lock);
 }
 
 static void
@@ -297,7 +313,7 @@
 
 	svc_release_skb(rqstp);
 
-	svc_free_allpages(rqstp);
+	svc_free_res_pages(rqstp);
 	rqstp->rq_res.page_len = 0;
 	rqstp->rq_res.page_base = 0;
 
@@ -321,25 +337,33 @@
 
 /*
  * External function to wake up a server waiting for data
+ * This really only makes sense for services like lockd
+ * which have exactly one thread anyway.
  */
 void
 svc_wake_up(struct svc_serv *serv)
 {
 	struct svc_rqst	*rqstp;
+	unsigned int i;
+	struct svc_pool *pool;
 
-	spin_lock_bh(&serv->sv_lock);
-	if (!list_empty(&serv->sv_threads)) {
-		rqstp = list_entry(serv->sv_threads.next,
-				   struct svc_rqst,
-				   rq_list);
-		dprintk("svc: daemon %p woken up.\n", rqstp);
-		/*
-		svc_serv_dequeue(serv, rqstp);
-		rqstp->rq_sock = NULL;
-		 */
-		wake_up(&rqstp->rq_wait);
+	for (i = 0; i < serv->sv_nrpools; i++) {
+		pool = &serv->sv_pools[i];
+
+		spin_lock_bh(&pool->sp_lock);
+		if (!list_empty(&pool->sp_threads)) {
+			rqstp = list_entry(pool->sp_threads.next,
+					   struct svc_rqst,
+					   rq_list);
+			dprintk("svc: daemon %p woken up.\n", rqstp);
+			/*
+			svc_thread_dequeue(pool, rqstp);
+			rqstp->rq_sock = NULL;
+			 */
+			wake_up(&rqstp->rq_wait);
+		}
+		spin_unlock_bh(&pool->sp_lock);
 	}
-	spin_unlock_bh(&serv->sv_lock);
 }
 
 /*
@@ -388,7 +412,8 @@
 	/* send head */
 	if (slen == xdr->head[0].iov_len)
 		flags = 0;
-	len = kernel_sendpage(sock, rqstp->rq_respages[0], 0, xdr->head[0].iov_len, flags);
+	len = kernel_sendpage(sock, rqstp->rq_respages[0], 0,
+				  xdr->head[0].iov_len, flags);
 	if (len != xdr->head[0].iov_len)
 		goto out;
 	slen -= xdr->head[0].iov_len;
@@ -413,8 +438,9 @@
 	}
 	/* send tail */
 	if (xdr->tail[0].iov_len) {
-		result = kernel_sendpage(sock, rqstp->rq_respages[rqstp->rq_restailpage],
-					     ((unsigned long)xdr->tail[0].iov_base)& (PAGE_SIZE-1),
+		result = kernel_sendpage(sock, rqstp->rq_respages[0],
+					     ((unsigned long)xdr->tail[0].iov_base)
+					        & (PAGE_SIZE-1),
 					     xdr->tail[0].iov_len, 0);
 
 		if (result > 0)
@@ -429,6 +455,56 @@
 }
 
 /*
+ * Report socket names for nfsdfs
+ */
+static int one_sock_name(char *buf, struct svc_sock *svsk)
+{
+	int len;
+
+	switch(svsk->sk_sk->sk_family) {
+	case AF_INET:
+		len = sprintf(buf, "ipv4 %s %u.%u.%u.%u %d\n",
+			      svsk->sk_sk->sk_protocol==IPPROTO_UDP?
+			      "udp" : "tcp",
+			      NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr),
+			      inet_sk(svsk->sk_sk)->num);
+		break;
+	default:
+		len = sprintf(buf, "*unknown-%d*\n",
+			       svsk->sk_sk->sk_family);
+	}
+	return len;
+}
+
+int
+svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
+{
+	struct svc_sock *svsk, *closesk = NULL;
+	int len = 0;
+
+	if (!serv)
+		return 0;
+	spin_lock(&serv->sv_lock);
+	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
+		int onelen = one_sock_name(buf+len, svsk);
+		if (toclose && strcmp(toclose, buf+len) == 0)
+			closesk = svsk;
+		else
+			len += onelen;
+	}
+	spin_unlock(&serv->sv_lock);
+	if (closesk)
+		/* Should unregister with portmap, but you cannot
+		 * unregister just one protocol...
+		 */
+		svc_delete_socket(closesk);
+	else if (toclose)
+		return -ENOENT;
+	return len;
+}
+EXPORT_SYMBOL(svc_sock_names);
+
+/*
  * Check input queue length
  */
 static int
@@ -557,7 +633,10 @@
 	    /* udp sockets need large rcvbuf as all pending
 	     * requests are still in that buffer.  sndbuf must
 	     * also be large enough that there is enough space
-	     * for one reply per thread.
+	     * for one reply per thread.  We count all threads
+	     * rather than threads in a particular pool, which
+	     * provides an upper bound on the number of threads
+	     * which will access the socket.
 	     */
 	    svc_sock_setbufsize(svsk->sk_sock,
 				(serv->sv_nrthreads+3) * serv->sv_bufsz,
@@ -631,9 +710,11 @@
 	if (len <= rqstp->rq_arg.head[0].iov_len) {
 		rqstp->rq_arg.head[0].iov_len = len;
 		rqstp->rq_arg.page_len = 0;
+		rqstp->rq_respages = rqstp->rq_pages+1;
 	} else {
 		rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len;
-		rqstp->rq_argused += (rqstp->rq_arg.page_len + PAGE_SIZE - 1)/ PAGE_SIZE;
+		rqstp->rq_respages = rqstp->rq_pages + 1 +
+			(rqstp->rq_arg.page_len + PAGE_SIZE - 1)/ PAGE_SIZE;
 	}
 
 	if (serv->sv_stats)
@@ -844,7 +925,7 @@
 					  struct svc_sock,
 					  sk_list);
 			set_bit(SK_CLOSE, &svsk->sk_flags);
-			svsk->sk_inuse ++;
+			atomic_inc(&svsk->sk_inuse);
 		}
 		spin_unlock_bh(&serv->sv_lock);
 
@@ -874,7 +955,7 @@
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct svc_serv	*serv = svsk->sk_server;
 	int		len;
-	struct kvec vec[RPCSVC_MAXPAGES];
+	struct kvec *vec;
 	int pnum, vlen;
 
 	dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
@@ -902,6 +983,11 @@
 		/* sndbuf needs to have room for one request
 		 * per thread, otherwise we can stall even when the
 		 * network isn't a bottleneck.
+		 *
+		 * We count all threads rather than threads in a
+		 * particular pool, which provides an upper bound
+		 * on the number of threads which will access the socket.
+		 *
 		 * rcvbuf just needs to be able to hold a few requests.
 		 * Normally they will be removed from the queue 
 		 * as soon a a complete request arrives.
@@ -967,15 +1053,17 @@
 	len = svsk->sk_reclen;
 	set_bit(SK_DATA, &svsk->sk_flags);
 
+	vec = rqstp->rq_vec;
 	vec[0] = rqstp->rq_arg.head[0];
 	vlen = PAGE_SIZE;
 	pnum = 1;
 	while (vlen < len) {
-		vec[pnum].iov_base = page_address(rqstp->rq_argpages[rqstp->rq_argused++]);
+		vec[pnum].iov_base = page_address(rqstp->rq_pages[pnum]);
 		vec[pnum].iov_len = PAGE_SIZE;
 		pnum++;
 		vlen += PAGE_SIZE;
 	}
+	rqstp->rq_respages = &rqstp->rq_pages[pnum];
 
 	/* Now receive data */
 	len = svc_recvfrom(rqstp, vec, pnum, len);
@@ -1117,13 +1205,17 @@
 }
 
 /*
- * Receive the next request on any socket.
+ * Receive the next request on any socket.  This code is carefully
+ * organised not to touch any cachelines in the shared svc_serv
+ * structure, only cachelines in the local svc_pool.
  */
 int
-svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
+svc_recv(struct svc_rqst *rqstp, long timeout)
 {
 	struct svc_sock		*svsk =NULL;
-	int			len;
+	struct svc_serv		*serv = rqstp->rq_server;
+	struct svc_pool		*pool = rqstp->rq_pool;
+	int			len, i;
 	int 			pages;
 	struct xdr_buf		*arg;
 	DECLARE_WAITQUEUE(wait, current);
@@ -1140,27 +1232,22 @@
 			"svc_recv: service %p, wait queue active!\n",
 			 rqstp);
 
-	/* Initialize the buffers */
-	/* first reclaim pages that were moved to response list */
-	svc_pushback_allpages(rqstp);
 
 	/* now allocate needed pages.  If we get a failure, sleep briefly */
 	pages = 2 + (serv->sv_bufsz + PAGE_SIZE -1) / PAGE_SIZE;
-	while (rqstp->rq_arghi < pages) {
-		struct page *p = alloc_page(GFP_KERNEL);
-		if (!p) {
-			schedule_timeout_uninterruptible(msecs_to_jiffies(500));
-			continue;
+	for (i=0; i < pages ; i++)
+		while (rqstp->rq_pages[i] == NULL) {
+			struct page *p = alloc_page(GFP_KERNEL);
+			if (!p)
+				schedule_timeout_uninterruptible(msecs_to_jiffies(500));
+			rqstp->rq_pages[i] = p;
 		}
-		rqstp->rq_argpages[rqstp->rq_arghi++] = p;
-	}
 
 	/* Make arg->head point to first page and arg->pages point to rest */
 	arg = &rqstp->rq_arg;
-	arg->head[0].iov_base = page_address(rqstp->rq_argpages[0]);
+	arg->head[0].iov_base = page_address(rqstp->rq_pages[0]);
 	arg->head[0].iov_len = PAGE_SIZE;
-	rqstp->rq_argused = 1;
-	arg->pages = rqstp->rq_argpages + 1;
+	arg->pages = rqstp->rq_pages + 1;
 	arg->page_base = 0;
 	/* save at least one page for response */
 	arg->page_len = (pages-2)*PAGE_SIZE;
@@ -1172,32 +1259,15 @@
 	if (signalled())
 		return -EINTR;
 
-	spin_lock_bh(&serv->sv_lock);
-	if (!list_empty(&serv->sv_tempsocks)) {
-		svsk = list_entry(serv->sv_tempsocks.next,
-				  struct svc_sock, sk_list);
-		/* apparently the "standard" is that clients close
-		 * idle connections after 5 minutes, servers after
-		 * 6 minutes
-		 *   http://www.connectathon.org/talks96/nfstcp.pdf 
-		 */
-		if (get_seconds() - svsk->sk_lastrecv < 6*60
-		    || test_bit(SK_BUSY, &svsk->sk_flags))
-			svsk = NULL;
-	}
-	if (svsk) {
-		set_bit(SK_BUSY, &svsk->sk_flags);
-		set_bit(SK_CLOSE, &svsk->sk_flags);
+	spin_lock_bh(&pool->sp_lock);
+	if ((svsk = svc_sock_dequeue(pool)) != NULL) {
 		rqstp->rq_sock = svsk;
-		svsk->sk_inuse++;
-	} else if ((svsk = svc_sock_dequeue(serv)) != NULL) {
-		rqstp->rq_sock = svsk;
-		svsk->sk_inuse++;
+		atomic_inc(&svsk->sk_inuse);
 		rqstp->rq_reserved = serv->sv_bufsz;	
-		svsk->sk_reserved += rqstp->rq_reserved;
+		atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
 	} else {
 		/* No data pending. Go to sleep */
-		svc_serv_enqueue(serv, rqstp);
+		svc_thread_enqueue(pool, rqstp);
 
 		/*
 		 * We have to be able to interrupt this wait
@@ -1205,26 +1275,26 @@
 		 */
 		set_current_state(TASK_INTERRUPTIBLE);
 		add_wait_queue(&rqstp->rq_wait, &wait);
-		spin_unlock_bh(&serv->sv_lock);
+		spin_unlock_bh(&pool->sp_lock);
 
 		schedule_timeout(timeout);
 
 		try_to_freeze();
 
-		spin_lock_bh(&serv->sv_lock);
+		spin_lock_bh(&pool->sp_lock);
 		remove_wait_queue(&rqstp->rq_wait, &wait);
 
 		if (!(svsk = rqstp->rq_sock)) {
-			svc_serv_dequeue(serv, rqstp);
-			spin_unlock_bh(&serv->sv_lock);
+			svc_thread_dequeue(pool, rqstp);
+			spin_unlock_bh(&pool->sp_lock);
 			dprintk("svc: server %p, no data yet\n", rqstp);
 			return signalled()? -EINTR : -EAGAIN;
 		}
 	}
-	spin_unlock_bh(&serv->sv_lock);
+	spin_unlock_bh(&pool->sp_lock);
 
-	dprintk("svc: server %p, socket %p, inuse=%d\n",
-		 rqstp, svsk, svsk->sk_inuse);
+	dprintk("svc: server %p, pool %u, socket %p, inuse=%d\n",
+		 rqstp, pool->sp_id, svsk, atomic_read(&svsk->sk_inuse));
 	len = svsk->sk_recvfrom(rqstp);
 	dprintk("svc: got len=%d\n", len);
 
@@ -1235,13 +1305,7 @@
 		return -EAGAIN;
 	}
 	svsk->sk_lastrecv = get_seconds();
-	if (test_bit(SK_TEMP, &svsk->sk_flags)) {
-		/* push active sockets to end of list */
-		spin_lock_bh(&serv->sv_lock);
-		if (!list_empty(&svsk->sk_list))
-			list_move_tail(&svsk->sk_list, &serv->sv_tempsocks);
-		spin_unlock_bh(&serv->sv_lock);
-	}
+	clear_bit(SK_OLD, &svsk->sk_flags);
 
 	rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
 	rqstp->rq_chandle.defer = svc_defer;
@@ -1301,6 +1365,58 @@
 }
 
 /*
+ * Timer function to close old temporary sockets, using
+ * a mark-and-sweep algorithm.
+ */
+static void
+svc_age_temp_sockets(unsigned long closure)
+{
+	struct svc_serv *serv = (struct svc_serv *)closure;
+	struct svc_sock *svsk;
+	struct list_head *le, *next;
+	LIST_HEAD(to_be_aged);
+
+	dprintk("svc_age_temp_sockets\n");
+
+	if (!spin_trylock_bh(&serv->sv_lock)) {
+		/* busy, try again 1 sec later */
+		dprintk("svc_age_temp_sockets: busy\n");
+		mod_timer(&serv->sv_temptimer, jiffies + HZ);
+		return;
+	}
+
+	list_for_each_safe(le, next, &serv->sv_tempsocks) {
+		svsk = list_entry(le, struct svc_sock, sk_list);
+
+		if (!test_and_set_bit(SK_OLD, &svsk->sk_flags))
+			continue;
+		if (atomic_read(&svsk->sk_inuse) || test_bit(SK_BUSY, &svsk->sk_flags))
+			continue;
+		atomic_inc(&svsk->sk_inuse);
+		list_move(le, &to_be_aged);
+		set_bit(SK_CLOSE, &svsk->sk_flags);
+		set_bit(SK_DETACHED, &svsk->sk_flags);
+	}
+	spin_unlock_bh(&serv->sv_lock);
+
+	while (!list_empty(&to_be_aged)) {
+		le = to_be_aged.next;
+		/* fiddling the sk_list node is safe 'cos we're SK_DETACHED */
+		list_del_init(le);
+		svsk = list_entry(le, struct svc_sock, sk_list);
+
+		dprintk("queuing svsk %p for closing, %lu seconds old\n",
+			svsk, get_seconds() - svsk->sk_lastrecv);
+
+		/* a thread will dequeue and close it soon */
+		svc_sock_enqueue(svsk);
+		svc_sock_put(svsk);
+	}
+
+	mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
+}
+
+/*
  * Initialize socket for RPC use and create svc_sock struct
  * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF.
  */
@@ -1337,7 +1453,9 @@
 	svsk->sk_odata = inet->sk_data_ready;
 	svsk->sk_owspace = inet->sk_write_space;
 	svsk->sk_server = serv;
+	atomic_set(&svsk->sk_inuse, 0);
 	svsk->sk_lastrecv = get_seconds();
+	spin_lock_init(&svsk->sk_defer_lock);
 	INIT_LIST_HEAD(&svsk->sk_deferred);
 	INIT_LIST_HEAD(&svsk->sk_ready);
 	mutex_init(&svsk->sk_mutex);
@@ -1353,6 +1471,13 @@
 		set_bit(SK_TEMP, &svsk->sk_flags);
 		list_add(&svsk->sk_list, &serv->sv_tempsocks);
 		serv->sv_tmpcnt++;
+		if (serv->sv_temptimer.function == NULL) {
+			/* setup timer to age temp sockets */
+			setup_timer(&serv->sv_temptimer, svc_age_temp_sockets,
+					(unsigned long)serv);
+			mod_timer(&serv->sv_temptimer,
+					jiffies + svc_conn_age_period * HZ);
+		}
 	} else {
 		clear_bit(SK_TEMP, &svsk->sk_flags);
 		list_add(&svsk->sk_list, &serv->sv_permsocks);
@@ -1367,6 +1492,38 @@
 	return svsk;
 }
 
+int svc_addsock(struct svc_serv *serv,
+		int fd,
+		char *name_return,
+		int *proto)
+{
+	int err = 0;
+	struct socket *so = sockfd_lookup(fd, &err);
+	struct svc_sock *svsk = NULL;
+
+	if (!so)
+		return err;
+	if (so->sk->sk_family != AF_INET)
+		err =  -EAFNOSUPPORT;
+	else if (so->sk->sk_protocol != IPPROTO_TCP &&
+	    so->sk->sk_protocol != IPPROTO_UDP)
+		err =  -EPROTONOSUPPORT;
+	else if (so->state > SS_UNCONNECTED)
+		err = -EISCONN;
+	else {
+		svsk = svc_setup_socket(serv, so, &err, 1);
+		if (svsk)
+			err = 0;
+	}
+	if (err) {
+		sockfd_put(so);
+		return err;
+	}
+	if (proto) *proto = so->sk->sk_protocol;
+	return one_sock_name(name_return, svsk);
+}
+EXPORT_SYMBOL_GPL(svc_addsock);
+
 /*
  * Create socket for RPC service.
  */
@@ -1434,15 +1591,27 @@
 
 	spin_lock_bh(&serv->sv_lock);
 
-	list_del_init(&svsk->sk_list);
-	list_del_init(&svsk->sk_ready);
+	if (!test_and_set_bit(SK_DETACHED, &svsk->sk_flags))
+		list_del_init(&svsk->sk_list);
+    	/*
+	 * We used to delete the svc_sock from whichever list
+	 * it's sk_ready node was on, but we don't actually
+	 * need to.  This is because the only time we're called
+	 * while still attached to a queue, the queue itself
+	 * is about to be destroyed (in svc_destroy).
+	 */
 	if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags))
 		if (test_bit(SK_TEMP, &svsk->sk_flags))
 			serv->sv_tmpcnt--;
 
-	if (!svsk->sk_inuse) {
+	if (!atomic_read(&svsk->sk_inuse)) {
 		spin_unlock_bh(&serv->sv_lock);
-		sock_release(svsk->sk_sock);
+		if (svsk->sk_sock->file)
+			sockfd_put(svsk->sk_sock);
+		else
+			sock_release(svsk->sk_sock);
+		if (svsk->sk_info_authunix != NULL)
+			svcauth_unix_info_release(svsk->sk_info_authunix);
 		kfree(svsk);
 	} else {
 		spin_unlock_bh(&serv->sv_lock);
@@ -1473,7 +1642,6 @@
 static void svc_revisit(struct cache_deferred_req *dreq, int too_many)
 {
 	struct svc_deferred_req *dr = container_of(dreq, struct svc_deferred_req, handle);
-	struct svc_serv *serv = dreq->owner;
 	struct svc_sock *svsk;
 
 	if (too_many) {
@@ -1484,9 +1652,9 @@
 	dprintk("revisit queued\n");
 	svsk = dr->svsk;
 	dr->svsk = NULL;
-	spin_lock_bh(&serv->sv_lock);
+	spin_lock_bh(&svsk->sk_defer_lock);
 	list_add(&dr->handle.recent, &svsk->sk_deferred);
-	spin_unlock_bh(&serv->sv_lock);
+	spin_unlock_bh(&svsk->sk_defer_lock);
 	set_bit(SK_DEFERRED, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
 	svc_sock_put(svsk);
@@ -1518,10 +1686,8 @@
 		dr->argslen = rqstp->rq_arg.len >> 2;
 		memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2);
 	}
-	spin_lock_bh(&rqstp->rq_server->sv_lock);
-	rqstp->rq_sock->sk_inuse++;
+	atomic_inc(&rqstp->rq_sock->sk_inuse);
 	dr->svsk = rqstp->rq_sock;
-	spin_unlock_bh(&rqstp->rq_server->sv_lock);
 
 	dr->handle.revisit = svc_revisit;
 	return &dr->handle;
@@ -1541,6 +1707,7 @@
 	rqstp->rq_prot        = dr->prot;
 	rqstp->rq_addr        = dr->addr;
 	rqstp->rq_daddr       = dr->daddr;
+	rqstp->rq_respages    = rqstp->rq_pages;
 	return dr->argslen<<2;
 }
 
@@ -1548,11 +1715,10 @@
 static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk)
 {
 	struct svc_deferred_req *dr = NULL;
-	struct svc_serv	*serv = svsk->sk_server;
 	
 	if (!test_bit(SK_DEFERRED, &svsk->sk_flags))
 		return NULL;
-	spin_lock_bh(&serv->sv_lock);
+	spin_lock_bh(&svsk->sk_defer_lock);
 	clear_bit(SK_DEFERRED, &svsk->sk_flags);
 	if (!list_empty(&svsk->sk_deferred)) {
 		dr = list_entry(svsk->sk_deferred.next,
@@ -1561,6 +1727,6 @@
 		list_del_init(&dr->handle.recent);
 		set_bit(SK_DEFERRED, &svsk->sk_flags);
 	}
-	spin_unlock_bh(&serv->sv_lock);
+	spin_unlock_bh(&svsk->sk_defer_lock);
 	return dr;
 }
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 693f02e..53bc8cb 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1666,8 +1666,9 @@
 		char addr_string[16];
 
 		tipc_printf(TIPC_OUTPUT, "Msg seq number: %u,  ", msg_seqno(msg));
-		tipc_printf(TIPC_OUTPUT, "Outstanding acks: %u\n", (u32)TIPC_SKB_CB(buf)->handle);
-		
+		tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n",
+				     (unsigned long) TIPC_SKB_CB(buf)->handle);
+
 		n_ptr = l_ptr->owner->next;
 		tipc_node_lock(n_ptr);
 
diff --git a/net/xfrm/xfrm_hash.h b/net/xfrm/xfrm_hash.h
index 6ac4e4f..d401dc8 100644
--- a/net/xfrm/xfrm_hash.h
+++ b/net/xfrm/xfrm_hash.h
@@ -41,17 +41,18 @@
 	return (h ^ (h >> 16)) & hmask;
 }
 
-static inline unsigned __xfrm_src_hash(xfrm_address_t *saddr,
+static inline unsigned __xfrm_src_hash(xfrm_address_t *daddr,
+				       xfrm_address_t *saddr,
 				       unsigned short family,
 				       unsigned int hmask)
 {
 	unsigned int h = family;
 	switch (family) {
 	case AF_INET:
-		h ^= __xfrm4_addr_hash(saddr);
+		h ^= __xfrm4_daddr_saddr_hash(daddr, saddr);
 		break;
 	case AF_INET6:
-		h ^= __xfrm6_addr_hash(saddr);
+		h ^= __xfrm6_daddr_saddr_hash(daddr, saddr);
 		break;
 	};
 	return (h ^ (h >> 16)) & hmask;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b6e2e79..2a78616 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -778,8 +778,9 @@
 	for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
 		struct xfrm_policy *pol;
 		struct hlist_node *entry;
-		int i;
+		int i, killed;
 
+		killed = 0;
 	again1:
 		hlist_for_each_entry(pol, entry,
 				     &xfrm_policy_inexact[dir], bydst) {
@@ -790,6 +791,7 @@
 			write_unlock_bh(&xfrm_policy_lock);
 
 			xfrm_policy_kill(pol);
+			killed++;
 
 			write_lock_bh(&xfrm_policy_lock);
 			goto again1;
@@ -807,13 +809,14 @@
 				write_unlock_bh(&xfrm_policy_lock);
 
 				xfrm_policy_kill(pol);
+				killed++;
 
 				write_lock_bh(&xfrm_policy_lock);
 				goto again2;
 			}
 		}
 
-		xfrm_policy_count[dir] = 0;
+		xfrm_policy_count[dir] -= killed;
 	}
 	atomic_inc(&flow_cache_genid);
 	write_unlock_bh(&xfrm_policy_lock);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f927b73..39b8bf3 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -63,10 +63,11 @@
 	return __xfrm_dst_hash(daddr, saddr, reqid, family, xfrm_state_hmask);
 }
 
-static inline unsigned int xfrm_src_hash(xfrm_address_t *addr,
+static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr,
+					 xfrm_address_t *saddr,
 					 unsigned short family)
 {
-	return __xfrm_src_hash(addr, family, xfrm_state_hmask);
+	return __xfrm_src_hash(daddr, saddr, family, xfrm_state_hmask);
 }
 
 static inline unsigned int
@@ -92,7 +93,8 @@
 				    nhashmask);
 		hlist_add_head(&x->bydst, ndsttable+h);
 
-		h = __xfrm_src_hash(&x->props.saddr, x->props.family,
+		h = __xfrm_src_hash(&x->id.daddr, &x->props.saddr,
+				    x->props.family,
 				    nhashmask);
 		hlist_add_head(&x->bysrc, nsrctable+h);
 
@@ -458,7 +460,7 @@
 
 static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
 {
-	unsigned int h = xfrm_src_hash(saddr, family);
+	unsigned int h = xfrm_src_hash(daddr, saddr, family);
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 
@@ -587,7 +589,7 @@
 		if (km_query(x, tmpl, pol) == 0) {
 			x->km.state = XFRM_STATE_ACQ;
 			hlist_add_head(&x->bydst, xfrm_state_bydst+h);
-			h = xfrm_src_hash(saddr, family);
+			h = xfrm_src_hash(daddr, saddr, family);
 			hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 			if (x->id.spi) {
 				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
@@ -622,7 +624,7 @@
 			  x->props.reqid, x->props.family);
 	hlist_add_head(&x->bydst, xfrm_state_bydst+h);
 
-	h = xfrm_src_hash(&x->props.saddr, x->props.family);
+	h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family);
 	hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 
 	if (x->id.spi) {
@@ -748,7 +750,7 @@
 		x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
 		add_timer(&x->timer);
 		hlist_add_head(&x->bydst, xfrm_state_bydst+h);
-		h = xfrm_src_hash(saddr, family);
+		h = xfrm_src_hash(daddr, saddr, family);
 		hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 		wake_up(&km_waitq);
 	}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c59a78d..d54b3a7 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -211,6 +211,7 @@
 	case XFRM_MODE_TRANSPORT:
 	case XFRM_MODE_TUNNEL:
 	case XFRM_MODE_ROUTEOPTIMIZATION:
+	case XFRM_MODE_BEET:
 		break;
 
 	default:
diff --git a/scripts/.gitignore b/scripts/.gitignore
index a234e52..a1f52cb 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -5,3 +5,4 @@
 kallsyms
 pnmtologo
 bin2c
+unifdef
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index cac8f21..6a026f6 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -97,7 +97,7 @@
 				   | $(HDRSED) > $@ || :
 
 quiet_cmd_check		  = CHECK   $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/.check.%,$(_dst)/%,$@)
-      cmd_check		  = $(srctree)/scripts/hdrcheck.sh		\
+      cmd_check		  = $(CONFIG_SHELL) $(srctree)/scripts/hdrcheck.sh \
                               $(INSTALL_HDR_PATH)/include $(subst /.check.,/,$@) $@
 
 quiet_cmd_remove	  = REMOVE  $(_dst)/$@
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 4b2721c..6c5469b 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -32,6 +32,10 @@
 # Step 4 is solely used to allow module versioning in external modules,
 # where the CRC of each module is retrieved from the Module.symers file.
 
+# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
+# symbols in the final module linking stage
+# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
+# This is solely usefull to speed up test compiles
 PHONY := _modpost
 _modpost: __modpost
 
@@ -46,7 +50,8 @@
 __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
 modules   := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
 
-_modpost: $(modules)
+# Stop after building .o files if NOFINAL is set. Makes compile tests quicker
+_modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))
 
 
 # Step 2), invoke modpost
@@ -58,7 +63,7 @@
 	$(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
 	$(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
 	$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
-	$(if $(KBUILD_EXTMOD),-w) \
+	$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
 	$(wildcard vmlinux) $(filter-out FORCE,$^)
 
 PHONY += __modpost
@@ -92,7 +97,7 @@
 
 # Step 6), final link of the modules
 quiet_cmd_ld_ko_o = LD [M]  $@
-      cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ 		\
+      cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@		\
 			  $(filter-out FORCE,$^)
 
 $(modules): %.ko :%.o %.mod.o FORCE
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index a90d3cc..7e7e147 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -11,7 +11,6 @@
 	$< arch/$(ARCH)/Kconfig
 
 menuconfig: $(obj)/mconf
-	$(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
 	$< arch/$(ARCH)/Kconfig
 
 config: $(obj)/conf
@@ -81,6 +80,23 @@
 	@echo  '  allyesconfig	  - New config where all options are accepted with yes'
 	@echo  '  allnoconfig	  - New config where all options are answered with no'
 
+# lxdialog stuff
+check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
+
+# Use reursively expanded variables so we do not call gcc unless
+# we really need to do so. (Do not call gcc as part of make mrproper)
+HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
+HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+
+HOST_EXTRACFLAGS += -DLOCALE
+
+PHONY += $(obj)/dochecklxdialog
+$(obj)/dochecklxdialog:
+	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
+
+always := dochecklxdialog
+
+
 # ===========================================================================
 # Shared Makefile for the various kconfig executables:
 # conf:	  Used for defconfig, oldconfig and related targets
@@ -92,11 +108,19 @@
 #         Based on GTK which needs to be installed to compile it
 # object files used by all kconfig flavours
 
-hostprogs-y	:= conf mconf qconf gconf kxgettext
+lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
+lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
+
 conf-objs	:= conf.o  zconf.tab.o
-mconf-objs	:= mconf.o zconf.tab.o
+mconf-objs	:= mconf.o zconf.tab.o $(lxdialog)
 kxgettext-objs	:= kxgettext.o zconf.tab.o
 
+hostprogs-y := conf qconf gconf kxgettext
+
+ifeq ($(MAKECMDGOALS),menuconfig)
+	hostprogs-y += mconf
+endif
+
 ifeq ($(MAKECMDGOALS),xconfig)
 	qconf-target := 1
 endif
@@ -116,7 +140,6 @@
 
 clean-files	:= lkc_defs.h qconf.moc .tmp_qtcheck \
 		   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
-subdir- += lxdialog
 
 # Needed for systems without gettext
 KBUILD_HAVE_NLS := $(shell \
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 69f96b3..66b15ef 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -517,7 +517,7 @@
 	fclose(out);
 
 	if (*tmpname) {
-		strcat(dirname, name ? name : conf_get_configname());
+		strcat(dirname, basename);
 		strcat(dirname, ".old");
 		rename(newname, dirname);
 		if (rename(tmpname, newname))
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
deleted file mode 100644
index a8b0263..0000000
--- a/scripts/kconfig/lxdialog/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Makefile to build lxdialog package
-#
-
-check-lxdialog  := $(srctree)/$(src)/check-lxdialog.sh
-
-# Use reursively expanded variables so we do not call gcc unless
-# we really need to do so. (Do not call gcc as part of make mrproper)
-HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
-HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
-
-HOST_EXTRACFLAGS += -DLOCALE
-
-PHONY += dochecklxdialog
-$(obj)/dochecklxdialog:
-	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
-
-hostprogs-y	:= lxdialog
-always		:= $(hostprogs-y) dochecklxdialog
-
-lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
-		 util.o lxdialog.o msgbox.o
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index 7988641..cf69708 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -28,25 +28,25 @@
 /*
  * Print list item
  */
-static void print_item(WINDOW * win, const char *item, int status, int choice,
-		       int selected)
+static void print_item(WINDOW * win, int choice, int selected)
 {
 	int i;
 
 	/* Clear 'residue' of last item */
-	wattrset(win, menubox_attr);
+	wattrset(win, dlg.menubox.atr);
 	wmove(win, choice, 0);
 	for (i = 0; i < list_width; i++)
 		waddch(win, ' ');
 
 	wmove(win, choice, check_x);
-	wattrset(win, selected ? check_selected_attr : check_attr);
-	wprintw(win, "(%c)", status ? 'X' : ' ');
+	wattrset(win, selected ? dlg.check_selected.atr
+		 : dlg.check.atr);
+	wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
 
-	wattrset(win, selected ? tag_selected_attr : tag_attr);
-	mvwaddch(win, choice, item_x, item[0]);
-	wattrset(win, selected ? item_selected_attr : item_attr);
-	waddstr(win, (char *)item + 1);
+	wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
+	mvwaddch(win, choice, item_x, item_str()[0]);
+	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+	waddstr(win, (char *)item_str() + 1);
 	if (selected) {
 		wmove(win, choice, check_x + 1);
 		wrefresh(win);
@@ -62,11 +62,11 @@
 	wmove(win, y, x);
 
 	if (scroll > 0) {
-		wattrset(win, uarrow_attr);
+		wattrset(win, dlg.uarrow.atr);
 		waddch(win, ACS_UARROW);
 		waddstr(win, "(-)");
 	} else {
-		wattrset(win, menubox_attr);
+		wattrset(win, dlg.menubox.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -77,11 +77,11 @@
 	wmove(win, y, x);
 
 	if ((height < item_no) && (scroll + choice < item_no - 1)) {
-		wattrset(win, darrow_attr);
+		wattrset(win, dlg.darrow.atr);
 		waddch(win, ACS_DARROW);
 		waddstr(win, "(+)");
 	} else {
-		wattrset(win, menubox_border_attr);
+		wattrset(win, dlg.menubox_border.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -109,32 +109,29 @@
  * in the style of radiolist (only one option turned on at a time).
  */
 int dialog_checklist(const char *title, const char *prompt, int height,
-		     int width, int list_height, int item_no,
-		     const char *const *items)
+		     int width, int list_height)
 {
 	int i, x, y, box_x, box_y;
-	int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+	int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
 	WINDOW *dialog, *list;
 
-	/* Allocate space for storing item on/off status */
-	if ((status = malloc(sizeof(int) * item_no)) == NULL) {
-		endwin();
-		fprintf(stderr,
-			"\nCan't allocate memory in dialog_checklist().\n");
-		exit(-1);
+	/* which item to highlight */
+	item_foreach() {
+		if (item_is_tag('X'))
+			choice = item_n();
+		if (item_is_selected()) {
+			choice = item_n();
+			break;
+		}
 	}
 
-	/* Initializes status */
-	for (i = 0; i < item_no; i++) {
-		status[i] = !strcasecmp(items[i * 3 + 2], "on");
-		if ((!choice && status[i])
-		    || !strcasecmp(items[i * 3 + 2], "selected"))
-			choice = i + 1;
-	}
-	if (choice)
-		choice--;
+do_resize:
+	if (getmaxy(stdscr) < (height + 6))
+		return -ERRDISPLAYTOOSMALL;
+	if (getmaxx(stdscr) < (width + 6))
+		return -ERRDISPLAYTOOSMALL;
 
-	max_choice = MIN(list_height, item_no);
+	max_choice = MIN(list_height, item_count());
 
 	/* center dialog box on screen */
 	x = (COLS - width) / 2;
@@ -145,17 +142,18 @@
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-	wattrset(dialog, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
 
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	print_autowrap(dialog, prompt, width - 2, 1, 3);
 
 	list_width = width - 6;
@@ -170,12 +168,12 @@
 
 	/* draw a box around the list items */
 	draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
-	         menubox_border_attr, menubox_attr);
+	         dlg.menubox_border.atr, dlg.menubox.atr);
 
 	/* Find length of longest item in order to center checklist */
 	check_x = 0;
-	for (i = 0; i < item_no; i++)
-		check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
+	item_foreach()
+		check_x = MAX(check_x, strlen(item_str()) + 4);
 
 	check_x = (list_width - check_x) / 2;
 	item_x = check_x + 4;
@@ -187,14 +185,11 @@
 
 	/* Print the list */
 	for (i = 0; i < max_choice; i++) {
-		if (i != choice)
-			print_item(list, items[(scroll + i) * 3 + 1],
-				   status[i + scroll], i, 0);
+		item_set(scroll + i);
+		print_item(list, i, i == choice);
 	}
-	print_item(list, items[(scroll + choice) * 3 + 1],
-		   status[choice + scroll], choice, 1);
 
-	print_arrows(dialog, choice, item_no, scroll,
+	print_arrows(dialog, choice, item_count(), scroll,
 		     box_y, box_x + check_x + 5, list_height);
 
 	print_buttons(dialog, height, width, 0);
@@ -203,13 +198,14 @@
 	wnoutrefresh(list);
 	doupdate();
 
-	while (key != ESC) {
+	while (key != KEY_ESC) {
 		key = wgetch(dialog);
 
-		for (i = 0; i < max_choice; i++)
-			if (toupper(key) ==
-			    toupper(items[(scroll + i) * 3 + 1][0]))
+		for (i = 0; i < max_choice; i++) {
+			item_set(i + scroll);
+			if (toupper(key) == toupper(item_str()[0]))
 				break;
+		}
 
 		if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
 		    key == '+' || key == '-') {
@@ -220,15 +216,16 @@
 					/* Scroll list down */
 					if (list_height > 1) {
 						/* De-highlight current first item */
-						print_item(list, items[scroll * 3 + 1],
-							   status[scroll], 0, FALSE);
+						item_set(scroll);
+						print_item(list, 0, FALSE);
 						scrollok(list, TRUE);
 						wscrl(list, -1);
 						scrollok(list, FALSE);
 					}
 					scroll--;
-					print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
-					print_arrows(dialog, choice, item_no,
+					item_set(scroll);
+					print_item(list, 0, TRUE);
+					print_arrows(dialog, choice, item_count(),
 						     scroll, box_y, box_x + check_x + 5, list_height);
 
 					wnoutrefresh(dialog);
@@ -239,23 +236,24 @@
 					i = choice - 1;
 			} else if (key == KEY_DOWN || key == '+') {
 				if (choice == max_choice - 1) {
-					if (scroll + choice >= item_no - 1)
+					if (scroll + choice >= item_count() - 1)
 						continue;
 					/* Scroll list up */
 					if (list_height > 1) {
 						/* De-highlight current last item before scrolling up */
-						print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
-							   status[scroll + max_choice - 1],
-							   max_choice - 1, FALSE);
+						item_set(scroll + max_choice - 1);
+						print_item(list,
+							    max_choice - 1,
+							    FALSE);
 						scrollok(list, TRUE);
 						wscrl(list, 1);
 						scrollok(list, FALSE);
 					}
 					scroll++;
-					print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
-						   status[scroll + max_choice - 1], max_choice - 1, TRUE);
+					item_set(scroll + max_choice - 1);
+					print_item(list, max_choice - 1, TRUE);
 
-					print_arrows(dialog, choice, item_no,
+					print_arrows(dialog, choice, item_count(),
 						     scroll, box_y, box_x + check_x + 5, list_height);
 
 					wnoutrefresh(dialog);
@@ -267,12 +265,12 @@
 			}
 			if (i != choice) {
 				/* De-highlight current item */
-				print_item(list, items[(scroll + choice) * 3 + 1],
-					   status[scroll + choice], choice, FALSE);
+				item_set(scroll + choice);
+				print_item(list, choice, FALSE);
 				/* Highlight new item */
 				choice = i;
-				print_item(list, items[(scroll + choice) * 3 + 1],
-					   status[scroll + choice], choice, TRUE);
+				item_set(scroll + choice);
+				print_item(list, choice, TRUE);
 				wnoutrefresh(dialog);
 				wrefresh(list);
 			}
@@ -282,10 +280,19 @@
 		case 'H':
 		case 'h':
 		case '?':
-			fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+			button = 1;
+			/* fall-through */
+		case 'S':
+		case 's':
+		case ' ':
+		case '\n':
+			item_foreach()
+				item_set_selected(0);
+			item_set(scroll + choice);
+			item_set_selected(1);
+			delwin(list);
 			delwin(dialog);
-			free(status);
-			return 1;
+			return button;
 		case TAB:
 		case KEY_LEFT:
 		case KEY_RIGHT:
@@ -295,42 +302,24 @@
 			print_buttons(dialog, height, width, button);
 			wrefresh(dialog);
 			break;
-		case 'S':
-		case 's':
-		case ' ':
-		case '\n':
-			if (!button) {
-				if (!status[scroll + choice]) {
-					for (i = 0; i < item_no; i++)
-						status[i] = 0;
-					status[scroll + choice] = 1;
-					for (i = 0; i < max_choice; i++)
-						print_item(list, items[(scroll + i) * 3 + 1],
-							   status[scroll + i], i, i == choice);
-				}
-				wnoutrefresh(dialog);
-				wrefresh(list);
-
-				for (i = 0; i < item_no; i++)
-					if (status[i])
-						fprintf(stderr, "%s", items[i * 3]);
-			} else
-				fprintf(stderr, "%s", items[(scroll + choice) * 3]);
-			delwin(dialog);
-			free(status);
-			return button;
 		case 'X':
 		case 'x':
-			key = ESC;
-		case ESC:
+			key = KEY_ESC;
 			break;
+		case KEY_ESC:
+			key = on_key_esc(dialog);
+			break;
+		case KEY_RESIZE:
+			delwin(list);
+			delwin(dialog);
+			on_key_resize();
+			goto do_resize;
 		}
 
 		/* Now, update everything... */
 		doupdate();
 	}
-
+	delwin(list);
 	delwin(dialog);
-	free(status);
-	return -1;		/* ESC pressed */
+	return key;		/* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h
deleted file mode 100644
index db071df1..0000000
--- a/scripts/kconfig/lxdialog/colors.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  colors.h -- color attribute definitions
- *
- *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *   Default color definitions
- *
- *   *_FG = foreground
- *   *_BG = background
- *   *_HL = highlight?
- */
-#define SCREEN_FG                    COLOR_CYAN
-#define SCREEN_BG                    COLOR_BLUE
-#define SCREEN_HL                    TRUE
-
-#define SHADOW_FG                    COLOR_BLACK
-#define SHADOW_BG                    COLOR_BLACK
-#define SHADOW_HL                    TRUE
-
-#define DIALOG_FG                    COLOR_BLACK
-#define DIALOG_BG                    COLOR_WHITE
-#define DIALOG_HL                    FALSE
-
-#define TITLE_FG                     COLOR_YELLOW
-#define TITLE_BG                     COLOR_WHITE
-#define TITLE_HL                     TRUE
-
-#define BORDER_FG                    COLOR_WHITE
-#define BORDER_BG                    COLOR_WHITE
-#define BORDER_HL                    TRUE
-
-#define BUTTON_ACTIVE_FG             COLOR_WHITE
-#define BUTTON_ACTIVE_BG             COLOR_BLUE
-#define BUTTON_ACTIVE_HL             TRUE
-
-#define BUTTON_INACTIVE_FG           COLOR_BLACK
-#define BUTTON_INACTIVE_BG           COLOR_WHITE
-#define BUTTON_INACTIVE_HL           FALSE
-
-#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
-#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
-#define BUTTON_KEY_ACTIVE_HL         TRUE
-
-#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
-#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
-#define BUTTON_KEY_INACTIVE_HL       FALSE
-
-#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
-#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
-#define BUTTON_LABEL_ACTIVE_HL       TRUE
-
-#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
-#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
-#define BUTTON_LABEL_INACTIVE_HL     TRUE
-
-#define INPUTBOX_FG                  COLOR_BLACK
-#define INPUTBOX_BG                  COLOR_WHITE
-#define INPUTBOX_HL                  FALSE
-
-#define INPUTBOX_BORDER_FG           COLOR_BLACK
-#define INPUTBOX_BORDER_BG           COLOR_WHITE
-#define INPUTBOX_BORDER_HL           FALSE
-
-#define SEARCHBOX_FG                 COLOR_BLACK
-#define SEARCHBOX_BG                 COLOR_WHITE
-#define SEARCHBOX_HL                 FALSE
-
-#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
-#define SEARCHBOX_TITLE_BG           COLOR_WHITE
-#define SEARCHBOX_TITLE_HL           TRUE
-
-#define SEARCHBOX_BORDER_FG          COLOR_WHITE
-#define SEARCHBOX_BORDER_BG          COLOR_WHITE
-#define SEARCHBOX_BORDER_HL          TRUE
-
-#define POSITION_INDICATOR_FG        COLOR_YELLOW
-#define POSITION_INDICATOR_BG        COLOR_WHITE
-#define POSITION_INDICATOR_HL        TRUE
-
-#define MENUBOX_FG                   COLOR_BLACK
-#define MENUBOX_BG                   COLOR_WHITE
-#define MENUBOX_HL                   FALSE
-
-#define MENUBOX_BORDER_FG            COLOR_WHITE
-#define MENUBOX_BORDER_BG            COLOR_WHITE
-#define MENUBOX_BORDER_HL            TRUE
-
-#define ITEM_FG                      COLOR_BLACK
-#define ITEM_BG                      COLOR_WHITE
-#define ITEM_HL                      FALSE
-
-#define ITEM_SELECTED_FG             COLOR_WHITE
-#define ITEM_SELECTED_BG             COLOR_BLUE
-#define ITEM_SELECTED_HL             TRUE
-
-#define TAG_FG                       COLOR_YELLOW
-#define TAG_BG                       COLOR_WHITE
-#define TAG_HL                       TRUE
-
-#define TAG_SELECTED_FG              COLOR_YELLOW
-#define TAG_SELECTED_BG              COLOR_BLUE
-#define TAG_SELECTED_HL              TRUE
-
-#define TAG_KEY_FG                   COLOR_YELLOW
-#define TAG_KEY_BG                   COLOR_WHITE
-#define TAG_KEY_HL                   TRUE
-
-#define TAG_KEY_SELECTED_FG          COLOR_YELLOW
-#define TAG_KEY_SELECTED_BG          COLOR_BLUE
-#define TAG_KEY_SELECTED_HL          TRUE
-
-#define CHECK_FG                     COLOR_BLACK
-#define CHECK_BG                     COLOR_WHITE
-#define CHECK_HL                     FALSE
-
-#define CHECK_SELECTED_FG            COLOR_WHITE
-#define CHECK_SELECTED_BG            COLOR_BLUE
-#define CHECK_SELECTED_HL            TRUE
-
-#define UARROW_FG                    COLOR_GREEN
-#define UARROW_BG                    COLOR_WHITE
-#define UARROW_HL                    TRUE
-
-#define DARROW_FG                    COLOR_GREEN
-#define DARROW_BG                    COLOR_WHITE
-#define DARROW_HL                    TRUE
-
-/* End of default color definitions */
-
-#define C_ATTR(x,y)                  ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
-#define COLOR_NAME_LEN               10
-#define COLOR_COUNT                  8
-
-/*
- * Global variables
- */
-
-extern int color_table[][3];
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index af3cf71..8dea47f 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -48,7 +48,7 @@
 
 #define TR(params) _tracef params
 
-#define ESC 27
+#define KEY_ESC 27
 #define TAB 9
 #define MAX_LEN 2048
 #define BUF_SIZE (10*1024)
@@ -86,63 +86,111 @@
 #define ACS_DARROW 'v'
 #endif
 
-/*
- * Attribute names
- */
-#define screen_attr                   attributes[0]
-#define shadow_attr                   attributes[1]
-#define dialog_attr                   attributes[2]
-#define title_attr                    attributes[3]
-#define border_attr                   attributes[4]
-#define button_active_attr            attributes[5]
-#define button_inactive_attr          attributes[6]
-#define button_key_active_attr        attributes[7]
-#define button_key_inactive_attr      attributes[8]
-#define button_label_active_attr      attributes[9]
-#define button_label_inactive_attr    attributes[10]
-#define inputbox_attr                 attributes[11]
-#define inputbox_border_attr          attributes[12]
-#define searchbox_attr                attributes[13]
-#define searchbox_title_attr          attributes[14]
-#define searchbox_border_attr         attributes[15]
-#define position_indicator_attr       attributes[16]
-#define menubox_attr                  attributes[17]
-#define menubox_border_attr           attributes[18]
-#define item_attr                     attributes[19]
-#define item_selected_attr            attributes[20]
-#define tag_attr                      attributes[21]
-#define tag_selected_attr             attributes[22]
-#define tag_key_attr                  attributes[23]
-#define tag_key_selected_attr         attributes[24]
-#define check_attr                    attributes[25]
-#define check_selected_attr           attributes[26]
-#define uarrow_attr                   attributes[27]
-#define darrow_attr                   attributes[28]
+/* error return codes */
+#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
 
-/* number of attributes */
-#define ATTRIBUTE_COUNT               29
+/*
+ *   Color definitions
+ */
+struct dialog_color {
+	chtype atr;	/* Color attribute */
+	int fg;		/* foreground */
+	int bg;		/* background */
+	int hl;		/* highlight this item */
+};
+
+struct dialog_info {
+	const char *backtitle;
+	struct dialog_color screen;
+	struct dialog_color shadow;
+	struct dialog_color dialog;
+	struct dialog_color title;
+	struct dialog_color border;
+	struct dialog_color button_active;
+	struct dialog_color button_inactive;
+	struct dialog_color button_key_active;
+	struct dialog_color button_key_inactive;
+	struct dialog_color button_label_active;
+	struct dialog_color button_label_inactive;
+	struct dialog_color inputbox;
+	struct dialog_color inputbox_border;
+	struct dialog_color searchbox;
+	struct dialog_color searchbox_title;
+	struct dialog_color searchbox_border;
+	struct dialog_color position_indicator;
+	struct dialog_color menubox;
+	struct dialog_color menubox_border;
+	struct dialog_color item;
+	struct dialog_color item_selected;
+	struct dialog_color tag;
+	struct dialog_color tag_selected;
+	struct dialog_color tag_key;
+	struct dialog_color tag_key_selected;
+	struct dialog_color check;
+	struct dialog_color check_selected;
+	struct dialog_color uarrow;
+	struct dialog_color darrow;
+};
 
 /*
  * Global variables
  */
-extern bool use_colors;
-extern bool use_shadow;
-
-extern chtype attributes[];
-
-extern const char *backtitle;
+extern struct dialog_info dlg;
+extern char dialog_input_result[];
 
 /*
  * Function prototypes
  */
-extern void create_rc(const char *filename);
-extern int parse_rc(void);
 
-void init_dialog(void);
+/* item list as used by checklist and menubox */
+void item_reset(void);
+void item_make(const char *fmt, ...);
+void item_add_str(const char *fmt, ...);
+void item_set_tag(char tag);
+void item_set_data(void *p);
+void item_set_selected(int val);
+int item_activate_selected(void);
+void *item_data(void);
+char item_tag(void);
+
+/* item list manipulation for lxdialog use */
+#define MAXITEMSTR 200
+struct dialog_item {
+	char str[MAXITEMSTR];	/* promtp displayed */
+	char tag;
+	void *data;	/* pointer to menu item - used by menubox+checklist */
+	int selected;	/* Set to 1 by dialog_*() function if selected. */
+};
+
+/* list of lialog_items */
+struct dialog_list {
+	struct dialog_item node;
+	struct dialog_list *next;
+};
+
+extern struct dialog_list *item_cur;
+extern struct dialog_list item_nil;
+extern struct dialog_list *item_head;
+
+int item_count(void);
+void item_set(int n);
+int item_n(void);
+const char *item_str(void);
+int item_is_selected(void);
+int item_is_tag(char tag);
+#define item_foreach() \
+	for (item_cur = item_head ? item_head: item_cur; \
+	     item_cur && (item_cur != &item_nil); item_cur = item_cur->next)
+
+/* generic key handlers */
+int on_key_esc(WINDOW *win);
+int on_key_resize(void);
+
+void init_dialog(const char *backtitle);
+void reset_dialog(void);
 void end_dialog(void);
 void attr_clear(WINDOW * win, int height, int width, chtype attr);
 void dialog_clear(void);
-void color_setup(void);
 void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
 void print_button(WINDOW * win, const char *label, int y, int x, int selected);
 void print_title(WINDOW *dialog, const char *title, int width);
@@ -155,12 +203,10 @@
 int dialog_msgbox(const char *title, const char *prompt, int height,
 		  int width, int pause);
 int dialog_textbox(const char *title, const char *file, int height, int width);
-int dialog_menu(const char *title, const char *prompt, int height, int width,
-		int menu_height, const char *choice, int item_no,
-		const char *const *items);
+int dialog_menu(const char *title, const char *prompt,
+		const void *selected, int *s_scroll);
 int dialog_checklist(const char *title, const char *prompt, int height,
-		     int width, int list_height, int item_no,
-		     const char *const *items);
+		     int width, int list_height);
 extern char dialog_input_result[];
 int dialog_inputbox(const char *title, const char *prompt, int height,
 		    int width, const char *init);
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 7795037..05e7206 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -49,6 +49,17 @@
 	char *instr = dialog_input_result;
 	WINDOW *dialog;
 
+	if (!init)
+		instr[0] = '\0';
+	else
+		strcpy(instr, init);
+
+do_resize:
+	if (getmaxy(stdscr) <= (height - 2))
+		return -ERRDISPLAYTOOSMALL;
+	if (getmaxx(stdscr) <= (width - 2))
+		return -ERRDISPLAYTOOSMALL;
+
 	/* center dialog box on screen */
 	x = (COLS - width) / 2;
 	y = (LINES - height) / 2;
@@ -58,17 +69,18 @@
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-	wattrset(dialog, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
 
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	print_autowrap(dialog, prompt, width - 2, 1, 3);
 
 	/* Draw the input field box */
@@ -76,18 +88,14 @@
 	getyx(dialog, y, x);
 	box_y = y + 2;
 	box_x = (width - box_width) / 2;
-	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
+	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
+		 dlg.border.atr, dlg.dialog.atr);
 
 	print_buttons(dialog, height, width, 0);
 
 	/* Set up the initial value */
 	wmove(dialog, box_y, box_x);
-	wattrset(dialog, inputbox_attr);
-
-	if (!init)
-		instr[0] = '\0';
-	else
-		strcpy(instr, init);
+	wattrset(dialog, dlg.inputbox.atr);
 
 	input_x = strlen(instr);
 
@@ -104,7 +112,7 @@
 
 	wrefresh(dialog);
 
-	while (key != ESC) {
+	while (key != KEY_ESC) {
 		key = wgetch(dialog);
 
 		if (button == -1) {	/* Input box selected */
@@ -120,7 +128,7 @@
 			case KEY_BACKSPACE:
 			case 127:
 				if (input_x || scroll) {
-					wattrset(dialog, inputbox_attr);
+					wattrset(dialog, dlg.inputbox.atr);
 					if (!input_x) {
 						scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
 						wmove(dialog, box_y, box_x);
@@ -140,7 +148,7 @@
 			default:
 				if (key < 0x100 && isprint(key)) {
 					if (scroll + input_x < MAX_LEN) {
-						wattrset(dialog, inputbox_attr);
+						wattrset(dialog, dlg.inputbox.atr);
 						instr[scroll + input_x] = key;
 						instr[scroll + input_x + 1] = '\0';
 						if (input_x == box_width - 1) {
@@ -213,12 +221,18 @@
 			return (button == -1 ? 0 : button);
 		case 'X':
 		case 'x':
-			key = ESC;
-		case ESC:
+			key = KEY_ESC;
 			break;
+		case KEY_ESC:
+			key = on_key_esc(dialog);
+			break;
+		case KEY_RESIZE:
+			delwin(dialog);
+			on_key_resize();
+			goto do_resize;
 		}
 	}
 
 	delwin(dialog);
-	return -1;		/* ESC pressed */
+	return KEY_ESC;		/* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c
deleted file mode 100644
index 79f6c5f..0000000
--- a/scripts/kconfig/lxdialog/lxdialog.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  dialog - Display simple dialog boxes from shell scripts
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void Usage(const char *name);
-
-typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
-
-struct Mode {
-	char *name;
-	int argmin, argmax, argmod;
-	jumperFn *jumper;
-};
-
-jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox;
-jumperFn j_msgbox, j_infobox;
-
-static struct Mode modes[] = {
-	{"--menu", 9, 0, 3, j_menu},
-	{"--radiolist", 9, 0, 3, j_radiolist},
-	{"--yesno", 5, 5, 1, j_yesno},
-	{"--textbox", 5, 5, 1, j_textbox},
-	{"--inputbox", 5, 6, 1, j_inputbox},
-	{"--msgbox", 5, 5, 1, j_msgbox},
-	{"--infobox", 5, 5, 1, j_infobox},
-	{NULL, 0, 0, 0, NULL}
-};
-
-static struct Mode *modePtr;
-
-#ifdef LOCALE
-#include <locale.h>
-#endif
-
-int main(int argc, const char *const *argv)
-{
-	int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
-	const char *title = NULL;
-
-#ifdef LOCALE
-	(void)setlocale(LC_ALL, "");
-#endif
-
-#ifdef TRACE
-	trace(TRACE_CALLS | TRACE_UPDATE);
-#endif
-	if (argc < 2) {
-		Usage(argv[0]);
-		exit(-1);
-	}
-
-	while (offset < argc - 1 && !end_common_opts) {	/* Common options */
-		if (!strcmp(argv[offset + 1], "--title")) {
-			if (argc - offset < 3 || title != NULL) {
-				Usage(argv[0]);
-				exit(-1);
-			} else {
-				title = argv[offset + 2];
-				offset += 2;
-			}
-		} else if (!strcmp(argv[offset + 1], "--backtitle")) {
-			if (backtitle != NULL) {
-				Usage(argv[0]);
-				exit(-1);
-			} else {
-				backtitle = argv[offset + 2];
-				offset += 2;
-			}
-		} else if (!strcmp(argv[offset + 1], "--clear")) {
-			if (opt_clear) {	/* Hey, "--clear" can't appear twice! */
-				Usage(argv[0]);
-				exit(-1);
-			} else if (argc == 2) {	/* we only want to clear the screen */
-				init_dialog();
-				refresh();	/* init_dialog() will clear the screen for us */
-				end_dialog();
-				return 0;
-			} else {
-				opt_clear = 1;
-				offset++;
-			}
-		} else		/* no more common options */
-			end_common_opts = 1;
-	}
-
-	if (argc - 1 == offset) {	/* no more options */
-		Usage(argv[0]);
-		exit(-1);
-	}
-	/* use a table to look for the requested mode, to avoid code duplication */
-
-	for (modePtr = modes; modePtr->name; modePtr++)	/* look for the mode */
-		if (!strcmp(argv[offset + 1], modePtr->name))
-			break;
-
-	if (!modePtr->name)
-		Usage(argv[0]);
-	if (argc - offset < modePtr->argmin)
-		Usage(argv[0]);
-	if (modePtr->argmax && argc - offset > modePtr->argmax)
-		Usage(argv[0]);
-
-	init_dialog();
-	retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
-
-	if (opt_clear) {	/* clear screen before exit */
-		attr_clear(stdscr, LINES, COLS, screen_attr);
-		refresh();
-	}
-	end_dialog();
-
-	exit(retval);
-}
-
-/*
- * Print program usage
- */
-static void Usage(const char *name)
-{
-	fprintf(stderr, "\
-\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
-\n  patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
-\n  modified/gutted for use as a Linux kernel config tool by \
-\n  William Roadcap (roadcapw@cfw.com)\
-\n\
-\n* Display dialog boxes from shell scripts *\
-\n\
-\nUsage: %s --clear\
-\n       %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
-\n\
-\nBox options:\
-\n\
-\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
-\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n  --textbox   <file> <height> <width>\
-\n  --inputbox  <text> <height> <width> [<init>]\
-\n  --yesno     <text> <height> <width>\
-\n", name, name);
-	exit(-1);
-}
-
-/*
- * These are the program jumpers
- */
-
-int j_menu(const char *t, int ac, const char *const *av)
-{
-	return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
-			   atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
-}
-
-int j_radiolist(const char *t, int ac, const char *const *av)
-{
-	return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
-				atoi(av[5]), (ac - 6) / 3, av + 6);
-}
-
-int j_textbox(const char *t, int ac, const char *const *av)
-{
-	return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_yesno(const char *t, int ac, const char *const *av)
-{
-	return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_inputbox(const char *t, int ac, const char *const *av)
-{
-	int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
-				  ac == 6 ? av[5] : (char *)NULL);
-	if (ret == 0)
-		fprintf(stderr, dialog_input_result);
-	return ret;
-}
-
-int j_msgbox(const char *t, int ac, const char *const *av)
-{
-	return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
-}
-
-int j_infobox(const char *t, int ac, const char *const *av)
-{
-	return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
-}
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index bf8052f..0d83159 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -63,19 +63,19 @@
 /*
  * Print menu item
  */
-static void do_print_item(WINDOW * win, const char *item, int choice,
+static void do_print_item(WINDOW * win, const char *item, int line_y,
                           int selected, int hotkey)
 {
 	int j;
 	char *menu_item = malloc(menu_width + 1);
 
 	strncpy(menu_item, item, menu_width - item_x);
-	menu_item[menu_width] = 0;
+	menu_item[menu_width - item_x] = '\0';
 	j = first_alpha(menu_item, "YyNnMmHh");
 
 	/* Clear 'residue' of last item */
-	wattrset(win, menubox_attr);
-	wmove(win, choice, 0);
+	wattrset(win, dlg.menubox.atr);
+	wmove(win, line_y, 0);
 #if OLD_NCURSES
 	{
 		int i;
@@ -85,23 +85,24 @@
 #else
 	wclrtoeol(win);
 #endif
-	wattrset(win, selected ? item_selected_attr : item_attr);
-	mvwaddstr(win, choice, item_x, menu_item);
+	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+	mvwaddstr(win, line_y, item_x, menu_item);
 	if (hotkey) {
-		wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
-		mvwaddch(win, choice, item_x + j, menu_item[j]);
+		wattrset(win, selected ? dlg.tag_key_selected.atr
+			 : dlg.tag_key.atr);
+		mvwaddch(win, line_y, item_x + j, menu_item[j]);
 	}
 	if (selected) {
-		wmove(win, choice, item_x + 1);
+		wmove(win, line_y, item_x + 1);
 	}
 	free(menu_item);
 	wrefresh(win);
 }
 
-#define print_item(index, choice, selected) \
-do {\
-	int hotkey = (items[(index) * 2][0] != ':'); \
-	do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
+#define print_item(index, choice, selected)				\
+do {									\
+	item_set(index);						\
+	do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
 } while (0)
 
 /*
@@ -117,11 +118,11 @@
 	wmove(win, y, x);
 
 	if (scroll > 0) {
-		wattrset(win, uarrow_attr);
+		wattrset(win, dlg.uarrow.atr);
 		waddch(win, ACS_UARROW);
 		waddstr(win, "(-)");
 	} else {
-		wattrset(win, menubox_attr);
+		wattrset(win, dlg.menubox.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -133,11 +134,11 @@
 	wrefresh(win);
 
 	if ((height < item_no) && (scroll + height < item_no)) {
-		wattrset(win, darrow_attr);
+		wattrset(win, dlg.darrow.atr);
 		waddch(win, ACS_DARROW);
 		waddstr(win, "(+)");
 	} else {
-		wattrset(win, menubox_border_attr);
+		wattrset(win, dlg.menubox_border.atr);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
 		waddch(win, ACS_HLINE);
@@ -178,17 +179,26 @@
 /*
  * Display a menu for choosing among a number of options
  */
-int dialog_menu(const char *title, const char *prompt, int height, int width,
-                int menu_height, const char *current, int item_no,
-                const char *const *items)
+int dialog_menu(const char *title, const char *prompt,
+                const void *selected, int *s_scroll)
 {
 	int i, j, x, y, box_x, box_y;
+	int height, width, menu_height;
 	int key = 0, button = 0, scroll = 0, choice = 0;
 	int first_item =  0, max_choice;
 	WINDOW *dialog, *menu;
-	FILE *f;
 
-	max_choice = MIN(menu_height, item_no);
+do_resize:
+	height = getmaxy(stdscr);
+	width = getmaxx(stdscr);
+	if (height < 15 || width < 65)
+		return -ERRDISPLAYTOOSMALL;
+
+	height -= 4;
+	width  -= 5;
+	menu_height = height - 10;
+
+	max_choice = MIN(menu_height, item_count());
 
 	/* center dialog box on screen */
 	x = (COLS - width) / 2;
@@ -199,18 +209,19 @@
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-	wattrset(dialog, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
-	wbkgdset(dialog, dialog_attr & A_COLOR);
+	wattrset(dialog, dlg.dialog.atr);
+	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
 
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	print_autowrap(dialog, prompt, width - 2, 1, 3);
 
 	menu_width = width - 6;
@@ -224,33 +235,29 @@
 
 	/* draw a box around the menu items */
 	draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
-		 menubox_border_attr, menubox_attr);
+		 dlg.menubox_border.atr, dlg.menubox.atr);
 
-	item_x = (menu_width - 70) / 2;
+	if (menu_width >= 80)
+		item_x = (menu_width - 70) / 2;
+	else
+		item_x = 4;
 
 	/* Set choice to default item */
-	for (i = 0; i < item_no; i++)
-		if (strcmp(current, items[i * 2]) == 0)
-			choice = i;
-
-	/* get the scroll info from the temp file */
-	if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) {
-		if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) &&
-		    (scroll + max_choice > choice) && (scroll >= 0) &&
-		    (scroll + max_choice <= item_no)) {
-			first_item = scroll;
-			choice = choice - scroll;
-			fclose(f);
-		} else {
-			scroll = 0;
-			remove("lxdialog.scrltmp");
-			fclose(f);
-			f = NULL;
-		}
+	item_foreach()
+		if (selected && (selected == item_data()))
+			choice = item_n();
+	/* get the saved scroll info */
+	scroll = *s_scroll;
+	if ((scroll <= choice) && (scroll + max_choice > choice) &&
+	   (scroll >= 0) && (scroll + max_choice <= item_count())) {
+		first_item = scroll;
+		choice = choice - scroll;
+	} else {
+		scroll = 0;
 	}
-	if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
-		if (choice >= item_no - max_choice / 2)
-			scroll = first_item = item_no - max_choice;
+	if ((choice >= max_choice)) {
+		if (choice >= item_count() - max_choice / 2)
+			scroll = first_item = item_count() - max_choice;
 		else
 			scroll = first_item = choice - max_choice / 2;
 		choice = choice - scroll;
@@ -263,14 +270,14 @@
 
 	wnoutrefresh(menu);
 
-	print_arrows(dialog, item_no, scroll,
+	print_arrows(dialog, item_count(), scroll,
 		     box_y, box_x + item_x + 1, menu_height);
 
 	print_buttons(dialog, height, width, 0);
 	wmove(menu, choice, item_x + 1);
 	wrefresh(menu);
 
-	while (key != ESC) {
+	while (key != KEY_ESC) {
 		key = wgetch(menu);
 
 		if (key < 256 && isalpha(key))
@@ -280,14 +287,16 @@
 			i = max_choice;
 		else {
 			for (i = choice + 1; i < max_choice; i++) {
-				j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
-				if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+				item_set(scroll + i);
+				j = first_alpha(item_str(), "YyNnMmHh");
+				if (key == tolower(item_str()[j]))
 					break;
 			}
 			if (i == max_choice)
 				for (i = 0; i < max_choice; i++) {
-					j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
-					if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+					item_set(scroll + i);
+					j = first_alpha(item_str(), "YyNnMmHh");
+					if (key == tolower(item_str()[j]))
 						break;
 				}
 		}
@@ -312,7 +321,7 @@
 				print_item(scroll+choice, choice, FALSE);
 
 				if ((choice > max_choice - 3) &&
-				    (scroll + max_choice < item_no)) {
+				    (scroll + max_choice < item_count())) {
 					/* Scroll menu up */
 					do_scroll(menu, &scroll, 1);
 
@@ -335,7 +344,7 @@
 
 			} else if (key == KEY_NPAGE) {
 				for (i = 0; (i < max_choice); i++) {
-					if (scroll + max_choice < item_no) {
+					if (scroll + max_choice < item_count()) {
 						do_scroll(menu, &scroll, 1);
 						print_item(scroll+max_choice-1,
 							   max_choice - 1, FALSE);
@@ -349,7 +358,7 @@
 
 			print_item(scroll + choice, choice, TRUE);
 
-			print_arrows(dialog, item_no, scroll,
+			print_arrows(dialog, item_count(), scroll,
 				     box_y, box_x + item_x + 1, menu_height);
 
 			wnoutrefresh(dialog);
@@ -375,12 +384,11 @@
 		case 'm':
 		case '/':
 			/* save scroll info */
-			if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
-				fprintf(f, "%d\n", scroll);
-				fclose(f);
-			}
+			*s_scroll = scroll;
+			delwin(menu);
 			delwin(dialog);
-			fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+			item_set(scroll + choice);
+			item_set_selected(1);
 			switch (key) {
 			case 's':
 				return 3;
@@ -400,27 +408,27 @@
 		case '?':
 			button = 2;
 		case '\n':
+			*s_scroll = scroll;
+			delwin(menu);
 			delwin(dialog);
-			if (button == 2)
-				fprintf(stderr, "%s \"%s\"\n",
-					items[(scroll + choice) * 2],
-					items[(scroll + choice) * 2 + 1] +
-					first_alpha(items [(scroll + choice) * 2 + 1], ""));
-			else
-				fprintf(stderr, "%s\n",
-					items[(scroll + choice) * 2]);
-
-			remove("lxdialog.scrltmp");
+			item_set(scroll + choice);
+			item_set_selected(1);
 			return button;
 		case 'e':
 		case 'x':
-			key = ESC;
-		case ESC:
+			key = KEY_ESC;
 			break;
+		case KEY_ESC:
+			key = on_key_esc(menu);
+			break;
+		case KEY_RESIZE:
+			on_key_resize();
+			delwin(menu);
+			delwin(dialog);
+			goto do_resize;
 		}
 	}
-
+	delwin(menu);
 	delwin(dialog);
-	remove("lxdialog.scrltmp");
-	return -1;		/* ESC pressed */
+	return key;		/* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
deleted file mode 100644
index 7323f54..0000000
--- a/scripts/kconfig/lxdialog/msgbox.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  msgbox.c -- implements the message box and info box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int dialog_msgbox(const char *title, const char *prompt, int height, int width,
-                  int pause)
-{
-	int i, x, y, key = 0;
-	WINDOW *dialog;
-
-	/* center dialog box on screen */
-	x = (COLS - width) / 2;
-	y = (LINES - height) / 2;
-
-	draw_shadow(stdscr, y, x, height, width);
-
-	dialog = newwin(height, width, y, x);
-	keypad(dialog, TRUE);
-
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-	print_title(dialog, title, width);
-
-	wattrset(dialog, dialog_attr);
-	print_autowrap(dialog, prompt, width - 2, 1, 2);
-
-	if (pause) {
-		wattrset(dialog, border_attr);
-		mvwaddch(dialog, height - 3, 0, ACS_LTEE);
-		for (i = 0; i < width - 2; i++)
-			waddch(dialog, ACS_HLINE);
-		wattrset(dialog, dialog_attr);
-		waddch(dialog, ACS_RTEE);
-
-		print_button(dialog, "  Ok  ", height - 2, width / 2 - 4, TRUE);
-
-		wrefresh(dialog);
-		while (key != ESC && key != '\n' && key != ' ' &&
-		       key != 'O' && key != 'o' && key != 'X' && key != 'x')
-			key = wgetch(dialog);
-	} else {
-		key = '\n';
-		wrefresh(dialog);
-	}
-
-	delwin(dialog);
-	return key == ESC ? -1 : 0;
-}
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 77848bb..fabfc1a 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -25,56 +25,62 @@
 static void print_page(WINDOW * win, int height, int width);
 static void print_line(WINDOW * win, int row, int width);
 static char *get_line(void);
-static void print_position(WINDOW * win, int height, int width);
+static void print_position(WINDOW * win);
 
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
+static int hscroll;
+static int begin_reached, end_reached, page_length;
+static const char *buf;
+static const char *page;
+
+/*
+ * refresh window content
+ */
+static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
+							  int cur_y, int cur_x)
+{
+	print_page(box, boxh, boxw);
+	print_position(dialog);
+	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
+	wrefresh(dialog);
+}
+
 
 /*
  * Display text from a file in a dialog box.
  */
-int dialog_textbox(const char *title, const char *file, int height, int width)
+int dialog_textbox(const char *title, const char *tbuf,
+		   int initial_height, int initial_width)
 {
-	int i, x, y, cur_x, cur_y, fpos, key = 0;
+	int i, x, y, cur_x, cur_y, key = 0;
+	int height, width, boxh, boxw;
 	int passed_end;
-	char search_term[MAX_LEN + 1];
-	WINDOW *dialog, *text;
+	WINDOW *dialog, *box;
 
-	search_term[0] = '\0';	/* no search term entered yet */
+	begin_reached = 1;
+	end_reached = 0;
+	page_length = 0;
+	hscroll = 0;
+	buf = tbuf;
+	page = buf;	/* page is pointer to start of page to be displayed */
 
-	/* Open input file for reading */
-	if ((fd = open(file, O_RDONLY)) == -1) {
-		endwin();
-		fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
-		exit(-1);
-	}
-	/* Get file size. Actually, 'file_size' is the real file size - 1,
-	   since it's only the last byte offset from the beginning */
-	if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
-		endwin();
-		fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
-		exit(-1);
-	}
-	/* Restore file pointer to beginning of file after getting file size */
-	if (lseek(fd, 0, SEEK_SET) == -1) {
-		endwin();
-		fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-		exit(-1);
-	}
-	/* Allocate space for read buffer */
-	if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
-		endwin();
-		fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
-		exit(-1);
-	}
-	if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
-		endwin();
-		fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-		exit(-1);
-	}
-	buf[bytes_read] = '\0';	/* mark end of valid data */
-	page = buf;		/* page is pointer to start of page to be displayed */
+do_resize:
+	getmaxyx(stdscr, height, width);
+	if (height < 8 || width < 8)
+		return -ERRDISPLAYTOOSMALL;
+	if (initial_height != 0)
+		height = initial_height;
+	else
+		if (height > 4)
+			height -= 4;
+		else
+			height = 0;
+	if (initial_width != 0)
+		width = initial_width;
+	else
+		if (width > 5)
+			width -= 5;
+		else
+			width = 0;
 
 	/* center dialog box on screen */
 	x = (COLS - width) / 2;
@@ -85,22 +91,25 @@
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	/* Create window for text region, used for scrolling text */
-	text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
-	wattrset(text, dialog_attr);
-	wbkgdset(text, dialog_attr & A_COLOR);
+	/* Create window for box region, used for scrolling text */
+	boxh = height - 4;
+	boxw = width - 2;
+	box = subwin(dialog, boxh, boxw, y + 1, x + 1);
+	wattrset(box, dlg.dialog.atr);
+	wbkgdset(box, dlg.dialog.atr & A_COLOR);
 
-	keypad(text, TRUE);
+	keypad(box, TRUE);
 
 	/* register the new window, along with its borders */
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
 
-	wattrset(dialog, border_attr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
-	wbkgdset(dialog, dialog_attr & A_COLOR);
+	wattrset(dialog, dlg.dialog.atr);
+	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
@@ -110,85 +119,37 @@
 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
 
 	/* Print first page of text */
-	attr_clear(text, height - 4, width - 2, dialog_attr);
-	print_page(text, height - 4, width - 2);
-	print_position(dialog, height, width);
-	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-	wrefresh(dialog);
+	attr_clear(box, boxh, boxw, dlg.dialog.atr);
+	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
 
-	while ((key != ESC) && (key != '\n')) {
+	while ((key != KEY_ESC) && (key != '\n')) {
 		key = wgetch(dialog);
 		switch (key) {
 		case 'E':	/* Exit */
 		case 'e':
 		case 'X':
 		case 'x':
+			delwin(box);
 			delwin(dialog);
-			free(buf);
-			close(fd);
 			return 0;
 		case 'g':	/* First page */
 		case KEY_HOME:
 			if (!begin_reached) {
 				begin_reached = 1;
-				/* First page not in buffer? */
-				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-					exit(-1);
-				}
-				if (fpos > bytes_read) {	/* Yes, we have to read it in */
-					if (lseek(fd, 0, SEEK_SET) == -1) {
-						endwin();
-						fprintf(stderr, "\nError moving file pointer in "
-							        "dialog_textbox().\n");
-						exit(-1);
-					}
-					if ((bytes_read =
-					     read(fd, buf, BUF_SIZE)) == -1) {
-						endwin();
-						fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-						exit(-1);
-					}
-					buf[bytes_read] = '\0';
-				}
 				page = buf;
-				print_page(text, height - 4, width - 2);
-				print_position(dialog, height, width);
-				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-				wrefresh(dialog);
+				refresh_text_box(dialog, box, boxh, boxw,
+						 cur_y, cur_x);
 			}
 			break;
 		case 'G':	/* Last page */
 		case KEY_END:
 
 			end_reached = 1;
-			/* Last page not in buffer? */
-			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-				endwin();
-				fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-				exit(-1);
-			}
-			if (fpos < file_size) {	/* Yes, we have to read it in */
-				if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
-					endwin();
-					fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-					exit(-1);
-				}
-				if ((bytes_read =
-				     read(fd, buf, BUF_SIZE)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-					exit(-1);
-				}
-				buf[bytes_read] = '\0';
-			}
-			page = buf + bytes_read;
-			back_lines(height - 4);
-			print_page(text, height - 4, width - 2);
-			print_position(dialog, height, width);
-			wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-			wrefresh(dialog);
+			/* point to last char in buf */
+			page = buf + strlen(buf);
+			back_lines(boxh);
+			refresh_text_box(dialog, box, boxh, boxw,
+					 cur_y, cur_x);
 			break;
 		case 'K':	/* Previous line */
 		case 'k':
@@ -196,21 +157,23 @@
 			if (!begin_reached) {
 				back_lines(page_length + 1);
 
-				/* We don't call print_page() here but use scrolling to ensure
-				   faster screen update. However, 'end_reached' and
-				   'page_length' should still be updated, and 'page' should
-				   point to start of next page. This is done by calling
-				   get_line() in the following 'for' loop. */
-				scrollok(text, TRUE);
-				wscrl(text, -1);	/* Scroll text region down one line */
-				scrollok(text, FALSE);
+				/* We don't call print_page() here but use
+				 * scrolling to ensure faster screen update.
+				 * However, 'end_reached' and 'page_length'
+				 * should still be updated, and 'page' should
+				 * point to start of next page. This is done
+				 * by calling get_line() in the following
+				 * 'for' loop. */
+				scrollok(box, TRUE);
+				wscrl(box, -1);	/* Scroll box region down one line */
+				scrollok(box, FALSE);
 				page_length = 0;
 				passed_end = 0;
-				for (i = 0; i < height - 4; i++) {
+				for (i = 0; i < boxh; i++) {
 					if (!i) {
 						/* print first line of page */
-						print_line(text, 0, width - 2);
-						wnoutrefresh(text);
+						print_line(box, 0, boxw);
+						wnoutrefresh(box);
 					} else
 						/* Called to update 'end_reached' and 'page' */
 						get_line();
@@ -220,7 +183,7 @@
 						passed_end = 1;
 				}
 
-				print_position(dialog, height, width);
+				print_position(dialog);
 				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
 				wrefresh(dialog);
 			}
@@ -230,23 +193,21 @@
 		case KEY_PPAGE:
 			if (begin_reached)
 				break;
-			back_lines(page_length + height - 4);
-			print_page(text, height - 4, width - 2);
-			print_position(dialog, height, width);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			back_lines(page_length + boxh);
+			refresh_text_box(dialog, box, boxh, boxw,
+					 cur_y, cur_x);
 			break;
 		case 'J':	/* Next line */
 		case 'j':
 		case KEY_DOWN:
 			if (!end_reached) {
 				begin_reached = 0;
-				scrollok(text, TRUE);
-				scroll(text);	/* Scroll text region up one line */
-				scrollok(text, FALSE);
-				print_line(text, height - 5, width - 2);
-				wnoutrefresh(text);
-				print_position(dialog, height, width);
+				scrollok(box, TRUE);
+				scroll(box);	/* Scroll box region up one line */
+				scrollok(box, FALSE);
+				print_line(box, boxh - 1, boxw);
+				wnoutrefresh(box);
+				print_position(dialog);
 				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
 				wrefresh(dialog);
 			}
@@ -257,10 +218,8 @@
 				break;
 
 			begin_reached = 0;
-			print_page(text, height - 4, width - 2);
-			print_position(dialog, height, width);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			refresh_text_box(dialog, box, boxh, boxw,
+					 cur_y, cur_x);
 			break;
 		case '0':	/* Beginning of line */
 		case 'H':	/* Scroll left */
@@ -275,9 +234,8 @@
 				hscroll--;
 			/* Reprint current page to scroll horizontally */
 			back_lines(page_length);
-			print_page(text, height - 4, width - 2);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			refresh_text_box(dialog, box, boxh, boxw,
+					 cur_y, cur_x);
 			break;
 		case 'L':	/* Scroll right */
 		case 'l':
@@ -287,131 +245,56 @@
 			hscroll++;
 			/* Reprint current page to scroll horizontally */
 			back_lines(page_length);
-			print_page(text, height - 4, width - 2);
-			wmove(dialog, cur_y, cur_x);
-			wrefresh(dialog);
+			refresh_text_box(dialog, box, boxh, boxw,
+					 cur_y, cur_x);
 			break;
-		case ESC:
+		case KEY_ESC:
+			key = on_key_esc(dialog);
 			break;
+		case KEY_RESIZE:
+			back_lines(height);
+			delwin(box);
+			delwin(dialog);
+			on_key_resize();
+			goto do_resize;
 		}
 	}
-
+	delwin(box);
 	delwin(dialog);
-	free(buf);
-	close(fd);
-	return -1;		/* ESC pressed */
+	return key;		/* ESC pressed */
 }
 
 /*
- * Go back 'n' lines in text file. Called by dialog_textbox().
+ * Go back 'n' lines in text. Called by dialog_textbox().
  * 'page' will be updated to point to the desired line in 'buf'.
  */
 static void back_lines(int n)
 {
-	int i, fpos;
+	int i;
 
 	begin_reached = 0;
-	/* We have to distinguish between end_reached and !end_reached
-	   since at end of file, the line is not ended by a '\n'.
-	   The code inside 'if' basically does a '--page' to move one
-	   character backward so as to skip '\n' of the previous line */
-	if (!end_reached) {
-		/* Either beginning of buffer or beginning of file reached? */
-		if (page == buf) {
-			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-				endwin();
-				fprintf(stderr, "\nError moving file pointer in "
-					        "back_lines().\n");
-				exit(-1);
+	/* Go back 'n' lines */
+	for (i = 0; i < n; i++) {
+		if (*page == '\0') {
+			if (end_reached) {
+				end_reached = 0;
+				continue;
 			}
-			if (fpos > bytes_read) {	/* Not beginning of file yet */
-				/* We've reached beginning of buffer, but not beginning of
-				   file yet, so read previous part of file into buffer.
-				   Note that we only move backward for BUF_SIZE/2 bytes,
-				   but not BUF_SIZE bytes to avoid re-reading again in
-				   print_page() later */
-				/* Really possible to move backward BUF_SIZE/2 bytes? */
-				if (fpos < BUF_SIZE / 2 + bytes_read) {
-					/* No, move less then */
-					if (lseek(fd, 0, SEEK_SET) == -1) {
-						endwin();
-						fprintf(stderr, "\nError moving file pointer in "
-						                "back_lines().\n");
-						exit(-1);
-					}
-					page = buf + fpos - bytes_read;
-				} else {	/* Move backward BUF_SIZE/2 bytes */
-					if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
-						endwin();
-						fprintf(stderr, "\nError moving file pointer "
-						                "in back_lines().\n");
-						exit(-1);
-					}
-					page = buf + BUF_SIZE / 2;
-				}
-				if ((bytes_read =
-				     read(fd, buf, BUF_SIZE)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError reading file in back_lines().\n");
-					exit(-1);
-				}
-				buf[bytes_read] = '\0';
-			} else {	/* Beginning of file reached */
+		}
+		if (page == buf) {
+			begin_reached = 1;
+			return;
+		}
+		page--;
+		do {
+			if (page == buf) {
 				begin_reached = 1;
 				return;
 			}
-		}
-		if (*(--page) != '\n') {	/* '--page' here */
-			/* Something's wrong... */
-			endwin();
-			fprintf(stderr, "\nInternal error in back_lines().\n");
-			exit(-1);
-		}
+			page--;
+		} while (*page != '\n');
+		page++;
 	}
-	/* Go back 'n' lines */
-	for (i = 0; i < n; i++)
-		do {
-			if (page == buf) {
-				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError moving file pointer in back_lines().\n");
-					exit(-1);
-				}
-				if (fpos > bytes_read) {
-					/* Really possible to move backward BUF_SIZE/2 bytes? */
-					if (fpos < BUF_SIZE / 2 + bytes_read) {
-						/* No, move less then */
-						if (lseek(fd, 0, SEEK_SET) == -1) {
-							endwin();
-							fprintf(stderr, "\nError moving file pointer "
-							                "in back_lines().\n");
-							exit(-1);
-						}
-						page = buf + fpos - bytes_read;
-					} else {	/* Move backward BUF_SIZE/2 bytes */
-						if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
-							endwin();
-							fprintf(stderr, "\nError moving file pointer"
-							                " in back_lines().\n");
-							exit(-1);
-						}
-						page = buf + BUF_SIZE / 2;
-					}
-					if ((bytes_read =
-					     read(fd, buf, BUF_SIZE)) == -1) {
-						endwin();
-						fprintf(stderr, "\nError reading file in "
-						                "back_lines().\n");
-						exit(-1);
-					}
-					buf[bytes_read] = '\0';
-				} else {	/* Beginning of file reached */
-					begin_reached = 1;
-					return;
-				}
-			}
-		} while (*(--page) != '\n');
-	page++;
 }
 
 /*
@@ -466,33 +349,14 @@
  */
 static char *get_line(void)
 {
-	int i = 0, fpos;
+	int i = 0;
 	static char line[MAX_LEN + 1];
 
 	end_reached = 0;
 	while (*page != '\n') {
 		if (*page == '\0') {
-			/* Either end of file or end of buffer reached */
-			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-				endwin();
-				fprintf(stderr, "\nError moving file pointer in "
-				                "get_line().\n");
-				exit(-1);
-			}
-			if (fpos < file_size) {	/* Not end of file yet */
-				/* We've reached end of buffer, but not end of file yet,
-				   so read next part of file into buffer */
-				if ((bytes_read =
-				     read(fd, buf, BUF_SIZE)) == -1) {
-					endwin();
-					fprintf(stderr, "\nError reading file in get_line().\n");
-					exit(-1);
-				}
-				buf[bytes_read] = '\0';
-				page = buf;
-			} else {
-				if (!end_reached)
-					end_reached = 1;
+			if (!end_reached) {
+				end_reached = 1;
 				break;
 			}
 		} else if (i < MAX_LEN)
@@ -515,19 +379,13 @@
 /*
  * Print current position
  */
-static void print_position(WINDOW * win, int height, int width)
+static void print_position(WINDOW * win)
 {
-	int fpos, percent;
+	int percent;
 
-	if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-		endwin();
-		fprintf(stderr, "\nError moving file pointer in print_position().\n");
-		exit(-1);
-	}
-	wattrset(win, position_indicator_attr);
-	wbkgdset(win, position_indicator_attr & A_COLOR);
-	percent = !file_size ?
-	    100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
-	wmove(win, height - 3, width - 9);
+	wattrset(win, dlg.position_indicator.atr);
+	wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
+	percent = (page - buf) * 100 / strlen(buf);
+	wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
 	wprintw(win, "(%3d%%)", percent);
 }
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index f82cebb..ebc781b 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -21,85 +21,217 @@
 
 #include "dialog.h"
 
-/* use colors by default? */
-bool use_colors = 1;
+struct dialog_info dlg;
 
-const char *backtitle = NULL;
+static void set_mono_theme(void)
+{
+	dlg.screen.atr = A_NORMAL;
+	dlg.shadow.atr = A_NORMAL;
+	dlg.dialog.atr = A_NORMAL;
+	dlg.title.atr = A_BOLD;
+	dlg.border.atr = A_NORMAL;
+	dlg.button_active.atr = A_REVERSE;
+	dlg.button_inactive.atr = A_DIM;
+	dlg.button_key_active.atr = A_REVERSE;
+	dlg.button_key_inactive.atr = A_BOLD;
+	dlg.button_label_active.atr = A_REVERSE;
+	dlg.button_label_inactive.atr = A_NORMAL;
+	dlg.inputbox.atr = A_NORMAL;
+	dlg.inputbox_border.atr = A_NORMAL;
+	dlg.searchbox.atr = A_NORMAL;
+	dlg.searchbox_title.atr = A_BOLD;
+	dlg.searchbox_border.atr = A_NORMAL;
+	dlg.position_indicator.atr = A_BOLD;
+	dlg.menubox.atr = A_NORMAL;
+	dlg.menubox_border.atr = A_NORMAL;
+	dlg.item.atr = A_NORMAL;
+	dlg.item_selected.atr = A_REVERSE;
+	dlg.tag.atr = A_BOLD;
+	dlg.tag_selected.atr = A_REVERSE;
+	dlg.tag_key.atr = A_BOLD;
+	dlg.tag_key_selected.atr = A_REVERSE;
+	dlg.check.atr = A_BOLD;
+	dlg.check_selected.atr = A_REVERSE;
+	dlg.uarrow.atr = A_BOLD;
+	dlg.darrow.atr = A_BOLD;
+}
+
+#define DLG_COLOR(dialog, f, b, h) \
+do {                               \
+	dlg.dialog.fg = (f);       \
+	dlg.dialog.bg = (b);       \
+	dlg.dialog.hl = (h);       \
+} while (0)
+
+static void set_classic_theme(void)
+{
+	DLG_COLOR(screen,                COLOR_CYAN,   COLOR_BLUE,   true);
+	DLG_COLOR(shadow,                COLOR_BLACK,  COLOR_BLACK,  true);
+	DLG_COLOR(dialog,                COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(title,                 COLOR_YELLOW, COLOR_WHITE,  true);
+	DLG_COLOR(border,                COLOR_WHITE,  COLOR_WHITE,  true);
+	DLG_COLOR(button_active,         COLOR_WHITE,  COLOR_BLUE,   true);
+	DLG_COLOR(button_inactive,       COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(button_key_active,     COLOR_WHITE,  COLOR_BLUE,   true);
+	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_WHITE,  false);
+	DLG_COLOR(button_label_active,   COLOR_YELLOW, COLOR_BLUE,   true);
+	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_WHITE,  true);
+	DLG_COLOR(inputbox,              COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(inputbox_border,       COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(searchbox,             COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(searchbox_title,       COLOR_YELLOW, COLOR_WHITE,  true);
+	DLG_COLOR(searchbox_border,      COLOR_WHITE,  COLOR_WHITE,  true);
+	DLG_COLOR(position_indicator,    COLOR_YELLOW, COLOR_WHITE,  true);
+	DLG_COLOR(menubox,               COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(menubox_border,        COLOR_WHITE,  COLOR_WHITE,  true);
+	DLG_COLOR(item,                  COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(item_selected,         COLOR_WHITE,  COLOR_BLUE,   true);
+	DLG_COLOR(tag,                   COLOR_YELLOW, COLOR_WHITE,  true);
+	DLG_COLOR(tag_selected,          COLOR_YELLOW, COLOR_BLUE,   true);
+	DLG_COLOR(tag_key,               COLOR_YELLOW, COLOR_WHITE,  true);
+	DLG_COLOR(tag_key_selected,      COLOR_YELLOW, COLOR_BLUE,   true);
+	DLG_COLOR(check,                 COLOR_BLACK,  COLOR_WHITE,  false);
+	DLG_COLOR(check_selected,        COLOR_WHITE,  COLOR_BLUE,   true);
+	DLG_COLOR(uarrow,                COLOR_GREEN,  COLOR_WHITE,  true);
+	DLG_COLOR(darrow,                COLOR_GREEN,  COLOR_WHITE,  true);
+}
+
+static void set_blackbg_theme(void)
+{
+	DLG_COLOR(screen, COLOR_RED,   COLOR_BLACK, true);
+	DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
+	DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
+	DLG_COLOR(title,  COLOR_RED,   COLOR_BLACK, false);
+	DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
+
+	DLG_COLOR(button_active,         COLOR_YELLOW, COLOR_RED,   false);
+	DLG_COLOR(button_inactive,       COLOR_YELLOW, COLOR_BLACK, false);
+	DLG_COLOR(button_key_active,     COLOR_YELLOW, COLOR_RED,   true);
+	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_BLACK, false);
+	DLG_COLOR(button_label_active,   COLOR_WHITE,  COLOR_RED,   false);
+	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_BLACK, true);
+
+	DLG_COLOR(inputbox,         COLOR_YELLOW, COLOR_BLACK, false);
+	DLG_COLOR(inputbox_border,  COLOR_YELLOW, COLOR_BLACK, false);
+
+	DLG_COLOR(searchbox,        COLOR_YELLOW, COLOR_BLACK, false);
+	DLG_COLOR(searchbox_title,  COLOR_YELLOW, COLOR_BLACK, true);
+	DLG_COLOR(searchbox_border, COLOR_BLACK,  COLOR_BLACK, true);
+
+	DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK,  false);
+
+	DLG_COLOR(menubox,          COLOR_YELLOW, COLOR_BLACK, false);
+	DLG_COLOR(menubox_border,   COLOR_BLACK,  COLOR_BLACK, true);
+
+	DLG_COLOR(item,             COLOR_WHITE, COLOR_BLACK, false);
+	DLG_COLOR(item_selected,    COLOR_WHITE, COLOR_RED,   false);
+
+	DLG_COLOR(tag,              COLOR_RED,    COLOR_BLACK, false);
+	DLG_COLOR(tag_selected,     COLOR_YELLOW, COLOR_RED,   true);
+	DLG_COLOR(tag_key,          COLOR_RED,    COLOR_BLACK, false);
+	DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED,   true);
+
+	DLG_COLOR(check,            COLOR_YELLOW, COLOR_BLACK, false);
+	DLG_COLOR(check_selected,   COLOR_YELLOW, COLOR_RED,   true);
+
+	DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
+	DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
+}
+
+static void set_bluetitle_theme(void)
+{
+	set_classic_theme();
+	DLG_COLOR(title,               COLOR_BLUE,   COLOR_WHITE, true);
+	DLG_COLOR(button_key_active,   COLOR_YELLOW, COLOR_BLUE,  true);
+	DLG_COLOR(button_label_active, COLOR_WHITE,  COLOR_BLUE,  true);
+	DLG_COLOR(searchbox_title,     COLOR_BLUE,   COLOR_WHITE, true);
+	DLG_COLOR(position_indicator,  COLOR_BLUE,   COLOR_WHITE, true);
+	DLG_COLOR(tag,                 COLOR_BLUE,   COLOR_WHITE, true);
+	DLG_COLOR(tag_key,             COLOR_BLUE,   COLOR_WHITE, true);
+
+}
 
 /*
- * Attribute values, default is for mono display
+ * Select color theme
  */
-chtype attributes[] = {
-	A_NORMAL,		/* screen_attr */
-	A_NORMAL,		/* shadow_attr */
-	A_NORMAL,		/* dialog_attr */
-	A_BOLD,			/* title_attr */
-	A_NORMAL,		/* border_attr */
-	A_REVERSE,		/* button_active_attr */
-	A_DIM,			/* button_inactive_attr */
-	A_REVERSE,		/* button_key_active_attr */
-	A_BOLD,			/* button_key_inactive_attr */
-	A_REVERSE,		/* button_label_active_attr */
-	A_NORMAL,		/* button_label_inactive_attr */
-	A_NORMAL,		/* inputbox_attr */
-	A_NORMAL,		/* inputbox_border_attr */
-	A_NORMAL,		/* searchbox_attr */
-	A_BOLD,			/* searchbox_title_attr */
-	A_NORMAL,		/* searchbox_border_attr */
-	A_BOLD,			/* position_indicator_attr */
-	A_NORMAL,		/* menubox_attr */
-	A_NORMAL,		/* menubox_border_attr */
-	A_NORMAL,		/* item_attr */
-	A_REVERSE,		/* item_selected_attr */
-	A_BOLD,			/* tag_attr */
-	A_REVERSE,		/* tag_selected_attr */
-	A_BOLD,			/* tag_key_attr */
-	A_REVERSE,		/* tag_key_selected_attr */
-	A_BOLD,			/* check_attr */
-	A_REVERSE,		/* check_selected_attr */
-	A_BOLD,			/* uarrow_attr */
-	A_BOLD			/* darrow_attr */
-};
+static int set_theme(const char *theme)
+{
+	int use_color = 1;
+	if (!theme)
+		set_bluetitle_theme();
+	else if (strcmp(theme, "classic") == 0)
+		set_classic_theme();
+	else if (strcmp(theme, "bluetitle") == 0)
+		set_bluetitle_theme();
+	else if (strcmp(theme, "blackbg") == 0)
+		set_blackbg_theme();
+	else if (strcmp(theme, "mono") == 0)
+		use_color = 0;
 
-#include "colors.h"
+	return use_color;
+}
+
+static void init_one_color(struct dialog_color *color)
+{
+	static int pair = 0;
+
+	pair++;
+	init_pair(pair, color->fg, color->bg);
+	if (color->hl)
+		color->atr = A_BOLD | COLOR_PAIR(pair);
+	else
+		color->atr = COLOR_PAIR(pair);
+}
+
+static void init_dialog_colors(void)
+{
+	init_one_color(&dlg.screen);
+	init_one_color(&dlg.shadow);
+	init_one_color(&dlg.dialog);
+	init_one_color(&dlg.title);
+	init_one_color(&dlg.border);
+	init_one_color(&dlg.button_active);
+	init_one_color(&dlg.button_inactive);
+	init_one_color(&dlg.button_key_active);
+	init_one_color(&dlg.button_key_inactive);
+	init_one_color(&dlg.button_label_active);
+	init_one_color(&dlg.button_label_inactive);
+	init_one_color(&dlg.inputbox);
+	init_one_color(&dlg.inputbox_border);
+	init_one_color(&dlg.searchbox);
+	init_one_color(&dlg.searchbox_title);
+	init_one_color(&dlg.searchbox_border);
+	init_one_color(&dlg.position_indicator);
+	init_one_color(&dlg.menubox);
+	init_one_color(&dlg.menubox_border);
+	init_one_color(&dlg.item);
+	init_one_color(&dlg.item_selected);
+	init_one_color(&dlg.tag);
+	init_one_color(&dlg.tag_selected);
+	init_one_color(&dlg.tag_key);
+	init_one_color(&dlg.tag_key_selected);
+	init_one_color(&dlg.check);
+	init_one_color(&dlg.check_selected);
+	init_one_color(&dlg.uarrow);
+	init_one_color(&dlg.darrow);
+}
 
 /*
- * Table of color values
+ * Setup for color display
  */
-int color_table[][3] = {
-	{SCREEN_FG, SCREEN_BG, SCREEN_HL},
-	{SHADOW_FG, SHADOW_BG, SHADOW_HL},
-	{DIALOG_FG, DIALOG_BG, DIALOG_HL},
-	{TITLE_FG, TITLE_BG, TITLE_HL},
-	{BORDER_FG, BORDER_BG, BORDER_HL},
-	{BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
-	{BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
-	{BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
-	{BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG,
-	 BUTTON_KEY_INACTIVE_HL},
-	{BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG,
-	 BUTTON_LABEL_ACTIVE_HL},
-	{BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
-	 BUTTON_LABEL_INACTIVE_HL},
-	{INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
-	{INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
-	{SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
-	{SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
-	{SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
-	{POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
-	{MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
-	{MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
-	{ITEM_FG, ITEM_BG, ITEM_HL},
-	{ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
-	{TAG_FG, TAG_BG, TAG_HL},
-	{TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
-	{TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
-	{TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
-	{CHECK_FG, CHECK_BG, CHECK_HL},
-	{CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
-	{UARROW_FG, UARROW_BG, UARROW_HL},
-	{DARROW_FG, DARROW_BG, DARROW_HL},
-};				/* color_table */
+static void color_setup(const char *theme)
+{
+	if (set_theme(theme)) {
+		if (has_colors()) {	/* Terminal supports color? */
+			start_color();
+			init_dialog_colors();
+		}
+	}
+	else
+	{
+		set_mono_theme();
+	}
+}
 
 /*
  * Set window to attribute 'attr'
@@ -119,13 +251,13 @@
 
 void dialog_clear(void)
 {
-	attr_clear(stdscr, LINES, COLS, screen_attr);
+	attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
 	/* Display background title if it exists ... - SLH */
-	if (backtitle != NULL) {
+	if (dlg.backtitle != NULL) {
 		int i;
 
-		wattrset(stdscr, screen_attr);
-		mvwaddstr(stdscr, 0, 1, (char *)backtitle);
+		wattrset(stdscr, dlg.screen.atr);
+		mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
 		wmove(stdscr, 1, 1);
 		for (i = 1; i < COLS - 1; i++)
 			waddch(stdscr, ACS_HLINE);
@@ -136,40 +268,22 @@
 /*
  * Do some initialization for dialog
  */
-void init_dialog(void)
+void init_dialog(const char *backtitle)
+{
+	dlg.backtitle = backtitle;
+	color_setup(getenv("MENUCONFIG_COLOR"));
+}
+
+void reset_dialog(void)
 {
 	initscr();		/* Init curses */
 	keypad(stdscr, TRUE);
 	cbreak();
 	noecho();
-
-	if (use_colors)		/* Set up colors */
-		color_setup();
-
 	dialog_clear();
 }
 
 /*
- * Setup for color display
- */
-void color_setup(void)
-{
-	int i;
-
-	if (has_colors()) {	/* Terminal supports color? */
-		start_color();
-
-		/* Initialize color pairs */
-		for (i = 0; i < ATTRIBUTE_COUNT; i++)
-			init_pair(i + 1, color_table[i][0], color_table[i][1]);
-
-		/* Setup color attributes */
-		for (i = 0; i < ATTRIBUTE_COUNT; i++)
-			attributes[i] = C_ATTR(color_table[i][2], i + 1);
-	}
-}
-
-/*
  * End using dialog functions.
  */
 void end_dialog(void)
@@ -184,7 +298,7 @@
 {
 	if (title) {
 		int tlen = MIN(width - 2, strlen(title));
-		wattrset(dialog, title_attr);
+		wattrset(dialog, dlg.title.atr);
 		mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
 		mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
 		waddch(dialog, ' ');
@@ -264,21 +378,23 @@
 	int i, temp;
 
 	wmove(win, y, x);
-	wattrset(win, selected ? button_active_attr : button_inactive_attr);
+	wattrset(win, selected ? dlg.button_active.atr
+		 : dlg.button_inactive.atr);
 	waddstr(win, "<");
 	temp = strspn(label, " ");
 	label += temp;
-	wattrset(win, selected ? button_label_active_attr
-		 : button_label_inactive_attr);
+	wattrset(win, selected ? dlg.button_label_active.atr
+		 : dlg.button_label_inactive.atr);
 	for (i = 0; i < temp; i++)
 		waddch(win, ' ');
-	wattrset(win, selected ? button_key_active_attr
-		 : button_key_inactive_attr);
+	wattrset(win, selected ? dlg.button_key_active.atr
+		 : dlg.button_key_inactive.atr);
 	waddch(win, label[0]);
-	wattrset(win, selected ? button_label_active_attr
-		 : button_label_inactive_attr);
+	wattrset(win, selected ? dlg.button_label_active.atr
+		 : dlg.button_label_inactive.atr);
 	waddstr(win, (char *)label + 1);
-	wattrset(win, selected ? button_active_attr : button_inactive_attr);
+	wattrset(win, selected ? dlg.button_active.atr
+		 : dlg.button_inactive.atr);
 	waddstr(win, ">");
 	wmove(win, y, x + temp + 1);
 }
@@ -326,7 +442,7 @@
 	int i;
 
 	if (has_colors()) {	/* Whether terminal supports color? */
-		wattrset(win, shadow_attr);
+		wattrset(win, dlg.shadow.atr);
 		wmove(win, y + height, x + 2);
 		for (i = 0; i < width; i++)
 			waddch(win, winch(win) & A_CHARTEXT);
@@ -360,3 +476,167 @@
 
 	return 0;
 }
+
+/*
+ * ncurses uses ESC to detect escaped char sequences. This resutl in
+ * a small timeout before ESC is actually delivered to the application.
+ * lxdialog suggest <ESC> <ESC> which is correctly translated to two
+ * times esc. But then we need to ignore the second esc to avoid stepping
+ * out one menu too much. Filter away all escaped key sequences since
+ * keypad(FALSE) turn off ncurses support for escape sequences - and thats
+ * needed to make notimeout() do as expected.
+ */
+int on_key_esc(WINDOW *win)
+{
+	int key;
+	int key2;
+	int key3;
+
+	nodelay(win, TRUE);
+	keypad(win, FALSE);
+	key = wgetch(win);
+	key2 = wgetch(win);
+	do {
+		key3 = wgetch(win);
+	} while (key3 != ERR);
+	nodelay(win, FALSE);
+	keypad(win, TRUE);
+	if (key == KEY_ESC && key2 == ERR)
+		return KEY_ESC;
+	else if (key != ERR && key != KEY_ESC && key2 == ERR)
+		ungetch(key);
+
+	return -1;
+}
+
+/* redraw screen in new size */
+int on_key_resize(void)
+{
+	dialog_clear();
+	return KEY_RESIZE;
+}
+
+struct dialog_list *item_cur;
+struct dialog_list item_nil;
+struct dialog_list *item_head;
+
+void item_reset(void)
+{
+	struct dialog_list *p, *next;
+
+	for (p = item_head; p; p = next) {
+		next = p->next;
+		free(p);
+	}
+	item_head = NULL;
+	item_cur = &item_nil;
+}
+
+void item_make(const char *fmt, ...)
+{
+	va_list ap;
+	struct dialog_list *p = malloc(sizeof(*p));
+
+	if (item_head)
+		item_cur->next = p;
+	else
+		item_head = p;
+	item_cur = p;
+	memset(p, 0, sizeof(*p));
+
+	va_start(ap, fmt);
+	vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
+	va_end(ap);
+}
+
+void item_add_str(const char *fmt, ...)
+{
+	va_list ap;
+        size_t avail;
+
+	avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
+
+	va_start(ap, fmt);
+	vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
+		  avail, fmt, ap);
+	item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
+	va_end(ap);
+}
+
+void item_set_tag(char tag)
+{
+	item_cur->node.tag = tag;
+}
+void item_set_data(void *ptr)
+{
+	item_cur->node.data = ptr;
+}
+
+void item_set_selected(int val)
+{
+	item_cur->node.selected = val;
+}
+
+int item_activate_selected(void)
+{
+	item_foreach()
+		if (item_is_selected())
+			return 1;
+	return 0;
+}
+
+void *item_data(void)
+{
+	return item_cur->node.data;
+}
+
+char item_tag(void)
+{
+	return item_cur->node.tag;
+}
+
+int item_count(void)
+{
+	int n = 0;
+	struct dialog_list *p;
+
+	for (p = item_head; p; p = p->next)
+		n++;
+	return n;
+}
+
+void item_set(int n)
+{
+	int i = 0;
+	item_foreach()
+		if (i++ == n)
+			return;
+}
+
+int item_n(void)
+{
+	int n = 0;
+	struct dialog_list *p;
+
+	for (p = item_head; p; p = p->next) {
+		if (p == item_cur)
+			return n;
+		n++;
+	}
+	return 0;
+}
+
+const char *item_str(void)
+{
+	return item_cur->node.str;
+}
+
+int item_is_selected(void)
+{
+	return (item_cur->node.selected != 0);
+}
+
+int item_is_tag(char tag)
+{
+	return (item_cur->node.tag == tag);
+}
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index cb2568a..ee0a04e 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -44,6 +44,12 @@
 	int i, x, y, key = 0, button = 0;
 	WINDOW *dialog;
 
+do_resize:
+	if (getmaxy(stdscr) < (height + 4))
+		return -ERRDISPLAYTOOSMALL;
+	if (getmaxx(stdscr) < (width + 4))
+		return -ERRDISPLAYTOOSMALL;
+
 	/* center dialog box on screen */
 	x = (COLS - width) / 2;
 	y = (LINES - height) / 2;
@@ -53,22 +59,23 @@
 	dialog = newwin(height, width, y, x);
 	keypad(dialog, TRUE);
 
-	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-	wattrset(dialog, border_attr);
+	draw_box(dialog, 0, 0, height, width,
+		 dlg.dialog.atr, dlg.border.atr);
+	wattrset(dialog, dlg.border.atr);
 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
 	for (i = 0; i < width - 2; i++)
 		waddch(dialog, ACS_HLINE);
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	waddch(dialog, ACS_RTEE);
 
 	print_title(dialog, title, width);
 
-	wattrset(dialog, dialog_attr);
+	wattrset(dialog, dlg.dialog.atr);
 	print_autowrap(dialog, prompt, width - 2, 1, 3);
 
 	print_buttons(dialog, height, width, 0);
 
-	while (key != ESC) {
+	while (key != KEY_ESC) {
 		key = wgetch(dialog);
 		switch (key) {
 		case 'Y':
@@ -92,11 +99,16 @@
 		case '\n':
 			delwin(dialog);
 			return button;
-		case ESC:
+		case KEY_ESC:
+			key = on_key_esc(dialog);
 			break;
+		case KEY_RESIZE:
+			delwin(dialog);
+			on_key_resize();
+			goto do_resize;
 		}
 	}
 
 	delwin(dialog);
-	return -1;		/* ESC pressed */
+	return key;		/* ESC pressed */
 }
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 7f97319..08a4c7a 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -24,6 +24,7 @@
 
 #define LKC_DIRECT_LINK
 #include "lkc.h"
+#include "lxdialog/dialog.h"
 
 static char menu_backtitle[128];
 static const char mconf_readme[] = N_(
@@ -159,7 +160,21 @@
 "\n"
 "Note that this mode can eventually be a little more CPU expensive\n"
 "(especially with a larger number of unrolled categories) than the\n"
-"default mode.\n"),
+"default mode.\n"
+"\n"
+"Different color themes available\n"
+"--------------------------------\n"
+"It is possible to select different color themes using the variable\n"
+"MENUCONFIG_COLOR. To select a theme use:\n"
+"\n"
+"make MENUCONFIG_COLOR=<theme> menuconfig\n"
+"\n"
+"Available themes are\n"
+" mono       => selects colors suitable for monochrome displays\n"
+" blackbg    => selects a color scheme with black background\n"
+" classic    => theme with blue background. The classic look\n"
+" bluetitle  => a LCD friendly version of classic. (default)\n"
+"\n"),
 menu_instructions[] = N_(
 	"Arrow keys navigate the menu.  "
 	"<Enter> selects submenus --->.  "
@@ -256,16 +271,12 @@
 	"          USB$ => find all CONFIG_ symbols ending with USB\n"
 	"\n");
 
-static char buf[4096], *bufptr = buf;
-static char input_buf[4096];
 static char filename[PATH_MAX+1] = ".config";
-static char *args[1024], **argptr = args;
 static int indent;
 static struct termios ios_org;
 static int rows = 0, cols = 0;
 static struct menu *current_menu;
 static int child_count;
-static int do_resize;
 static int single_menu_mode;
 
 static void conf(struct menu *menu);
@@ -276,12 +287,6 @@
 static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
-static void show_file(const char *filename, const char *title, int r, int c);
-
-static void cprint_init(void);
-static int cprint1(const char *fmt, ...);
-static void cprint_done(void);
-static int cprint(const char *fmt, ...);
 
 static void init_wsize(void)
 {
@@ -318,54 +323,6 @@
 	cols -= 5;
 }
 
-static void cprint_init(void)
-{
-	bufptr = buf;
-	argptr = args;
-	memset(args, 0, sizeof(args));
-	indent = 0;
-	child_count = 0;
-	cprint("./scripts/kconfig/lxdialog/lxdialog");
-	cprint("--backtitle");
-	cprint(menu_backtitle);
-}
-
-static int cprint1(const char *fmt, ...)
-{
-	va_list ap;
-	int res;
-
-	if (!*argptr)
-		*argptr = bufptr;
-	va_start(ap, fmt);
-	res = vsprintf(bufptr, fmt, ap);
-	va_end(ap);
-	bufptr += res;
-
-	return res;
-}
-
-static void cprint_done(void)
-{
-	*bufptr++ = 0;
-	argptr++;
-}
-
-static int cprint(const char *fmt, ...)
-{
-	va_list ap;
-	int res;
-
-	*argptr++ = bufptr;
-	va_start(ap, fmt);
-	res = vsprintf(bufptr, fmt, ap);
-	va_end(ap);
-	bufptr += res;
-	*bufptr++ = 0;
-
-	return res;
-}
-
 static void get_prompt_str(struct gstr *r, struct property *prop)
 {
 	int i, j;
@@ -438,108 +395,17 @@
 	return res;
 }
 
-pid_t pid;
-
-static void winch_handler(int sig)
-{
-	if (!do_resize) {
-		kill(pid, SIGINT);
-		do_resize = 1;
-	}
-}
-
-static int exec_conf(void)
-{
-	int pipefd[2], stat, size;
-	struct sigaction sa;
-	sigset_t sset, osset;
-
-	sigemptyset(&sset);
-	sigaddset(&sset, SIGINT);
-	sigprocmask(SIG_BLOCK, &sset, &osset);
-
-	signal(SIGINT, SIG_DFL);
-
-	sa.sa_handler = winch_handler;
-	sigemptyset(&sa.sa_mask);
-	sa.sa_flags = SA_RESTART;
-	sigaction(SIGWINCH, &sa, NULL);
-
-	*argptr++ = NULL;
-
-	pipe(pipefd);
-	pid = fork();
-	if (pid == 0) {
-		sigprocmask(SIG_SETMASK, &osset, NULL);
-		dup2(pipefd[1], 2);
-		close(pipefd[0]);
-		close(pipefd[1]);
-		execv(args[0], args);
-		_exit(EXIT_FAILURE);
-	}
-
-	close(pipefd[1]);
-	bufptr = input_buf;
-	while (1) {
-		size = input_buf + sizeof(input_buf) - bufptr;
-		size = read(pipefd[0], bufptr, size);
-		if (size <= 0) {
-			if (size < 0) {
-				if (errno == EINTR || errno == EAGAIN)
-					continue;
-				perror("read");
-			}
-			break;
-		}
-		bufptr += size;
-	}
-	*bufptr++ = 0;
-	close(pipefd[0]);
-	waitpid(pid, &stat, 0);
-
-	if (do_resize) {
-		init_wsize();
-		do_resize = 0;
-		sigprocmask(SIG_SETMASK, &osset, NULL);
-		return -1;
-	}
-	if (WIFSIGNALED(stat)) {
-		printf("\finterrupted(%d)\n", WTERMSIG(stat));
-		exit(1);
-	}
-#if 0
-	printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
-	sleep(1);
-#endif
-	sigpending(&sset);
-	if (sigismember(&sset, SIGINT)) {
-		printf("\finterrupted\n");
-		exit(1);
-	}
-	sigprocmask(SIG_SETMASK, &osset, NULL);
-
-	return WEXITSTATUS(stat);
-}
-
 static void search_conf(void)
 {
 	struct symbol **sym_arr;
-	int stat;
 	struct gstr res;
-
+	int dres;
 again:
-	cprint_init();
-	cprint("--title");
-	cprint(_("Search Configuration Parameter"));
-	cprint("--inputbox");
-	cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
-	cprint("10");
-	cprint("75");
-	cprint("");
-	stat = exec_conf();
-	if (stat < 0)
-		goto again;
-	switch (stat) {
+	dialog_clear();
+	dres = dialog_inputbox(_("Search Configuration Parameter"),
+			      _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
+			      10, 75, "");
+	switch (dres) {
 	case 0:
 		break;
 	case 1:
@@ -549,7 +415,7 @@
 		return;
 	}
 
-	sym_arr = sym_re_search(input_buf);
+	sym_arr = sym_re_search(dialog_input_result);
 	res = get_relations_str(sym_arr);
 	free(sym_arr);
 	show_textbox(_("Search Results"), str_get(&res), 0, 0);
@@ -576,24 +442,24 @@
 			switch (prop->type) {
 			case P_MENU:
 				child_count++;
-				cprint("m%p", menu);
-
 				if (single_menu_mode) {
-					cprint1("%s%*c%s",
-						menu->data ? "-->" : "++>",
-						indent + 1, ' ', prompt);
+					item_make("%s%*c%s",
+						  menu->data ? "-->" : "++>",
+						  indent + 1, ' ', prompt);
 				} else
-					cprint1("   %*c%s  --->", indent + 1, ' ', prompt);
+					item_make("   %*c%s  --->", indent + 1, ' ', prompt);
 
-				cprint_done();
+				item_set_tag('m');
+				item_set_data(menu);
 				if (single_menu_mode && menu->data)
 					goto conf_childs;
 				return;
 			default:
 				if (prompt) {
 					child_count++;
-					cprint(":%p", menu);
-					cprint("---%*c%s", indent + 1, ' ', prompt);
+					item_make("---%*c%s", indent + 1, ' ', prompt);
+					item_set_tag(':');
+					item_set_data(menu);
 				}
 			}
 		} else
@@ -614,10 +480,9 @@
 
 		val = sym_get_tristate_value(sym);
 		if (sym_is_changable(sym)) {
-			cprint("t%p", menu);
 			switch (type) {
 			case S_BOOLEAN:
-				cprint1("[%c]", val == no ? ' ' : '*');
+				item_make("[%c]", val == no ? ' ' : '*');
 				break;
 			case S_TRISTATE:
 				switch (val) {
@@ -625,84 +490,87 @@
 				case mod: ch = 'M'; break;
 				default:  ch = ' '; break;
 				}
-				cprint1("<%c>", ch);
+				item_make("<%c>", ch);
 				break;
 			}
+			item_set_tag('t');
+			item_set_data(menu);
 		} else {
-			cprint("%c%p", def_menu ? 't' : ':', menu);
-			cprint1("   ");
+			item_make("   ");
+			item_set_tag(def_menu ? 't' : ':');
+			item_set_data(menu);
 		}
 
-		cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+		item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
 		if (val == yes) {
 			if (def_menu) {
-				cprint1(" (%s)", menu_get_prompt(def_menu));
-				cprint1("  --->");
-				cprint_done();
+				item_add_str(" (%s)", menu_get_prompt(def_menu));
+				item_add_str("  --->");
 				if (def_menu->list) {
 					indent += 2;
 					build_conf(def_menu);
 					indent -= 2;
 				}
-			} else
-				cprint_done();
+			}
 			return;
 		}
-		cprint_done();
 	} else {
 		if (menu == current_menu) {
-			cprint(":%p", menu);
-			cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+			item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+			item_set_tag(':');
+			item_set_data(menu);
 			goto conf_childs;
 		}
 		child_count++;
 		val = sym_get_tristate_value(sym);
 		if (sym_is_choice_value(sym) && val == yes) {
-			cprint(":%p", menu);
-			cprint1("   ");
+			item_make("   ");
+			item_set_tag(':');
+			item_set_data(menu);
 		} else {
 			switch (type) {
 			case S_BOOLEAN:
-				cprint("t%p", menu);
 				if (sym_is_changable(sym))
-					cprint1("[%c]", val == no ? ' ' : '*');
+					item_make("[%c]", val == no ? ' ' : '*');
 				else
-					cprint1("---");
+					item_make("---");
+				item_set_tag('t');
+				item_set_data(menu);
 				break;
 			case S_TRISTATE:
-				cprint("t%p", menu);
 				switch (val) {
 				case yes: ch = '*'; break;
 				case mod: ch = 'M'; break;
 				default:  ch = ' '; break;
 				}
 				if (sym_is_changable(sym))
-					cprint1("<%c>", ch);
+					item_make("<%c>", ch);
 				else
-					cprint1("---");
+					item_make("---");
+				item_set_tag('t');
+				item_set_data(menu);
 				break;
 			default:
-				cprint("s%p", menu);
-				tmp = cprint1("(%s)", sym_get_string_value(sym));
+				tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
+				item_make("(%s)", sym_get_string_value(sym));
 				tmp = indent - tmp + 4;
 				if (tmp < 0)
 					tmp = 0;
-				cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
-					(sym_has_value(sym) || !sym_is_changable(sym)) ?
-					"" : " (NEW)");
-				cprint_done();
+				item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
+					     (sym_has_value(sym) || !sym_is_changable(sym)) ?
+					     "" : " (NEW)");
+				item_set_tag('s');
+				item_set_data(menu);
 				goto conf_childs;
 			}
 		}
-		cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
-			(sym_has_value(sym) || !sym_is_changable(sym)) ?
-			"" : " (NEW)");
+		item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
+			  (sym_has_value(sym) || !sym_is_changable(sym)) ?
+			  "" : " (NEW)");
 		if (menu->prompt->type == P_MENU) {
-			cprint1("  --->");
-			cprint_done();
+			item_add_str("  --->");
 			return;
 		}
-		cprint_done();
 	}
 
 conf_childs:
@@ -717,59 +585,45 @@
 	struct menu *submenu;
 	const char *prompt = menu_get_prompt(menu);
 	struct symbol *sym;
-	char active_entry[40];
-	int stat, type, i;
+	struct menu *active_menu = NULL;
+	int res;
+	int s_scroll = 0;
 
-	unlink("lxdialog.scrltmp");
-	active_entry[0] = 0;
 	while (1) {
-		cprint_init();
-		cprint("--title");
-		cprint("%s", prompt ? prompt : _("Main Menu"));
-		cprint("--menu");
-		cprint(_(menu_instructions));
-		cprint("%d", rows);
-		cprint("%d", cols);
-		cprint("%d", rows - 10);
-		cprint("%s", active_entry);
+		item_reset();
 		current_menu = menu;
 		build_conf(menu);
 		if (!child_count)
 			break;
 		if (menu == &rootmenu) {
-			cprint(":");
-			cprint("--- ");
-			cprint("L");
-			cprint(_("    Load an Alternate Configuration File"));
-			cprint("S");
-			cprint(_("    Save Configuration to an Alternate File"));
+			item_make("--- ");
+			item_set_tag(':');
+			item_make(_("    Load an Alternate Configuration File"));
+			item_set_tag('L');
+			item_make(_("    Save an Alternate Configuration File"));
+			item_set_tag('S');
 		}
-		stat = exec_conf();
-		if (stat < 0)
-			continue;
-
-		if (stat == 1 || stat == 255)
+		dialog_clear();
+		res = dialog_menu(prompt ? prompt : _("Main Menu"),
+				  _(menu_instructions),
+				  active_menu, &s_scroll);
+		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
 			break;
-
-		type = input_buf[0];
-		if (!type)
+		if (!item_activate_selected())
+			continue;
+		if (!item_tag())
 			continue;
 
-		for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
-			;
-		if (i >= sizeof(active_entry))
-			i = sizeof(active_entry) - 1;
-		input_buf[i] = 0;
-		strcpy(active_entry, input_buf);
-
-		sym = NULL;
-		submenu = NULL;
-		if (sscanf(input_buf + 1, "%p", &submenu) == 1)
+		submenu = item_data();
+		active_menu = item_data();
+		if (submenu)
 			sym = submenu->sym;
+		else
+			sym = NULL;
 
-		switch (stat) {
+		switch (res) {
 		case 0:
-			switch (type) {
+			switch (item_tag()) {
 			case 'm':
 				if (single_menu_mode)
 					submenu->data = (void *) (long) !submenu->data;
@@ -800,7 +654,7 @@
 				show_helptext("README", _(mconf_readme));
 			break;
 		case 3:
-			if (type == 't') {
+			if (item_is_tag('t')) {
 				if (sym_set_tristate_value(sym, yes))
 					break;
 				if (sym_set_tristate_value(sym, mod))
@@ -808,17 +662,17 @@
 			}
 			break;
 		case 4:
-			if (type == 't')
+			if (item_is_tag('t'))
 				sym_set_tristate_value(sym, no);
 			break;
 		case 5:
-			if (type == 't')
+			if (item_is_tag('t'))
 				sym_set_tristate_value(sym, mod);
 			break;
 		case 6:
-			if (type == 't')
+			if (item_is_tag('t'))
 				sym_toggle_tristate_value(sym);
-			else if (type == 'm')
+			else if (item_is_tag('m'))
 				conf(submenu);
 			break;
 		case 7:
@@ -830,13 +684,8 @@
 
 static void show_textbox(const char *title, const char *text, int r, int c)
 {
-	int fd;
-
-	fd = creat(".help.tmp", 0777);
-	write(fd, text, strlen(text));
-	close(fd);
-	show_file(".help.tmp", title, r, c);
-	unlink(".help.tmp");
+	dialog_clear();
+	dialog_textbox(title, text, r, c);
 }
 
 static void show_helptext(const char *title, const char *text)
@@ -864,68 +713,52 @@
 	str_free(&help);
 }
 
-static void show_file(const char *filename, const char *title, int r, int c)
-{
-	do {
-		cprint_init();
-		if (title) {
-			cprint("--title");
-			cprint("%s", title);
-		}
-		cprint("--textbox");
-		cprint("%s", filename);
-		cprint("%d", r ? r : rows);
-		cprint("%d", c ? c : cols);
-	} while (exec_conf() < 0);
-}
-
 static void conf_choice(struct menu *menu)
 {
 	const char *prompt = menu_get_prompt(menu);
 	struct menu *child;
 	struct symbol *active;
-	int stat;
 
 	active = sym_get_choice_value(menu->sym);
 	while (1) {
-		cprint_init();
-		cprint("--title");
-		cprint("%s", prompt ? prompt : _("Main Menu"));
-		cprint("--radiolist");
-		cprint(_(radiolist_instructions));
-		cprint("15");
-		cprint("70");
-		cprint("6");
+		int res;
+		int selected;
+		item_reset();
 
 		current_menu = menu;
 		for (child = menu->list; child; child = child->next) {
 			if (!menu_is_visible(child))
 				continue;
-			cprint("%p", child);
-			cprint("%s", menu_get_prompt(child));
+			item_make("%s", menu_get_prompt(child));
+			item_set_data(child);
+			if (child->sym == active)
+				item_set_selected(1);
 			if (child->sym == sym_get_choice_value(menu->sym))
-				cprint("ON");
-			else if (child->sym == active)
-				cprint("SELECTED");
-			else
-				cprint("OFF");
+				item_set_tag('X');
 		}
-
-		stat = exec_conf();
-		switch (stat) {
+		dialog_clear();
+		res = dialog_checklist(prompt ? prompt : _("Main Menu"),
+					_(radiolist_instructions),
+					 15, 70, 6);
+		selected = item_activate_selected();
+		switch (res) {
 		case 0:
-			if (sscanf(input_buf, "%p", &child) != 1)
-				break;
-			sym_set_tristate_value(child->sym, yes);
+			if (selected) {
+				child = item_data();
+				sym_set_tristate_value(child->sym, yes);
+			}
 			return;
 		case 1:
-			if (sscanf(input_buf, "%p", &child) == 1) {
+			if (selected) {
+				child = item_data();
 				show_help(child);
 				active = child->sym;
 			} else
 				show_help(menu);
 			break;
-		case 255:
+		case KEY_ESC:
+			return;
+		case -ERRDISPLAYTOOSMALL:
 			return;
 		}
 	}
@@ -934,40 +767,38 @@
 static void conf_string(struct menu *menu)
 {
 	const char *prompt = menu_get_prompt(menu);
-	int stat;
 
 	while (1) {
-		cprint_init();
-		cprint("--title");
-		cprint("%s", prompt ? prompt : _("Main Menu"));
-		cprint("--inputbox");
+		int res;
+		char *heading;
+
 		switch (sym_get_type(menu->sym)) {
 		case S_INT:
-			cprint(_(inputbox_instructions_int));
+			heading = _(inputbox_instructions_int);
 			break;
 		case S_HEX:
-			cprint(_(inputbox_instructions_hex));
+			heading = _(inputbox_instructions_hex);
 			break;
 		case S_STRING:
-			cprint(_(inputbox_instructions_string));
+			heading = _(inputbox_instructions_string);
 			break;
 		default:
-			/* panic? */;
+			heading = "Internal mconf error!";
 		}
-		cprint("10");
-		cprint("75");
-		cprint("%s", sym_get_string_value(menu->sym));
-		stat = exec_conf();
-		switch (stat) {
+		dialog_clear();
+		res = dialog_inputbox(prompt ? prompt : _("Main Menu"),
+				      heading, 10, 75,
+				      sym_get_string_value(menu->sym));
+		switch (res) {
 		case 0:
-			if (sym_set_string_value(menu->sym, input_buf))
+			if (sym_set_string_value(menu->sym, dialog_input_result))
 				return;
 			show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
 			break;
 		case 1:
 			show_help(menu);
 			break;
-		case 255:
+		case KEY_ESC:
 			return;
 		}
 	}
@@ -975,28 +806,24 @@
 
 static void conf_load(void)
 {
-	int stat;
 
 	while (1) {
-		cprint_init();
-		cprint("--inputbox");
-		cprint(load_config_text);
-		cprint("11");
-		cprint("55");
-		cprint("%s", filename);
-		stat = exec_conf();
-		switch(stat) {
+		int res;
+		dialog_clear();
+		res = dialog_inputbox(NULL, load_config_text,
+				      11, 55, filename);
+		switch(res) {
 		case 0:
-			if (!input_buf[0])
+			if (!dialog_input_result[0])
 				return;
-			if (!conf_read(input_buf))
+			if (!conf_read(dialog_input_result))
 				return;
 			show_textbox(NULL, _("File does not exist!"), 5, 38);
 			break;
 		case 1:
 			show_helptext(_("Load Alternate Configuration"), load_config_help);
 			break;
-		case 255:
+		case KEY_ESC:
 			return;
 		}
 	}
@@ -1004,28 +831,23 @@
 
 static void conf_save(void)
 {
-	int stat;
-
 	while (1) {
-		cprint_init();
-		cprint("--inputbox");
-		cprint(save_config_text);
-		cprint("11");
-		cprint("55");
-		cprint("%s", filename);
-		stat = exec_conf();
-		switch(stat) {
+		int res;
+		dialog_clear();
+		res = dialog_inputbox(NULL, save_config_text,
+				      11, 55, filename);
+		switch(res) {
 		case 0:
-			if (!input_buf[0])
+			if (!dialog_input_result[0])
 				return;
-			if (!conf_write(input_buf))
+			if (!conf_write(dialog_input_result))
 				return;
 			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
 			break;
 		case 1:
 			show_helptext(_("Save Alternate Configuration"), save_config_help);
 			break;
-		case 255:
+		case KEY_ESC:
 			return;
 		}
 	}
@@ -1034,15 +856,13 @@
 static void conf_cleanup(void)
 {
 	tcsetattr(1, TCSAFLUSH, &ios_org);
-	unlink(".help.tmp");
-	unlink("lxdialog.scrltmp");
 }
 
 int main(int ac, char **av)
 {
 	struct symbol *sym;
 	char *mode;
-	int stat;
+	int res;
 
 	setlocale(LC_ALL, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1065,18 +885,19 @@
 	tcgetattr(1, &ios_org);
 	atexit(conf_cleanup);
 	init_wsize();
-	conf(&rootmenu);
-
+	reset_dialog();
+	init_dialog(menu_backtitle);
 	do {
-		cprint_init();
-		cprint("--yesno");
-		cprint(_("Do you wish to save your new kernel configuration?"));
-		cprint("5");
-		cprint("60");
-		stat = exec_conf();
-	} while (stat < 0);
-
-	if (stat == 0) {
+		conf(&rootmenu);
+		dialog_clear();
+		res = dialog_yesno(NULL,
+				   _("Do you wish to save your "
+				     "new kernel configuration?\n"
+				     "<ESC><ESC> to continue."),
+				   6, 60);
+	} while (res == KEY_ESC);
+	end_dialog();
+	if (res == 0) {
 		if (conf_write(NULL)) {
 			fprintf(stderr, _("\n\n"
 				"Error during writing of the kernel configuration.\n"
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index c9ca0c2..00d1ad1 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -57,8 +57,8 @@
 #	other functions are ignored.
 #
 #  -nofunction funcname
-#	If set, then only generate documentation for the other function(s).  All
-#	other functions are ignored. Cannot be used with -function together
+#	If set, then only generate documentation for the other function(s).
+#	Cannot be used together with -function
 #	(yes, that's a bug -- perl hackers can fix it 8))
 #
 #  c files - list of 'c' files to process
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index 293dbd6..23b5104 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -112,7 +112,7 @@
 	  your distribution will provide these and enable the new controls
 	  in the kernel they also distribute.
 
-	  Note that this option can be overriden at boot with the
+	  Note that this option can be overridden at boot with the
 	  selinux_compat_net parameter, and after boot via
 	  /selinux/compat_net.  See Documentation/kernel-parameters.txt
 	  for details on this parameter.
@@ -122,7 +122,7 @@
 	  well as any conntrack helpers for protocols which you
 	  wish to control.
 
-	  If you are unsure what do do here, select N.
+	  If you are unsure what to do here, select N.
 
 config SECURITY_SELINUX_POLICYDB_VERSION_MAX
 	bool "NSA SELinux maximum supported policy format version"
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index 3ebc349..a444bfe 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -96,11 +96,11 @@
 {
 	snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA v" CONFIG_SND_VERSION " emulation code)\n");
 	snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n",
-		    system_utsname.sysname,
-		    system_utsname.nodename,
-		    system_utsname.release,
-		    system_utsname.version,
-		    system_utsname.machine);
+		    init_utsname()->sysname,
+		    init_utsname()->nodename,
+		    init_utsname()->release,
+		    init_utsname()->version,
+		    init_utsname()->machine);
 	snd_iprintf(buffer, "Config options: 0\n");
 	snd_iprintf(buffer, "\nInstalled drivers: \n");
 	snd_iprintf(buffer, "Type 10: ALSA emulation\n");
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 97e38b6..cc2b9ab 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -115,10 +115,6 @@
 	  Say Y or M if you have an SGI Indy or Indigo2 system and want to be able to
 	  use its on-board A2 audio system.
 
-config SOUND_IT8172
-	tristate "IT8172G Sound"
-	depends on SOUND_PRIME && (MIPS_ITE8172 || MIPS_IVR)
-
 config SOUND_VRC5477
 	tristate "NEC Vrc5477 AC97 sound"
 	depends on SOUND_PRIME && DDB5477
@@ -647,7 +643,7 @@
 	  command line.
 
 config PSS_MIXER
-	bool "Enable PSS mixer (Beethoven ADSP-16 and other compatibile)"
+	bool "Enable PSS mixer (Beethoven ADSP-16 and other compatible)"
 	depends on SOUND_PSS
 	help
 	  Answer Y for Beethoven ADSP-16. You may try to say Y also for other
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 9bf3ee5..2489bd6 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -15,72 +15,42 @@
 obj-$(CONFIG_SOUND_AEDSP16)	+= aedsp16.o
 obj-$(CONFIG_SOUND_PSS)		+= pss.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_TRIX)	+= trix.o ad1848.o sb_lib.o uart401.o
-obj-$(CONFIG_SOUND_OPL3SA1)	+= opl3sa.o ad1848.o uart401.o
 obj-$(CONFIG_SOUND_SSCAPE)	+= sscape.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_MAD16)	+= mad16.o ad1848.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_CS4232)	+= cs4232.o uart401.o
 obj-$(CONFIG_SOUND_MSS)		+= ad1848.o
 obj-$(CONFIG_SOUND_OPL3SA2)	+= opl3sa2.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_PAS)		+= pas2.o sb.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_SB)		+= sb.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_KAHLUA)	+= kahlua.o
-obj-$(CONFIG_SOUND_WAVEFRONT)	+= wavefront.o
-obj-$(CONFIG_SOUND_MAUI)	+= maui.o mpu401.o
 obj-$(CONFIG_SOUND_MPU401)	+= mpu401.o
 obj-$(CONFIG_SOUND_UART6850)	+= uart6850.o
-obj-$(CONFIG_SOUND_GUS)		+= gus.o ad1848.o
 obj-$(CONFIG_SOUND_ADLIB)	+= adlib_card.o opl3.o
 obj-$(CONFIG_SOUND_YM3812)	+= opl3.o
 obj-$(CONFIG_SOUND_VMIDI)	+= v_midi.o
 obj-$(CONFIG_SOUND_VIDC)	+= vidc_mod.o
 obj-$(CONFIG_SOUND_WAVEARTIST)	+= waveartist.o
-obj-$(CONFIG_SOUND_SGALAXY)	+= sgalaxy.o ad1848.o
 obj-$(CONFIG_SOUND_AD1816)	+= ad1816.o
 obj-$(CONFIG_SOUND_AD1889)	+= ad1889.o ac97_codec.o
 obj-$(CONFIG_SOUND_ACI_MIXER)	+= aci.o
-obj-$(CONFIG_SOUND_AWE32_SYNTH)	+= awe_wave.o
 
 obj-$(CONFIG_SOUND_VIA82CXXX)	+= via82cxxx_audio.o ac97_codec.o
 ifeq ($(CONFIG_MIDI_VIA82CXXX),y)
   obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o
 endif
-obj-$(CONFIG_SOUND_YMFPCI)	+= ymfpci.o ac97_codec.o
-ifeq ($(CONFIG_SOUND_YMFPCI_LEGACY),y)
-  obj-$(CONFIG_SOUND_YMFPCI)    += opl3.o uart401.o
-endif
 obj-$(CONFIG_SOUND_MSNDCLAS)	+= msnd.o msnd_classic.o
 obj-$(CONFIG_SOUND_MSNDPIN)	+= msnd.o msnd_pinnacle.o
 obj-$(CONFIG_SOUND_VWSND)	+= vwsnd.o
 obj-$(CONFIG_SOUND_NM256)	+= nm256_audio.o ac97.o
 obj-$(CONFIG_SOUND_ICH)		+= i810_audio.o ac97_codec.o
-obj-$(CONFIG_SOUND_SONICVIBES)	+= sonicvibes.o
-obj-$(CONFIG_SOUND_CMPCI)	+= cmpci.o
-ifeq ($(CONFIG_SOUND_CMPCI_FM),y)
-  obj-$(CONFIG_SOUND_CMPCI)     += sound.o opl3.o
-endif
-ifeq ($(CONFIG_SOUND_CMPCI_MIDI),y)
-  obj-$(CONFIG_SOUND_CMPCI)     += sound.o mpu401.o
-endif
-obj-$(CONFIG_SOUND_ES1370)	+= es1370.o
 obj-$(CONFIG_SOUND_ES1371)	+= es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_VRC5477)	+= nec_vrc5477.o ac97_codec.o
-obj-$(CONFIG_SOUND_AU1000)	+= au1000.o ac97_codec.o
 obj-$(CONFIG_SOUND_AU1550_AC97)	+= au1550_ac97.o ac97_codec.o
-obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
-obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
-obj-$(CONFIG_SOUND_MAESTRO3)	+= maestro3.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
-obj-$(CONFIG_SOUND_HARMONY)	+= harmony.o
 obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
 obj-$(CONFIG_SOUND_BCM_CS4297A)	+= swarm_cs4297a.o
-obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
 obj-$(CONFIG_SOUND_BT878)	+= btaudio.o
-obj-$(CONFIG_SOUND_ALI5455)	+= ali5455.o ac97_codec.o
-obj-$(CONFIG_SOUND_IT8172)	+= ite8172.o ac97_codec.o
-obj-$(CONFIG_SOUND_FORTE)	+= forte.o ac97_codec.o
 
-obj-$(CONFIG_SOUND_AD1980)	+= ac97_plugin_ad1980.o ac97_codec.o
 obj-$(CONFIG_SOUND_WM97XX)	+= ac97_plugin_wm97xx.o
 
 ifeq ($(CONFIG_MIDI_EMU10K1),y)
@@ -88,28 +58,25 @@
 endif
 
 obj-$(CONFIG_SOUND_EMU10K1)	+= emu10k1/
-obj-$(CONFIG_SOUND_CS4281)	+= cs4281/
 obj-$(CONFIG_DMASOUND)		+= dmasound/
 
 # Declare multi-part drivers.
 
 sound-objs	:= 							\
-    dev_table.o soundcard.o sound_syms.o		\
-    audio.o audio_syms.o dmabuf.o					\
-    midi_syms.o midi_synth.o midibuf.o					\
-    sequencer.o sequencer_syms.o sound_timer.o sys_timer.o
+    dev_table.o soundcard.o 		\
+    audio.o dmabuf.o					\
+    midi_synth.o midibuf.o					\
+    sequencer.o sound_timer.o sys_timer.o
 
-gus-objs	:= gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
 pas2-objs	:= pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
 sb-objs		:= sb_card.o
 sb_lib-objs	:= sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
 vidc_mod-objs	:= vidc.o vidc_fill.o
-wavefront-objs  := wavfront.o wf_midi.o yss225.o
 
 hostprogs-y	:= bin2hex hex2hex
 
 # Files generated that shall be removed upon make clean
-clean-files := maui_boot.h msndperm.c msndinit.c pndsperm.c pndspini.c \
+clean-files := msndperm.c msndinit.c pndsperm.c pndspini.c \
                pss_boot.h trix_boot.h
 
 # Firmware files that need translation
@@ -119,21 +86,6 @@
 # will be forced to be remade.
 #
 
-# Turtle Beach Maui / Tropez
-
-$(obj)/maui.o: $(obj)/maui_boot.h
-
-ifeq ($(CONFIG_MAUI_HAVE_BOOT),y)
-    $(obj)/maui_boot.h: $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE)) $(obj)/bin2hex
-	$(obj)/bin2hex -i maui_os < $< > $@
-else
-    $(obj)/maui_boot.h:
-	(							\
-	    echo 'static unsigned char * maui_os = NULL;';	\
-	    echo 'static int maui_osLen = 0;';			\
-	) > $@
-endif
-
 # Turtle Beach MultiSound
 
 ifeq ($(CONFIG_MSNDCLAS_HAVE_BOOT),y)
diff --git a/sound/oss/ac97.c b/sound/oss/ac97.c
index 3ba6d91..72cf4ed 100644
--- a/sound/oss/ac97.c
+++ b/sound/oss/ac97.c
@@ -112,25 +112,6 @@
     return 0;
 }
 
-/* Reset the mixer to the currently saved settings.  */
-int
-ac97_reset (struct ac97_hwint *dev)
-{
-    int x;
-
-    if (dev->reset_device (dev))
-	return -1;
-
-    /* Now set the registers back to their last-written values. */
-    for (x = 0; mixerRegs[x].ac97_regnum != -1; x++) {
-	int regnum = mixerRegs[x].ac97_regnum;
-	int value = dev->last_written_mixer_values [regnum / 2];
-	if (value >= 0)
-	    ac97_put_register (dev, regnum, value);
-    }
-    return 0;
-}
-
 /* Return the contents of register REG; use the cache if the value in it
    is valid.  Returns a negative error code on failure. */
 static int
@@ -441,7 +422,6 @@
 EXPORT_SYMBOL(ac97_set_values);
 EXPORT_SYMBOL(ac97_put_register);
 EXPORT_SYMBOL(ac97_mixer_ioctl);
-EXPORT_SYMBOL(ac97_reset);
 MODULE_LICENSE("GPL");
 
 
diff --git a/sound/oss/ac97.h b/sound/oss/ac97.h
index 77d454e..01837a9 100644
--- a/sound/oss/ac97.h
+++ b/sound/oss/ac97.h
@@ -192,9 +192,6 @@
 extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd,
 			     void __user * arg);
 
-/* Do a complete reset on the AC97 mixer, restoring all mixer registers to
-   the current values.  Normally used after an APM resume event.  */
-extern int ac97_reset (struct ac97_hwint *dev);
 #endif
 
 /*
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index 972327c..602db49 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -1399,95 +1399,6 @@
 
 EXPORT_SYMBOL(ac97_set_adc_rate);
 
-int ac97_save_state(struct ac97_codec *codec)
-{
-	return 0;	
-}
-
-EXPORT_SYMBOL(ac97_save_state);
-
-int ac97_restore_state(struct ac97_codec *codec)
-{
-	int i;
-	unsigned int left, right, val;
-
-	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-		if (!supported_mixer(codec, i)) 
-			continue;
-
-		val = codec->mixer_state[i];
-		right = val >> 8;
-		left = val  & 0xff;
-		codec->write_mixer(codec, i, left, right);
-	}
-	return 0;
-}
-
-EXPORT_SYMBOL(ac97_restore_state);
-
-/**
- *	ac97_register_driver	-	register a codec helper
- *	@driver: Driver handler
- *
- *	Register a handler for codecs matching the codec id. The handler
- *	attach function is called for all present codecs and will be 
- *	called when new codecs are discovered.
- */
- 
-int ac97_register_driver(struct ac97_driver *driver)
-{
-	struct list_head *l;
-	struct ac97_codec *c;
-	
-	mutex_lock(&codec_mutex);
-	INIT_LIST_HEAD(&driver->list);
-	list_add(&driver->list, &codec_drivers);
-	
-	list_for_each(l, &codecs)
-	{
-		c = list_entry(l, struct ac97_codec, list);
-		if(c->driver != NULL || ((c->model ^ driver->codec_id) & driver->codec_mask))
-			continue;
-		if(driver->probe(c, driver))
-			continue;
-		c->driver = driver;
-	}
-	mutex_unlock(&codec_mutex);
-	return 0;
-}
-
-EXPORT_SYMBOL_GPL(ac97_register_driver);
-
-/**
- *	ac97_unregister_driver	-	unregister a codec helper
- *	@driver: Driver handler
- *
- *	Unregister a handler for codecs matching the codec id. The handler
- *	remove function is called for all matching codecs.
- */
- 
-void ac97_unregister_driver(struct ac97_driver *driver)
-{
-	struct list_head *l;
-	struct ac97_codec *c;
-	
-	mutex_lock(&codec_mutex);
-	list_del_init(&driver->list);
-
-	list_for_each(l, &codecs)
-	{
-		c = list_entry(l, struct ac97_codec, list);
-		if (c->driver == driver) {
-			driver->remove(c, driver);
-			c->driver = NULL;
-		}
-	}
-	
-	mutex_unlock(&codec_mutex);
-}
-
-EXPORT_SYMBOL_GPL(ac97_unregister_driver);
-
 static int swap_headphone(int remove_master)
 {
 	struct list_head *l;
diff --git a/sound/oss/ac97_plugin_ad1980.c b/sound/oss/ac97_plugin_ad1980.c
deleted file mode 100644
index 24a9acd..0000000
--- a/sound/oss/ac97_plugin_ad1980.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-    ac97_plugin_ad1980.c  Copyright (C) 2003 Red Hat, Inc. All rights reserved.
-
-   The contents of this file are subject to the Open Software License version 1.1
-   that can be found at http://www.opensource.org/licenses/osl-1.1.txt and is 
-   included herein by reference. 
-   
-   Alternatively, the contents of this file may be used under the
-   terms of the GNU General Public License version 2 (the "GPL") as 
-   distributed in the kernel source COPYING file, in which
-   case the provisions of the GPL are applicable instead of the
-   above.  If you wish to allow the use of your version of this file
-   only under the terms of the GPL and not to allow others to use
-   your version of this file under the OSL, indicate your decision
-   by deleting the provisions above and replace them with the notice
-   and other provisions required by the GPL.  If you do not delete
-   the provisions above, a recipient may use your version of this
-   file under either the OSL or the GPL.
-   
-   Authors: 	Alan Cox <alan@redhat.com>
-
-   This is an example codec plugin. This one switches the connections
-   around to match the setups some vendors use with audio switched to
-   non standard front connectors not the normal rear ones
-
-   This code primarily exists to demonstrate how to use the codec
-   interface
-
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/ac97_codec.h>
-
-/**
- *	ad1980_remove		-	codec remove callback
- *	@codec: The codec that is being removed
- *
- *	This callback occurs when an AC97 codec is being removed. A
- *	codec remove call will not occur for a codec during that codec
- *	probe callback.
- *
- *	Most drivers will need to lock their remove versus their 
- *	use of the codec after the probe function.
- */
- 
-static void __devexit ad1980_remove(struct ac97_codec *codec, struct ac97_driver *driver)
-{
-	/* Nothing to do in the simple example */
-}
-
-
-/**
- *	ad1980_probe		-	codec found callback
- *	@codec: ac97 codec matching the idents
- *	@driver: ac97_driver it matched
- *
- *	This entry point is called when a codec is found which matches
- *	the driver. At the point it is called the codec is basically
- *	operational, mixer operations have been initialised and can
- *	be overriden. Called in process context. The field driver_private
- *	is available for the driver to use to store stuff.
- *
- *	The caller can claim the device by returning zero, or return
- *	a negative error code. 
- */
- 
-static int ad1980_probe(struct ac97_codec *codec, struct ac97_driver *driver)
-{
-	u16 control;
-
-#define AC97_AD_MISC	0x76
-
-	/* Switch the inputs/outputs over (from Dell code) */
-	control = codec->codec_read(codec, AC97_AD_MISC);
-	codec->codec_write(codec, AC97_AD_MISC, control | 0x4420);
-	
-	/* We could refuse the device since we dont need to hang around,
-	   but we will claim it */
-	return 0;
-}
-	
- 
-static struct ac97_driver ad1980_driver = {
-	.codec_id	= 0x41445370,
-	.codec_mask	= 0xFFFFFFFF,
-	.name		= "AD1980 example",
-	.probe		= ad1980_probe,
-	.remove		= __devexit_p(ad1980_remove),
-};
-
-/**
- *	ad1980_exit		-	module exit path
- *
- *	Our module is being unloaded. At this point unregister_driver
- *	will call back our remove handler for any existing codecs. You
- *	may not unregister_driver from interrupt context or from a 
- *	probe/remove callback.
- */
-
-static void ad1980_exit(void)
-{
-	ac97_unregister_driver(&ad1980_driver);
-}
-
-/**
- *	ad1980_init		-	set up ad1980 handlers
- *
- *	After we call the register function it will call our probe
- *	function for each existing matching device before returning to us.
- *	Any devices appearing afterwards whose id's match the codec_id
- *	will also cause the probe function to be called.
- *	You may not register_driver from interrupt context or from a 
- *	probe/remove callback.
- */
- 
-static int ad1980_init(void)
-{
-	return ac97_register_driver(&ad1980_driver);
-}
-
-module_init(ad1980_init);
-module_exit(ad1980_exit);
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 3b45e11..257b753 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -1,5 +1,5 @@
 /*
- * sound/ad1848.c
+ * sound/oss/ad1848.c
  *
  * The low level driver for the AD1848/CS4248 codec chip which
  * is used for example in the MS Sound System.
@@ -195,6 +195,7 @@
 static void     ad1848_halt_input(int dev);
 static void     ad1848_halt_output(int dev);
 static void     ad1848_trigger(int dev, int bits);
+static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy);
 
 #ifndef EXCLUDE_TIMERS
 static int ad1848_tmr_install(int dev);
@@ -2195,7 +2196,7 @@
 		printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
 }
 
-irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
 	unsigned char status;
 	ad1848_info *devc;
@@ -2802,7 +2803,6 @@
 EXPORT_SYMBOL(ad1848_init);
 EXPORT_SYMBOL(ad1848_unload);
 EXPORT_SYMBOL(ad1848_control);
-EXPORT_SYMBOL(adintr);
 EXPORT_SYMBOL(probe_ms_sound);
 EXPORT_SYMBOL(attach_ms_sound);
 EXPORT_SYMBOL(unload_ms_sound);
diff --git a/sound/oss/ad1848.h b/sound/oss/ad1848.h
index d0573b0..b95ebe2 100644
--- a/sound/oss/ad1848.h
+++ b/sound/oss/ad1848.h
@@ -18,7 +18,6 @@
 int ad1848_detect (struct resource *ports, int *flags, int *osp);
 int ad1848_control(int cmd, int arg);
 
-irqreturn_t adintr(int irq, void *dev_id, struct pt_regs * dummy);
 void attach_ms_sound(struct address_info * hw_config, struct resource *ports, struct module * owner);
 
 int probe_ms_sound(struct address_info *hw_config, struct resource *ports);
diff --git a/sound/oss/ad1848_mixer.h b/sound/oss/ad1848_mixer.h
index f9231c6..2cf719b 100644
--- a/sound/oss/ad1848_mixer.h
+++ b/sound/oss/ad1848_mixer.h
@@ -1,5 +1,5 @@
 /*
- * sound/ad1848_mixer.h
+ * sound/oss/ad1848_mixer.h
  *
  * Definitions for the mixer of AD1848 and compatible codecs.
  */
diff --git a/sound/oss/adlib_card.c b/sound/oss/adlib_card.c
index 6414ceb..c9a7c9b 100644
--- a/sound/oss/adlib_card.c
+++ b/sound/oss/adlib_card.c
@@ -1,5 +1,5 @@
 /*
- * sound/adlib_card.c
+ * sound/oss/adlib_card.c
  *
  * Detection routine for the AdLib card.
  *
diff --git a/sound/oss/ali5455.c b/sound/oss/ali5455.c
deleted file mode 100644
index 70dcd70..0000000
--- a/sound/oss/ali5455.c
+++ /dev/null
@@ -1,3735 +0,0 @@
-/*
- *	ALI  ali5455 and friends ICH driver for Linux
- *	LEI HU <Lei_Hu@ali.com.tw>
- *
- *  Built from:
- *	drivers/sound/i810_audio
- *
- *  	The ALi 5455 is similar but not quite identical to the Intel ICH
- *	series of controllers. Its easier to keep the driver separated from
- *	the i810 driver.
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	This program is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *	GNU General Public License for more details.
- *
- *	You should have received a copy of the GNU General Public License
- *	along with this program; if not, write to the Free Software
- *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- *	ALi 5455 theory of operation
- *
- *	The chipset provides three DMA channels that talk to an AC97
- *	CODEC (AC97 is a digital/analog mixer standard). At its simplest
- *	you get 48Khz audio with basic volume and mixer controls. At the
- *	best you get rate adaption in the codec. We set the card up so
- *	that we never take completion interrupts but instead keep the card
- *	chasing its tail around a ring buffer. This is needed for mmap
- *	mode audio and happens to work rather well for non-mmap modes too.
- *
- *	The board has one output channel for PCM audio (supported) and
- *	a stereo line in and mono microphone input. Again these are normally
- *	locked to 48Khz only. Right now recording is not finished.
- *
- *	There is no midi support, no synth support. Use timidity. To get
- *	esd working you need to use esd -r 48000 as it won't probe 48KHz
- *	by default. mpg123 can't handle 48Khz only audio so use xmms.
- *
- *	If you need to force a specific rate set the clocking= option
- *
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-
-#ifndef PCI_DEVICE_ID_ALI_5455
-#define PCI_DEVICE_ID_ALI_5455	0x5455
-#endif
-
-#ifndef PCI_VENDOR_ID_ALI
-#define PCI_VENDOR_ID_ALI	0x10b9
-#endif
-
-static int strict_clocking = 0;
-static unsigned int clocking = 0;
-static unsigned int codec_pcmout_share_spdif_locked = 0;
-static unsigned int codec_independent_spdif_locked = 0;
-static unsigned int controller_pcmout_share_spdif_locked = 0;
-static unsigned int controller_independent_spdif_locked = 0;
-static unsigned int globel = 0;
-
-#define ADC_RUNNING	1
-#define DAC_RUNNING	2
-#define CODEC_SPDIFOUT_RUNNING 8
-#define CONTROLLER_SPDIFOUT_RUNNING 4
-
-#define SPDIF_ENABLE_OUTPUT	4	/* bits 0,1 are PCM */
-
-#define ALI5455_FMT_16BIT	1
-#define ALI5455_FMT_STEREO	2
-#define ALI5455_FMT_MASK	3
-
-#define SPDIF_ON	0x0004
-#define SURR_ON		0x0010
-#define CENTER_LFE_ON	0x0020
-#define VOL_MUTED	0x8000
-
-
-#define ALI_SPDIF_OUT_CH_STATUS 0xbf
-/* the 810's array of pointers to data buffers */
-
-struct sg_item {
-#define BUSADDR_MASK	0xFFFFFFFE
-	u32 busaddr;
-#define CON_IOC 	0x80000000	/* interrupt on completion */
-#define CON_BUFPAD	0x40000000	/* pad underrun with last sample, else 0 */
-#define CON_BUFLEN_MASK	0x0000ffff	/* buffer length in samples */
-	u32 control;
-};
-
-/* an instance of the ali channel */
-#define SG_LEN 32
-struct ali_channel {
-	/* these sg guys should probably be allocated
-	   separately as nocache. Must be 8 byte aligned */
-	struct sg_item sg[SG_LEN];	/* 32*8 */
-	u32 offset;		/* 4 */
-	u32 port;		/* 4 */
-	u32 used;
-	u32 num;
-};
-
-/*
- * we have 3 separate dma engines.  pcm in, pcm out, and mic.
- * each dma engine has controlling registers.  These goofy
- * names are from the datasheet, but make it easy to write
- * code while leafing through it.
- */
-
-#define ENUM_ENGINE(PRE,DIG) 									\
-enum {												\
-	PRE##_BDBAR =	0x##DIG##0,		/* Buffer Descriptor list Base Address */	\
-	PRE##_CIV =	0x##DIG##4,		/* Current Index Value */			\
-	PRE##_LVI =	0x##DIG##5,		/* Last Valid Index */				\
-	PRE##_SR =	0x##DIG##6,		/* Status Register */				\
-	PRE##_PICB =	0x##DIG##8,		/* Position In Current Buffer */		\
-	PRE##_CR =	0x##DIG##b		/* Control Register */				\
-}
-
-ENUM_ENGINE(OFF, 0);		/* Offsets */
-ENUM_ENGINE(PI, 4);		/* PCM In */
-ENUM_ENGINE(PO, 5);		/* PCM Out */
-ENUM_ENGINE(MC, 6);		/* Mic In */
-ENUM_ENGINE(CODECSPDIFOUT, 7);	/* CODEC SPDIF OUT  */
-ENUM_ENGINE(CONTROLLERSPDIFIN, A);	/* CONTROLLER SPDIF In */
-ENUM_ENGINE(CONTROLLERSPDIFOUT, B);	/* CONTROLLER SPDIF OUT */
-
-
-enum {
-	ALI_SCR = 0x00,		/* System Control Register */
-	ALI_SSR = 0x04,		/* System Status Register  */
-	ALI_DMACR = 0x08,	/* DMA Control Register    */
-	ALI_FIFOCR1 = 0x0c,	/* FIFO Control Register 1  */
-	ALI_INTERFACECR = 0x10,	/* Interface Control Register */
-	ALI_INTERRUPTCR = 0x14,	/* Interrupt control Register */
-	ALI_INTERRUPTSR = 0x18,	/* Interrupt  Status Register */
-	ALI_FIFOCR2 = 0x1c,	/* FIFO Control Register 2   */
-	ALI_CPR = 0x20,		/* Command Port Register     */
-	ALI_SPR = 0x24,		/* Status Port Register      */
-	ALI_FIFOCR3 = 0x2c,	/* FIFO Control Register 3  */
-	ALI_TTSR = 0x30,	/* Transmit Tag Slot Register */
-	ALI_RTSR = 0x34,	/* Receive Tag Slot  Register */
-	ALI_CSPSR = 0x38,	/* Command/Status Port Status Register */
-	ALI_CAS = 0x3c,		/* Codec Write Semaphore Register */
-	ALI_SPDIFCSR = 0xf8,	/* spdif channel status register  */
-	ALI_SPDIFICS = 0xfc	/* spdif interface control/status  */
-};
-
-// x-status register(x:pcm in ,pcm out, mic in,)
-/* interrupts for a dma engine */
-#define DMA_INT_FIFO		(1<<4)	/* fifo under/over flow */
-#define DMA_INT_COMPLETE	(1<<3)	/* buffer read/write complete and ioc set */
-#define DMA_INT_LVI		(1<<2)	/* last valid done */
-#define DMA_INT_CELV		(1<<1)	/* last valid is current */
-#define DMA_INT_DCH		(1)	/* DMA Controller Halted (happens on LVI interrupts) */	//not eqult intel
-#define DMA_INT_MASK (DMA_INT_FIFO|DMA_INT_COMPLETE|DMA_INT_LVI)
-
-/* interrupts for the whole chip */// by interrupt status register finish
-
-#define INT_SPDIFOUT   (1<<23)	/* controller spdif out INTERRUPT */
-#define INT_SPDIFIN   (1<<22)
-#define INT_CODECSPDIFOUT   (1<<19)
-#define INT_MICIN   (1<<18)
-#define INT_PCMOUT   (1<<17)
-#define INT_PCMIN   (1<<16)
-#define INT_CPRAIS   (1<<7)
-#define INT_SPRAIS   (1<<5)
-#define INT_GPIO    (1<<1)
-#define INT_MASK   (INT_SPDIFOUT|INT_CODECSPDIFOUT|INT_MICIN|INT_PCMOUT|INT_PCMIN)
-
-#define DRIVER_VERSION "0.02ac"
-
-/* magic numbers to protect our data structures */
-#define ALI5455_CARD_MAGIC		0x5072696E	/* "Prin" */
-#define ALI5455_STATE_MAGIC		0x63657373	/* "cess" */
-#define ALI5455_DMA_MASK		0xffffffff	/* DMA buffer mask for pci_alloc_consist */
-#define NR_HW_CH			5	//I think 5 channel
-
-/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
-#define NR_AC97		2
-
-/* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */
-/* stream at a minimum for this card to be happy */
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-/* Samples are 16bit values, so we are shifting to a word, not to a byte, hence shift */
-/* values are one less than might be expected */
-static const unsigned sample_shift[] = { -1, 0, 0, 1 };
-
-#define ALI5455
-static char *card_names[] = {
-	"ALI 5455"
-};
-
-static struct pci_device_id ali_pci_tbl[] = {
-	{PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5455,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI5455},
-	{0,}
-};
-
-MODULE_DEVICE_TABLE(pci, ali_pci_tbl);
-
-#ifdef CONFIG_PM
-#define PM_SUSPENDED(card) (card->pm_suspended)
-#else
-#define PM_SUSPENDED(card) (0)
-#endif
-
-/* "software" or virtual channel, an instance of opened /dev/dsp */
-struct ali_state {
-	unsigned int magic;
-	struct ali_card *card;	/* Card info */
-
-	/* single open lock mechanism, only used for recording */
-	struct mutex open_mutex;
-	wait_queue_head_t open_wait;
-
-	/* file mode */
-	mode_t open_mode;
-
-	/* virtual channel number */
-	int virt;
-
-#ifdef CONFIG_PM
-	unsigned int pm_saved_dac_rate, pm_saved_adc_rate;
-#endif
-	struct dmabuf {
-		/* wave sample stuff */
-		unsigned int rate;
-		unsigned char fmt, enable, trigger;
-
-		/* hardware channel */
-		struct ali_channel *read_channel;
-		struct ali_channel *write_channel;
-		struct ali_channel *codec_spdifout_channel;
-		struct ali_channel *controller_spdifout_channel;
-
-		/* OSS buffer management stuff */
-		void *rawbuf;
-		dma_addr_t dma_handle;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-
-		/* our buffer acts like a circular ring */
-		unsigned hwptr;	/* where dma last started, updated by update_ptr */
-		unsigned swptr;	/* where driver last clear/filled, updated by read/write */
-		int count;	/* bytes to be consumed or been generated by dma machine */
-		unsigned total_bytes;	/* total bytes dmaed by hardware */
-
-		unsigned error;	/* number of over/underruns */
-		wait_queue_head_t wait;	/* put process on wait queue when no more space in buffer */
-
-		/* redundant, but makes calculations easier */
-		/* what the hardware uses */
-		unsigned dmasize;
-		unsigned fragsize;
-		unsigned fragsamples;
-
-		/* what we tell the user to expect */
-		unsigned userfrags;
-		unsigned userfragsize;
-
-		/* OSS stuff */
-		unsigned mapped:1;
-		unsigned ready:1;
-		unsigned update_flag;
-		unsigned ossfragsize;
-		unsigned ossmaxfrags;
-		unsigned subdivision;
-	} dmabuf;
-};
-
-
-struct ali_card {
-	struct ali_channel channel[5];
-	unsigned int magic;
-
-	/* We keep ali5455 cards in a linked list */
-	struct ali_card *next;
-
-	/* The ali has a certain amount of cross channel interaction
-	   so we use a single per card lock */
-	spinlock_t lock;
-	spinlock_t ac97_lock;
-
-	/* PCI device stuff */
-	struct pci_dev *pci_dev;
-	u16 pci_id;
-#ifdef CONFIG_PM
-	u16 pm_suspended;
-	int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97];
-#endif
-	/* soundcore stuff */
-	int dev_audio;
-
-	/* structures for abstraction of hardware facilities, codecs, banks and channels */
-	struct ac97_codec *ac97_codec[NR_AC97];
-	struct ali_state *states[NR_HW_CH];
-
-	u16 ac97_features;
-	u16 ac97_status;
-	u16 channels;
-
-	/* hardware resources */
-	unsigned long iobase;
-
-	u32 irq;
-
-	/* Function support */
-	struct ali_channel *(*alloc_pcm_channel) (struct ali_card *);
-	struct ali_channel *(*alloc_rec_pcm_channel) (struct ali_card *);
-	struct ali_channel *(*alloc_rec_mic_channel) (struct ali_card *);
-	struct ali_channel *(*alloc_codec_spdifout_channel) (struct ali_card *);
-	struct ali_channel *(*alloc_controller_spdifout_channel) (struct  ali_card *);
-	void (*free_pcm_channel) (struct ali_card *, int chan);
-
-	/* We have a *very* long init time possibly, so use this to block */
-	/* attempts to open our devices before we are ready (stops oops'es) */
-	int initializing;
-};
-
-
-static struct ali_card *devs = NULL;
-
-static int ali_open_mixdev(struct inode *inode, struct file *file);
-static int ali_ioctl_mixdev(struct inode *inode, struct file *file,
-			    unsigned int cmd, unsigned long arg);
-static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg);
-static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data);
-
-static struct ali_channel *ali_alloc_pcm_channel(struct ali_card *card)
-{
-	if (card->channel[1].used == 1)
-		return NULL;
-	card->channel[1].used = 1;
-	return &card->channel[1];
-}
-
-static struct ali_channel *ali_alloc_rec_pcm_channel(struct ali_card *card)
-{
-	if (card->channel[0].used == 1)
-		return NULL;
-	card->channel[0].used = 1;
-	return &card->channel[0];
-}
-
-static struct ali_channel *ali_alloc_rec_mic_channel(struct ali_card *card)
-{
-	if (card->channel[2].used == 1)
-		return NULL;
-	card->channel[2].used = 1;
-	return &card->channel[2];
-}
-
-static struct ali_channel *ali_alloc_codec_spdifout_channel(struct ali_card *card)
-{
-	if (card->channel[3].used == 1)
-		return NULL;
-	card->channel[3].used = 1;
-	return &card->channel[3];
-}
-
-static struct ali_channel *ali_alloc_controller_spdifout_channel(struct ali_card *card)
-{
-	if (card->channel[4].used == 1)
-		return NULL;
-	card->channel[4].used = 1;
-	return &card->channel[4];
-}
-static void ali_free_pcm_channel(struct ali_card *card, int channel)
-{
-	card->channel[channel].used = 0;
-}
-
-
-//add support  codec spdif out 
-static int ali_valid_spdif_rate(struct ac97_codec *codec, int rate)
-{
-	unsigned long id = 0L;
-
-	id = (ali_ac97_get(codec, AC97_VENDOR_ID1) << 16);
-	id |= ali_ac97_get(codec, AC97_VENDOR_ID2) & 0xffff;
-	switch (id) {
-	case 0x41445361:	/* AD1886 */
-		if (rate == 48000) {
-			return 1;
-		}
-		break;
-	case 0x414c4720:	/* ALC650 */
-		if (rate == 48000) {
-			return 1;
-		}
-		break;
-	default:		/* all other codecs, until we know otherwiae */
-		if (rate == 48000 || rate == 44100 || rate == 32000) {
-			return 1;
-		}
-		break;
-	}
-	return (0);
-}
-
-/* ali_set_spdif_output
- * 
- *  Configure the S/PDIF output transmitter. When we turn on
- *  S/PDIF, we turn off the analog output. This may not be
- *  the right thing to do.
- *
- *  Assumptions:
- *     The DSP sample rate must already be set to a supported
- *     S/PDIF rate (32kHz, 44.1kHz, or 48kHz) or we abort.
- */
-static void ali_set_spdif_output(struct ali_state *state, int slots,
-				 int rate)
-{
-	int vol;
-	int aud_reg;
-	struct ac97_codec *codec = state->card->ac97_codec[0];
-
-	if (!(state->card->ac97_features & 4)) {
-		state->card->ac97_status &= ~SPDIF_ON;
-	} else {
-		if (slots == -1) {	/* Turn off S/PDIF */
-			aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-			ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-
-			/* If the volume wasn't muted before we turned on S/PDIF, unmute it */
-			if (!(state->card->ac97_status & VOL_MUTED)) {
-				aud_reg = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO);
-				ali_ac97_set(codec, AC97_MASTER_VOL_STEREO,
-					     (aud_reg & ~VOL_MUTED));
-			}
-			state->card->ac97_status &= ~(VOL_MUTED | SPDIF_ON);
-			return;
-		}
-
-		vol = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO);
-		state->card->ac97_status = vol & VOL_MUTED;
-
-		/* Set S/PDIF transmitter sample rate */
-		aud_reg = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-		switch (rate) {
-		case 32000:
-			aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K;
-			break;
-		case 44100:
-			aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K;
-			break;
-		case 48000:
-			aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K;
-			break;
-		default:
-			/* turn off S/PDIF */
-			aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-			ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-			state->card->ac97_status &= ~SPDIF_ON;
-			return;
-		}
-
-		ali_ac97_set(codec, AC97_SPDIF_CONTROL, aud_reg);
-
-		aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-		aud_reg = (aud_reg & AC97_EA_SLOT_MASK) | slots | AC97_EA_SPDIF;
-		ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
-
-		aud_reg = ali_ac97_get(codec, AC97_POWER_CONTROL);
-		aud_reg |= 0x0002;
-		ali_ac97_set(codec, AC97_POWER_CONTROL, aud_reg);
-		udelay(1);
-
-		state->card->ac97_status |= SPDIF_ON;
-
-		/* Check to make sure the configuration is valid */
-		aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-		if (!(aud_reg & 0x0400)) {
-			/* turn off S/PDIF */
-			ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-			state->card->ac97_status &= ~SPDIF_ON;
-			return;
-		}
-		if (codec_independent_spdif_locked > 0) {
-			aud_reg = ali_ac97_get(codec, 0x6a);
-			ali_ac97_set(codec, 0x6a, (aud_reg & 0xefff));
-		}
-		/* Mute the analog output */
-		/* Should this only mute the PCM volume??? */
-	}
-}
-
-/* ali_set_dac_channels
- *
- *  Configure the codec's multi-channel DACs
- *
- *  The logic is backwards. Setting the bit to 1 turns off the DAC. 
- *
- *  What about the ICH? We currently configure it using the
- *  SNDCTL_DSP_CHANNELS ioctl.  If we're turnning on the DAC, 
- *  does that imply that we want the ICH set to support
- *  these channels?
- *  
- *  TODO:
- *    vailidate that the codec really supports these DACs
- *    before turning them on. 
- */
-static void ali_set_dac_channels(struct ali_state *state, int channel)
-{
-	int aud_reg;
-	struct ac97_codec *codec = state->card->ac97_codec[0];
-
-	aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-	aud_reg |= AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK;
-	state->card->ac97_status &= ~(SURR_ON | CENTER_LFE_ON);
-
-	switch (channel) {
-	case 2:		/* always enabled */
-		break;
-	case 4:
-		aud_reg &= ~AC97_EA_PRJ;
-		state->card->ac97_status |= SURR_ON;
-		break;
-	case 6:
-		aud_reg &= ~(AC97_EA_PRJ | AC97_EA_PRI | AC97_EA_PRK);
-		state->card->ac97_status |= SURR_ON | CENTER_LFE_ON;
-		break;
-	default:
-		break;
-	}
-	ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
-
-}
-
-/* set playback sample rate */
-static unsigned int ali_set_dac_rate(struct ali_state *state,
-				     unsigned int rate)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	u32 new_rate;
-	struct ac97_codec *codec = state->card->ac97_codec[0];
-
-	if (!(state->card->ac97_features & 0x0001)) {
-		dmabuf->rate = clocking;
-		return clocking;
-	}
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 8000)
-		rate = 8000;
-	dmabuf->rate = rate;
-
-	/*
-	 *      Adjust for misclocked crap
-	 */
-
-	rate = (rate * clocking) / 48000;
-
-	if (strict_clocking && rate < 8000) {
-		rate = 8000;
-		dmabuf->rate = (rate * 48000) / clocking;
-	}
-
-	new_rate = ac97_set_dac_rate(codec, rate);
-	if (new_rate != rate) {
-		dmabuf->rate = (new_rate * 48000) / clocking;
-	}
-	rate = new_rate;
-	return dmabuf->rate;
-}
-
-/* set recording sample rate */
-static unsigned int ali_set_adc_rate(struct ali_state *state,
-				     unsigned int rate)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	u32 new_rate;
-	struct ac97_codec *codec = state->card->ac97_codec[0];
-
-	if (!(state->card->ac97_features & 0x0001)) {
-		dmabuf->rate = clocking;
-		return clocking;
-	}
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 8000)
-		rate = 8000;
-	dmabuf->rate = rate;
-
-	/*
-	 *      Adjust for misclocked crap
-	 */
-
-	rate = (rate * clocking) / 48000;
-	if (strict_clocking && rate < 8000) {
-		rate = 8000;
-		dmabuf->rate = (rate * 48000) / clocking;
-	}
-
-	new_rate = ac97_set_adc_rate(codec, rate);
-
-	if (new_rate != rate) {
-		dmabuf->rate = (new_rate * 48000) / clocking;
-		rate = new_rate;
-	}
-	return dmabuf->rate;
-}
-
-/* set codec independent spdifout sample rate */
-static unsigned int ali_set_codecspdifout_rate(struct ali_state *state,
-					       unsigned int rate)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-
-	if (!(state->card->ac97_features & 0x0001)) {
-		dmabuf->rate = clocking;
-		return clocking;
-	}
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 8000)
-		rate = 8000;
-	dmabuf->rate = rate;
-
-	return dmabuf->rate;
-}
-
-/* set  controller independent spdif out function sample rate */
-static void ali_set_spdifout_rate(struct ali_state *state,
-				  unsigned int rate)
-{
-	unsigned char ch_st_sel;
-	unsigned short status_rate;
-
-	switch (rate) {
-	case 44100:
-		status_rate = 0;
-		break;
-	case 32000:
-		status_rate = 0x300;
-		break;
-	case 48000:
-	default:
-		status_rate = 0x200;
-		break;
-	}
-
-	ch_st_sel = inb(state->card->iobase + ALI_SPDIFICS) & ALI_SPDIF_OUT_CH_STATUS;	//select spdif_out
-
-	ch_st_sel |= 0x80;	//select right
-	outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS));
-	outb(status_rate | 0x20, (state->card->iobase + ALI_SPDIFCSR + 2));
-
-	ch_st_sel &= (~0x80);	//select left
-	outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS));
-	outw(status_rate | 0x10, (state->card->iobase + ALI_SPDIFCSR + 2));
-}
-
-/* get current playback/recording dma buffer pointer (byte offset from LBA),
-   called with spinlock held! */
-
-static inline unsigned ali_get_dma_addr(struct ali_state *state, int rec)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned int civ, offset, port, port_picb;
-	unsigned int data;
-
-	if (!dmabuf->enable)
-		return 0;
-
-	if (rec == 1)
-		port = state->card->iobase + dmabuf->read_channel->port;
-	else if (rec == 2)
-		port = state->card->iobase + dmabuf->codec_spdifout_channel->port;
-	else if (rec == 3)
-		port = state->card->iobase + dmabuf->controller_spdifout_channel->port;
-	else
-		port = state->card->iobase + dmabuf->write_channel->port;
-
-	port_picb = port + OFF_PICB;
-
-	do {
-		civ = inb(port + OFF_CIV) & 31;
-		offset = inw(port_picb);
-		/* Must have a delay here! */
-		if (offset == 0)
-			udelay(1);
-
-		/* Reread both registers and make sure that that total
-		 * offset from the first reading to the second is 0.
-		 * There is an issue with SiS hardware where it will count
-		 * picb down to 0, then update civ to the next value,
-		 * then set the new picb to fragsize bytes.  We can catch
-		 * it between the civ update and the picb update, making
-		 * it look as though we are 1 fragsize ahead of where we
-		 * are.  The next to we get the address though, it will
-		 * be back in thdelay is more than long enough
-		 * that we won't have to worry about the chip still being
-		 * out of sync with reality ;-)
-		 */
-	} while (civ != (inb(port + OFF_CIV) & 31) || offset != inw(port_picb));
-
-	data = ((civ + 1) * dmabuf->fragsize - (2 * offset)) % dmabuf->dmasize;
-	if (inw(port_picb) == 0)
-		data -= 2048;
-
-	return data;
-}
-
-/* Stop recording (lock held) */
-static inline void __stop_adc(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	struct ali_card *card = state->card;
-
-	dmabuf->enable &= ~ADC_RUNNING;
-
-	outl((1 << 18) | (1 << 16), card->iobase + ALI_DMACR);
-	udelay(1);
-
-	outb(0, card->iobase + PI_CR);
-	while (inb(card->iobase + PI_CR) != 0);
-
-	// now clear any latent interrupt bits (like the halt bit)
-	outb(inb(card->iobase + PI_SR) | 0x001e, card->iobase + PI_SR);
-	outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMIN, card->iobase + ALI_INTERRUPTSR);
-}
-
-static void stop_adc(struct ali_state *state)
-{
-	struct ali_card *card = state->card;
-	unsigned long flags;
-	spin_lock_irqsave(&card->lock, flags);
-	__stop_adc(state);
-	spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_adc(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-
-	if (dmabuf->count < dmabuf->dmasize && dmabuf->ready
-	    && !dmabuf->enable && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-		dmabuf->enable |= ADC_RUNNING;
-		outb((1 << 4) | (1 << 2), state->card->iobase + PI_CR);
-		if (state->card->channel[0].used == 1)
-			outl(1, state->card->iobase + ALI_DMACR);	// DMA CONTROL REGISTRER
-		udelay(100);
-		if (state->card->channel[2].used == 1)
-			outl((1 << 2), state->card->iobase + ALI_DMACR);	//DMA CONTROL REGISTER
-		udelay(100);
-	}
-}
-
-static void start_adc(struct ali_state *state)
-{
-	struct ali_card *card = state->card;
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->lock, flags);
-	__start_adc(state);
-	spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* stop playback (lock held) */
-static inline void __stop_dac(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	struct ali_card *card = state->card;
-
-	dmabuf->enable &= ~DAC_RUNNING;
-	outl(0x00020000, card->iobase + 0x08);
-	outb(0, card->iobase + PO_CR);
-	while (inb(card->iobase + PO_CR) != 0)
-		cpu_relax();
-
-	outb(inb(card->iobase + PO_SR) | 0x001e, card->iobase + PO_SR);
-
-	outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMOUT, card->iobase + ALI_INTERRUPTSR);
-}
-
-static void stop_dac(struct ali_state *state)
-{
-	struct ali_card *card = state->card;
-	unsigned long flags;
-	spin_lock_irqsave(&card->lock, flags);
-	__stop_dac(state);
-	spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_dac(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
-	    (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-		dmabuf->enable |= DAC_RUNNING;
-		outb((1 << 4) | (1 << 2), state->card->iobase + PO_CR);
-		outl((1 << 1), state->card->iobase + 0x08);	//dma control register
-	}
-}
-
-static void start_dac(struct ali_state *state)
-{
-	struct ali_card *card = state->card;
-	unsigned long flags;
-	spin_lock_irqsave(&card->lock, flags);
-	__start_dac(state);
-	spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* stop codec and controller spdif out  (lock held) */
-static inline void __stop_spdifout(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	struct ali_card *card = state->card;
-
-	if (codec_independent_spdif_locked > 0) {
-		dmabuf->enable &= ~CODEC_SPDIFOUT_RUNNING;
-		outl((1 << 19), card->iobase + 0x08);
-		outb(0, card->iobase + CODECSPDIFOUT_CR);
-
-		while (inb(card->iobase + CODECSPDIFOUT_CR) != 0)
-			cpu_relax();
-
-		outb(inb(card->iobase + CODECSPDIFOUT_SR) | 0x001e, card->iobase + CODECSPDIFOUT_SR);
-		outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_CODECSPDIFOUT, card->iobase + ALI_INTERRUPTSR);
-	} else {
-		if (controller_independent_spdif_locked > 0) {
-			dmabuf->enable &= ~CONTROLLER_SPDIFOUT_RUNNING;
-			outl((1 << 23), card->iobase + 0x08);
-			outb(0, card->iobase + CONTROLLERSPDIFOUT_CR);
-			while (inb(card->iobase + CONTROLLERSPDIFOUT_CR) != 0)
-				cpu_relax();
-			outb(inb(card->iobase + CONTROLLERSPDIFOUT_SR) | 0x001e, card->iobase + CONTROLLERSPDIFOUT_SR);
-			outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_SPDIFOUT, card->iobase + ALI_INTERRUPTSR);
-		}
-	}
-}
-
-static void stop_spdifout(struct ali_state *state)
-{
-	struct ali_card *card = state->card;
-	unsigned long flags;
-	spin_lock_irqsave(&card->lock, flags);
-	__stop_spdifout(state);
-	spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_spdifout(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
-	    (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-		if (codec_independent_spdif_locked > 0) {
-			dmabuf->enable |= CODEC_SPDIFOUT_RUNNING;
-			outb((1 << 4) | (1 << 2), state->card->iobase + CODECSPDIFOUT_CR);
-			outl((1 << 3), state->card->iobase + 0x08);	//dma control register
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				dmabuf->enable |= CONTROLLER_SPDIFOUT_RUNNING;
-				outb((1 << 4) | (1 << 2), state->card->iobase + CONTROLLERSPDIFOUT_CR);
-				outl((1 << 7), state->card->iobase + 0x08);	//dma control register
-			}
-		}
-	}
-}
-
-static void start_spdifout(struct ali_state *state)
-{
-	struct ali_card *card = state->card;
-	unsigned long flags;
-	spin_lock_irqsave(&card->lock, flags);
-	__start_spdifout(state);
-	spin_unlock_irqrestore(&card->lock, flags);
-}
-
-#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-/* allocate DMA buffer, playback , recording,spdif out  buffer should be allocated separately */
-static int alloc_dmabuf(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	void *rawbuf = NULL;
-	int order, size;
-	struct page *page, *pend;
-
-	/* If we don't have any oss frag params, then use our default ones */
-	if (dmabuf->ossmaxfrags == 0)
-		dmabuf->ossmaxfrags = 4;
-	if (dmabuf->ossfragsize == 0)
-		dmabuf->ossfragsize = (PAGE_SIZE << DMABUF_DEFAULTORDER) / dmabuf->ossmaxfrags;
-	size = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
-
-	if (dmabuf->rawbuf && (PAGE_SIZE << dmabuf->buforder) == size)
-		return 0;
-	/* alloc enough to satisfy the oss params */
-	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
-		if ((PAGE_SIZE << order) > size)
-			continue;
-		if ((rawbuf = pci_alloc_consistent(state->card->pci_dev,
-						   PAGE_SIZE << order,
-						   &dmabuf->dma_handle)))
-			break;
-	}
-	if (!rawbuf)
-		return -ENOMEM;
-
-	dmabuf->ready = dmabuf->mapped = 0;
-	dmabuf->rawbuf = rawbuf;
-	dmabuf->buforder = order;
-
-	/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-	pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-	for (page = virt_to_page(rawbuf); page <= pend; page++)
-		SetPageReserved(page);
-	return 0;
-}
-
-/* free DMA buffer */
-static void dealloc_dmabuf(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	struct page *page, *pend;
-
-	if (dmabuf->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
-		for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++)
-			ClearPageReserved(page);
-		pci_free_consistent(state->card->pci_dev,
-				    PAGE_SIZE << dmabuf->buforder,
-				    dmabuf->rawbuf, dmabuf->dma_handle);
-	}
-	dmabuf->rawbuf = NULL;
-	dmabuf->mapped = dmabuf->ready = 0;
-}
-
-static int prog_dmabuf(struct ali_state *state, unsigned rec)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	struct ali_channel *c = NULL;
-	struct sg_item *sg;
-	unsigned long flags;
-	int ret;
-	unsigned fragint;
-	int i;
-
-	spin_lock_irqsave(&state->card->lock, flags);
-	if (dmabuf->enable & DAC_RUNNING)
-		__stop_dac(state);
-	if (dmabuf->enable & ADC_RUNNING)
-		__stop_adc(state);
-	if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-		__stop_spdifout(state);
-	if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-		__stop_spdifout(state);
-
-	dmabuf->total_bytes = 0;
-	dmabuf->count = dmabuf->error = 0;
-	dmabuf->swptr = dmabuf->hwptr = 0;
-	spin_unlock_irqrestore(&state->card->lock, flags);
-
-	/* allocate DMA buffer, let alloc_dmabuf determine if we are already
-	 * allocated well enough or if we should replace the current buffer
-	 * (assuming one is already allocated, if it isn't, then allocate it).
-	 */
-	if ((ret = alloc_dmabuf(state)))
-		return ret;
-
-	/* FIXME: figure out all this OSS fragment stuff */
-	/* I did, it now does what it should according to the OSS API.  DL */
-	/* We may not have realloced our dmabuf, but the fragment size to
-	 * fragment number ratio may have changed, so go ahead and reprogram
-	 * things
-	 */
-
-	dmabuf->dmasize = PAGE_SIZE << dmabuf->buforder;
-	dmabuf->numfrag = SG_LEN;
-	dmabuf->fragsize = dmabuf->dmasize / dmabuf->numfrag;
-	dmabuf->fragsamples = dmabuf->fragsize >> 1;
-	dmabuf->userfragsize = dmabuf->ossfragsize;
-	dmabuf->userfrags = dmabuf->dmasize / dmabuf->ossfragsize;
-
-	memset(dmabuf->rawbuf, 0, dmabuf->dmasize);
-
-	if (dmabuf->ossmaxfrags == 4) {
-		fragint = 8;
-		dmabuf->fragshift = 2;
-	} else if (dmabuf->ossmaxfrags == 8) {
-		fragint = 4;
-		dmabuf->fragshift = 3;
-	} else if (dmabuf->ossmaxfrags == 16) {
-		fragint = 2;
-		dmabuf->fragshift = 4;
-	} else {
-		fragint = 1;
-		dmabuf->fragshift = 5;
-	}
-	/*
-	 *      Now set up the ring 
-	 */
-
-	if (rec == 1)
-		c = dmabuf->read_channel;
-	else if (rec == 2)
-		c = dmabuf->codec_spdifout_channel;
-	else if (rec == 3)
-		c = dmabuf->controller_spdifout_channel;
-	else if (rec == 0)
-		c = dmabuf->write_channel;
-	if (c != NULL) {
-		sg = &c->sg[0];
-		/*
-		 *      Load up 32 sg entries and take an interrupt at half
-		 *      way (we might want more interrupts later..) 
-		 */
-		for (i = 0; i < dmabuf->numfrag; i++) {
-			sg->busaddr =
-			    virt_to_bus(dmabuf->rawbuf +
-					dmabuf->fragsize * i);
-			// the card will always be doing 16bit stereo
-			sg->control = dmabuf->fragsamples;
-			sg->control |= CON_BUFPAD;	//I modify
-			// set us up to get IOC interrupts as often as needed to
-			// satisfy numfrag requirements, no more
-			if (((i + 1) % fragint) == 0) {
-				sg->control |= CON_IOC;
-			}
-			sg++;
-		}
-		spin_lock_irqsave(&state->card->lock, flags);
-		outb(2, state->card->iobase + c->port + OFF_CR);	/* reset DMA machine */
-		outl(virt_to_bus(&c->sg[0]), state->card->iobase + c->port + OFF_BDBAR);
-		outb(0, state->card->iobase + c->port + OFF_CIV);
-		outb(0, state->card->iobase + c->port + OFF_LVI);
-		spin_unlock_irqrestore(&state->card->lock, flags);
-	}
-	/* set the ready flag for the dma buffer */
-	dmabuf->ready = 1;
-	return 0;
-}
-
-static void __ali_update_lvi(struct ali_state *state, int rec)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	int x, port;
-	port = state->card->iobase;
-	if (rec == 1)
-		port += dmabuf->read_channel->port;
-	else if (rec == 2)
-		port += dmabuf->codec_spdifout_channel->port;
-	else if (rec == 3)
-		port += dmabuf->controller_spdifout_channel->port;
-	else if (rec == 0)
-		port += dmabuf->write_channel->port;
-	/* if we are currently stopped, then our CIV is actually set to our
-	 * *last* sg segment and we are ready to wrap to the next.  However,
-	 * if we set our LVI to the last sg segment, then it won't wrap to
-	 * the next sg segment, it won't even get a start.  So, instead, when
-	 * we are stopped, we set both the LVI value and also we increment
-	 * the CIV value to the next sg segment to be played so that when
-	 * we call start_{dac,adc}, things will operate properly
-	 */
-	if (!dmabuf->enable && dmabuf->ready) {
-		if (rec && dmabuf->count < dmabuf->dmasize && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-			outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-			__start_adc(state);
-			while (! (inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-				cpu_relax();
-		} else if (!rec && dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-			outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-			__start_dac(state);
-			while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-				cpu_relax();
-		} else if (rec && dmabuf->count && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-			if (codec_independent_spdif_locked > 0) {
-				// outb((inb(port+OFF_CIV))&31, port+OFF_LVI);
-				outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-				__start_spdifout(state);
-				while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-					cpu_relax();
-			} else {
-				if (controller_independent_spdif_locked > 0) {
-					outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-					__start_spdifout(state);
-					while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-						cpu_relax();
-				}
-			}
-		}
-	}
-
-	/* swptr - 1 is the tail of our transfer */
-	x = (dmabuf->dmasize + dmabuf->swptr - 1) % dmabuf->dmasize;
-	x /= dmabuf->fragsize;
-	outb(x, port + OFF_LVI);
-}
-
-static void ali_update_lvi(struct ali_state *state, int rec)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned long flags;
-	if (!dmabuf->ready)
-		return;
-	spin_lock_irqsave(&state->card->lock, flags);
-	__ali_update_lvi(state, rec);
-	spin_unlock_irqrestore(&state->card->lock, flags);
-}
-
-/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
-static void ali_update_ptr(struct ali_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned hwptr;
-	int diff;
-	
-	/* error handling and process wake up for DAC */
-	if (dmabuf->enable == ADC_RUNNING) {
-		/* update hardware pointer */
-		hwptr = ali_get_dma_addr(state, 1);
-		diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-		dmabuf->hwptr = hwptr;
-		dmabuf->total_bytes += diff;
-		dmabuf->count += diff;
-		if (dmabuf->count > dmabuf->dmasize) {
-			/* buffer underrun or buffer overrun */
-			/* this is normal for the end of a read */
-			/* only give an error if we went past the */
-			/* last valid sg entry */
-			if ((inb(state->card->iobase + PI_CIV) & 31) != (inb(state->card->iobase + PI_LVI) & 31)) {
-				printk(KERN_WARNING "ali_audio: DMA overrun on read\n");
-				dmabuf->error++;
-			}
-		}
-		if (dmabuf->count > dmabuf->userfragsize)
-			wake_up(&dmabuf->wait);
-	}
-	/* error handling and process wake up for DAC */
-	if (dmabuf->enable == DAC_RUNNING) {
-		/* update hardware pointer */
-		hwptr = ali_get_dma_addr(state, 0);
-		diff =
-		    (dmabuf->dmasize + hwptr -
-		     dmabuf->hwptr) % dmabuf->dmasize;
-#if defined(DEBUG_INTERRUPTS) || defined(DEBUG_MMAP)
-		printk("DAC HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff);
-#endif
-		dmabuf->hwptr = hwptr;
-		dmabuf->total_bytes += diff;
-		dmabuf->count -= diff;
-		if (dmabuf->count < 0) {
-			/* buffer underrun or buffer overrun */
-			/* this is normal for the end of a write */
-			/* only give an error if we went past the */
-			/* last valid sg entry */
-			if ((inb(state->card->iobase + PO_CIV) & 31) != (inb(state->card->iobase + PO_LVI) & 31)) {
-				printk(KERN_WARNING "ali_audio: DMA overrun on write\n");
-				printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n",
-				     			inb(state->card->iobase + PO_CIV) & 31,
-				     			inb(state->card->iobase + PO_LVI) & 31, 
-							dmabuf->hwptr,
-							dmabuf->count);
-				dmabuf->error++;
-			}
-		}
-		if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-		    	wake_up(&dmabuf->wait);
-	}
-
-	/* error handling and process wake up for CODEC SPDIF OUT */
-	if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-		/* update hardware pointer */
-		hwptr = ali_get_dma_addr(state, 2);
-		diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-		dmabuf->hwptr = hwptr;
-		dmabuf->total_bytes += diff;
-		dmabuf->count -= diff;
-		if (dmabuf->count < 0) {
-			/* buffer underrun or buffer overrun */
-			/* this is normal for the end of a write */
-			/* only give an error if we went past the */
-			/* last valid sg entry */
-			if ((inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31)) {
-				printk(KERN_WARNING "ali_audio: DMA overrun on write\n");
-				printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n", 
-				        inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31,
-					inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31,
-					dmabuf->hwptr, dmabuf->count);
-				dmabuf->error++;
-			}
-		}
-		if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-			wake_up(&dmabuf->wait);
-	}
-	/* error handling and process wake up for CONTROLLER SPDIF OUT */
-	if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-		/* update hardware pointer */
-		hwptr = ali_get_dma_addr(state, 3);
-		diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-		dmabuf->hwptr = hwptr;
-		dmabuf->total_bytes += diff;
-		dmabuf->count -= diff;
-		if (dmabuf->count < 0) {
-			/* buffer underrun or buffer overrun */
-			/* this is normal for the end of a write */
-			/* only give an error if we went past the */
-			/* last valid sg entry */
-			if ((inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31)) {
-				printk(KERN_WARNING
-				       "ali_audio: DMA overrun on write\n");
-				printk("ali_audio: CIV %d, LVI %d, hwptr %x, "
-					"count %d\n",
-				     		inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31,
-				     		inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31,
-				     		dmabuf->hwptr, dmabuf->count);
-				dmabuf->error++;
-			}
-		}
-		if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-			wake_up(&dmabuf->wait);
-	}
-}
-
-static inline int ali_get_free_write_space(struct
-					   ali_state
-					   *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	int free;
-
-	if (dmabuf->count < 0) {
-		dmabuf->count = 0;
-		dmabuf->swptr = dmabuf->hwptr;
-	}
-	free = dmabuf->dmasize - dmabuf->swptr;
-	if ((dmabuf->count + free) > dmabuf->dmasize){
-		free = dmabuf->dmasize - dmabuf->count;
-	}
-	return free;
-}
-
-static inline int ali_get_available_read_data(struct
-					      ali_state
-					      *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	int avail;
-	ali_update_ptr(state);
-	// catch overruns during record
-	if (dmabuf->count > dmabuf->dmasize) {
-		dmabuf->count = dmabuf->dmasize;
-		dmabuf->swptr = dmabuf->hwptr;
-	}
-	avail = dmabuf->count;
-	avail -= (dmabuf->hwptr % dmabuf->fragsize);
-	if (avail < 0)
-		return (0);
-	return (avail);
-}
-
-static int drain_dac(struct ali_state *state, int signals_allowed)
-{
-
-	DECLARE_WAITQUEUE(wait, current);
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned long flags;
-	unsigned long tmo;
-	int count;
-	if (!dmabuf->ready)
-		return 0;
-	if (dmabuf->mapped) {
-		stop_dac(state);
-		return 0;
-	}
-	add_wait_queue(&dmabuf->wait, &wait);
-	for (;;) {
-
-		spin_lock_irqsave(&state->card->lock, flags);
-		ali_update_ptr(state);
-		count = dmabuf->count;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-		if (count <= 0)
-			break;
-		/* 
-		 * This will make sure that our LVI is correct, that our
-		 * pointer is updated, and that the DAC is running.  We
-		 * have to force the setting of dmabuf->trigger to avoid
-		 * any possible deadlocks.
-		 */
-		if (!dmabuf->enable) {
-			dmabuf->trigger = PCM_ENABLE_OUTPUT;
-			ali_update_lvi(state, 0);
-		}
-		if (signal_pending(current) && signals_allowed) {
-			break;
-		}
-
-		/* It seems that we have to set the current state to
-		 * TASK_INTERRUPTIBLE every time to make the process
-		 * really go to sleep.  This also has to be *after* the
-		 * update_ptr() call because update_ptr is likely to
-		 * do a wake_up() which will unset this before we ever
-		 * try to sleep, resuling in a tight loop in this code
-		 * instead of actually sleeping and waiting for an
-		 * interrupt to wake us up!
-		 */
-		set_current_state(TASK_INTERRUPTIBLE);
-		/*
-		 * set the timeout to significantly longer than it *should*
-		 * take for the DAC to drain the DMA buffer
-		 */
-		tmo = (count * HZ) / (dmabuf->rate);
-		if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-			printk(KERN_ERR "ali_audio: drain_dac, dma timeout?\n");
-			count = 0;
-			break;
-		}
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&dmabuf->wait, &wait);
-	if (count > 0 && signal_pending(current) && signals_allowed)
-		return -ERESTARTSYS;
-	stop_dac(state);
-	return 0;
-}
-
-
-static int drain_spdifout(struct ali_state *state, int signals_allowed)
-{
-
-	DECLARE_WAITQUEUE(wait, current);
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned long flags;
-	unsigned long tmo;
-	int count;
-	if (!dmabuf->ready)
-		return 0;
-	if (dmabuf->mapped) {
-		stop_spdifout(state);
-		return 0;
-	}
-	add_wait_queue(&dmabuf->wait, &wait);
-	for (;;) {
-
-		spin_lock_irqsave(&state->card->lock, flags);
-		ali_update_ptr(state);
-		count = dmabuf->count;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-		if (count <= 0)
-			break;
-		/* 
-		 * This will make sure that our LVI is correct, that our
-		 * pointer is updated, and that the DAC is running.  We
-		 * have to force the setting of dmabuf->trigger to avoid
-		 * any possible deadlocks.
-		 */
-		if (!dmabuf->enable) {
-			if (codec_independent_spdif_locked > 0) {
-				dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-				ali_update_lvi(state, 2);
-			} else {
-				if (controller_independent_spdif_locked > 0) {
-					dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-					ali_update_lvi(state, 3);
-				}
-			}
-		}
-		if (signal_pending(current) && signals_allowed) {
-			break;
-		}
-
-		/* It seems that we have to set the current state to
-		 * TASK_INTERRUPTIBLE every time to make the process
-		 * really go to sleep.  This also has to be *after* the
-		 * update_ptr() call because update_ptr is likely to
-		 * do a wake_up() which will unset this before we ever
-		 * try to sleep, resuling in a tight loop in this code
-		 * instead of actually sleeping and waiting for an
-		 * interrupt to wake us up!
-		 */
-		set_current_state(TASK_INTERRUPTIBLE);
-		/*
-		 * set the timeout to significantly longer than it *should*
-		 * take for the DAC to drain the DMA buffer
-		 */
-		tmo = (count * HZ) / (dmabuf->rate);
-		if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-			printk(KERN_ERR "ali_audio: drain_spdifout, dma timeout?\n");
-			count = 0;
-			break;
-		}
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&dmabuf->wait, &wait);
-	if (count > 0 && signal_pending(current) && signals_allowed)
-		return -ERESTARTSYS;
-	stop_spdifout(state);
-	return 0;
-}
-
-static void ali_channel_interrupt(struct ali_card *card)
-{
-	int i, count;
-	
-	for (i = 0; i < NR_HW_CH; i++) {
-		struct ali_state *state = card->states[i];
-		struct ali_channel *c = NULL;
-		struct dmabuf *dmabuf;
-		unsigned long port = card->iobase;
-		u16 status;
-		if (!state)
-			continue;
-		if (!state->dmabuf.ready)
-			continue;
-		dmabuf = &state->dmabuf;
-		if (codec_independent_spdif_locked > 0) {
-			if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-				c = dmabuf->codec_spdifout_channel;
-			}
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-					c = dmabuf->controller_spdifout_channel;
-			} else {
-				if (dmabuf->enable & DAC_RUNNING) {
-					c = dmabuf->write_channel;
-				} else if (dmabuf->enable & ADC_RUNNING) {
-					c = dmabuf->read_channel;
-				} else
-					continue;
-			}
-		}
-		port += c->port;
-
-		status = inw(port + OFF_SR);
-
-		if (status & DMA_INT_COMPLETE) {
-			/* only wake_up() waiters if this interrupt signals
-			 * us being beyond a userfragsize of data open or
-			 * available, and ali_update_ptr() does that for
-			 * us
-			 */
-			ali_update_ptr(state);
-		}
-
-		if (status & DMA_INT_LVI) {
-			ali_update_ptr(state);
-			wake_up(&dmabuf->wait);
-
-			if (dmabuf->enable & DAC_RUNNING)
-				count = dmabuf->count;
-			else if (dmabuf->enable & ADC_RUNNING)
-				count = dmabuf->dmasize - dmabuf->count;
-			else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-				count = dmabuf->count;
-			else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-				count = dmabuf->count;
-			else count = 0;
-
-			if (count > 0) {
-				if (dmabuf->enable & DAC_RUNNING)
-					outl((1 << 1), state->card->iobase + ALI_DMACR);
-				else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-						outl((1 << 3), state->card->iobase + ALI_DMACR);
-				else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-					outl((1 << 7), state->card->iobase + ALI_DMACR);
-			} else {
-				if (dmabuf->enable & DAC_RUNNING)
-					__stop_dac(state);
-				if (dmabuf->enable & ADC_RUNNING)
-					__stop_adc(state);
-				if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-					__stop_spdifout(state);
-				if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-					__stop_spdifout(state);
-				dmabuf->enable = 0;
-				wake_up(&dmabuf->wait);
-			}
-
-		}
-		if (!(status & DMA_INT_DCH)) {
-			ali_update_ptr(state);
-			wake_up(&dmabuf->wait);
-			if (dmabuf->enable & DAC_RUNNING)
-				count = dmabuf->count;
-			else if (dmabuf->enable & ADC_RUNNING)
-				count = dmabuf->dmasize - dmabuf->count;
-			else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-				count = dmabuf->count;
-			else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-				count = dmabuf->count;
-			else
-				count = 0;
-
-			if (count > 0) {
-				if (dmabuf->enable & DAC_RUNNING)
-					outl((1 << 1), state->card->iobase + ALI_DMACR);
-				else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-					outl((1 << 3), state->card->iobase + ALI_DMACR);
-				else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-					outl((1 << 7), state->card->iobase + ALI_DMACR);
-			} else {
-				if (dmabuf->enable & DAC_RUNNING)
-					__stop_dac(state);
-				if (dmabuf->enable & ADC_RUNNING)
-					__stop_adc(state);
-				if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-					__stop_spdifout(state);
-				if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-					__stop_spdifout(state);
-				dmabuf->enable = 0;
-				wake_up(&dmabuf->wait);
-			}
-		}
-		outw(status & DMA_INT_MASK, port + OFF_SR);
-	}
-}
-
-static irqreturn_t ali_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct ali_card *card = (struct ali_card *) dev_id;
-	u32 status;
-	u16 status2;
-
-	spin_lock(&card->lock);
-	status = inl(card->iobase + ALI_INTERRUPTSR);
-	if (!(status & INT_MASK)) {
-		spin_unlock(&card->lock);
-		return IRQ_NONE;		/* not for us */
-	}
-
-	if (codec_independent_spdif_locked > 0) {
-		if (globel == 0) {
-			globel += 1;
-			status2 = inw(card->iobase + 0x76);
-			outw(status2 | 0x000c, card->iobase + 0x76);
-		} else {
-			if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT))
-				ali_channel_interrupt(card);
-		}
-	} else {
-		if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT))
-			ali_channel_interrupt(card);
-	}
-
-	/* clear 'em */
-	outl(status & INT_MASK, card->iobase + ALI_INTERRUPTSR);
-	spin_unlock(&card->lock);
-	return IRQ_HANDLED;
-}
-
-/* in this loop, dmabuf.count signifies the amount of data that is
-   waiting to be copied to the user's buffer.  It is filled by the dma
-   machine and drained by this loop. */
-
-static ssize_t ali_read(struct file *file, char __user *buffer,
-			size_t count, loff_t * ppos)
-{
-	struct ali_state *state = (struct ali_state *) file->private_data;
-	struct ali_card *card = state ? state->card : NULL;
-	struct dmabuf *dmabuf = &state->dmabuf;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned int swptr;
-	int cnt;
-	DECLARE_WAITQUEUE(waita, current);
-#ifdef DEBUG2
-	printk("ali_audio: ali_read called, count = %d\n", count);
-#endif
-	if (dmabuf->mapped)
-		return -ENXIO;
-	if (dmabuf->enable & DAC_RUNNING)
-		return -ENODEV;
-	if (!dmabuf->read_channel) {
-		dmabuf->ready = 0;
-		dmabuf->read_channel = card->alloc_rec_pcm_channel(card);
-		if (!dmabuf->read_channel) {
-			return -EBUSY;
-		}
-	}
-	if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	add_wait_queue(&dmabuf->wait, &waita);
-	while (count > 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		spin_lock_irqsave(&card->lock, flags);
-		if (PM_SUSPENDED(card)) {
-			spin_unlock_irqrestore(&card->lock, flags);
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			continue;
-		}
-		swptr = dmabuf->swptr;
-		cnt = ali_get_available_read_data(state);
-		// this is to make the copy_to_user simpler below
-		if (cnt > (dmabuf->dmasize - swptr))
-			cnt = dmabuf->dmasize - swptr;
-		spin_unlock_irqrestore(&card->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		/* Lop off the last two bits to force the code to always
-		 * write in full samples.  This keeps software that sets
-		 * O_NONBLOCK but doesn't check the return value of the
-		 * write call from getting things out of state where they
-		 * think a full 4 byte sample was written when really only
-		 * a portion was, resulting in odd sound and stereo
-		 * hysteresis.
-		 */
-		cnt &= ~0x3;
-		if (cnt <= 0) {
-			unsigned long tmo;
-			/*
-			 * Don't let us deadlock.  The ADC won't start if
-			 * dmabuf->trigger isn't set.  A call to SETTRIGGER
-			 * could have turned it off after we set it to on
-			 * previously.
-			 */
-			dmabuf->trigger = PCM_ENABLE_INPUT;
-			/*
-			 * This does three things.  Updates LVI to be correct,
-			 * makes sure the ADC is running, and updates the
-			 * hwptr.
-			 */
-			ali_update_lvi(state, 1);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto done;
-			}
-			/* Set the timeout to how long it would take to fill
-			 * two of our buffers.  If we haven't been woke up
-			 * by then, then we know something is wrong.
-			 */
-			tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4);
-			    
-			/* There are two situations when sleep_on_timeout returns, one is when
-			   the interrupt is serviced correctly and the process is waked up by
-			   ISR ON TIME. Another is when timeout is expired, which means that
-			   either interrupt is NOT serviced correctly (pending interrupt) or it
-			   is TOO LATE for the process to be scheduled to run (scheduler latency)
-			   which results in a (potential) buffer overrun. And worse, there is
-			   NOTHING we can do to prevent it. */
-			if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-				printk(KERN_ERR
-				       "ali_audio: recording schedule timeout, "
-				       "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				       dmabuf->dmasize, dmabuf->fragsize,
-				       dmabuf->count, dmabuf->hwptr,
-				       dmabuf->swptr);
-				/* a buffer overrun, we delay the recovery until next time the
-				   while loop begin and we REALLY have space to record */
-			}
-			if (signal_pending(current)) {
-				ret = ret ? ret : -ERESTARTSYS;
-				goto done;
-			}
-			continue;
-		}
-
-		if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			goto done;
-		}
-
-		swptr = (swptr + cnt) % dmabuf->dmasize;
-		spin_lock_irqsave(&card->lock, flags);
-		if (PM_SUSPENDED(card)) {
-			spin_unlock_irqrestore(&card->lock, flags);
-			continue;
-		}
-		dmabuf->swptr = swptr;
-		dmabuf->count -= cnt;
-		spin_unlock_irqrestore(&card->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-	}
-done:
-	ali_update_lvi(state, 1);
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&dmabuf->wait, &waita);
-	return ret;
-}
-
-/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
-   the soundcard.  it is drained by the dma machine and filled by this loop. */
-static ssize_t ali_write(struct file *file,
-			 const char __user *buffer, size_t count, loff_t * ppos)
-{
-	struct ali_state *state = (struct ali_state *) file->private_data;
-	struct ali_card *card = state ? state->card : NULL;
-	struct dmabuf *dmabuf = &state->dmabuf;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned int swptr = 0;
-	int cnt, x;
-	DECLARE_WAITQUEUE(waita, current);
-#ifdef DEBUG2
-	printk("ali_audio: ali_write called, count = %d\n", count);
-#endif
-	if (dmabuf->mapped)
-		return -ENXIO;
-	if (dmabuf->enable & ADC_RUNNING)
-		return -ENODEV;
-	if (codec_independent_spdif_locked > 0) {
-		if (!dmabuf->codec_spdifout_channel) {
-			dmabuf->ready = 0;
-			dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card);
-			if (!dmabuf->codec_spdifout_channel)
-				return -EBUSY;
-		}
-	} else {
-		if (controller_independent_spdif_locked > 0) {
-			if (!dmabuf->controller_spdifout_channel) {
-				dmabuf->ready = 0;
-				dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card);
-				if (!dmabuf->controller_spdifout_channel)
-					return -EBUSY;
-			}
-		} else {
-			if (!dmabuf->write_channel) {
-				dmabuf->ready = 0;
-				dmabuf->write_channel =
-				    card->alloc_pcm_channel(card);
-				if (!dmabuf->write_channel)
-					return -EBUSY;
-			}
-		}
-	}
-
-	if (codec_independent_spdif_locked > 0) {
-		if (!dmabuf->ready && (ret = prog_dmabuf(state, 2)))
-			return ret;
-	} else {
-		if (controller_independent_spdif_locked > 0) {
-			if (!dmabuf->ready && (ret = prog_dmabuf(state, 3)))
-				return ret;
-		} else {
-
-			if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-				return ret;
-		}
-	}
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	add_wait_queue(&dmabuf->wait, &waita);
-	while (count > 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		spin_lock_irqsave(&state->card->lock, flags);
-		if (PM_SUSPENDED(card)) {
-			spin_unlock_irqrestore(&card->lock, flags);
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			continue;
-		}
-
-		swptr = dmabuf->swptr;
-		cnt = ali_get_free_write_space(state);
-		/* Bound the maximum size to how much we can copy to the
-		 * dma buffer before we hit the end.  If we have more to
-		 * copy then it will get done in a second pass of this
-		 * loop starting from the beginning of the buffer.
-		 */
-		if (cnt > (dmabuf->dmasize - swptr))
-			cnt = dmabuf->dmasize - swptr;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-#ifdef DEBUG2
-		printk(KERN_INFO
-		       "ali_audio: ali_write: %d bytes available space\n",
-		       cnt);
-#endif
-		if (cnt > count)
-			cnt = count;
-		/* Lop off the last two bits to force the code to always
-		 * write in full samples.  This keeps software that sets
-		 * O_NONBLOCK but doesn't check the return value of the
-		 * write call from getting things out of state where they
-		 * think a full 4 byte sample was written when really only
-		 * a portion was, resulting in odd sound and stereo
-		 * hysteresis.
-		 */
-		cnt &= ~0x3;
-		if (cnt <= 0) {
-			unsigned long tmo;
-			// There is data waiting to be played
-			/*
-			 * Force the trigger setting since we would
-			 * deadlock with it set any other way
-			 */
-			if (codec_independent_spdif_locked > 0) {
-				dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-				ali_update_lvi(state, 2);
-			} else {
-				if (controller_independent_spdif_locked > 0) {
-					dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-					ali_update_lvi(state, 3);
-				} else {
-
-					dmabuf->trigger = PCM_ENABLE_OUTPUT;
-					ali_update_lvi(state, 0);
-				}
-			}
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto ret;
-			}
-			/* Not strictly correct but works */
-			tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4);
-			/* There are two situations when sleep_on_timeout returns, one is when
-			   the interrupt is serviced correctly and the process is waked up by
-			   ISR ON TIME. Another is when timeout is expired, which means that
-			   either interrupt is NOT serviced correctly (pending interrupt) or it
-			   is TOO LATE for the process to be scheduled to run (scheduler latency)
-			   which results in a (potential) buffer underrun. And worse, there is
-			   NOTHING we can do to prevent it. */
-			   
-			/* FIXME - do timeout handling here !! */
-			schedule_timeout(tmo >= 2 ? tmo : 2);
-
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				goto ret;
-			}
-			continue;
-		}
-		if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			goto ret;
-		}
-
-		swptr = (swptr + cnt) % dmabuf->dmasize;
-		spin_lock_irqsave(&state->card->lock, flags);
-		if (PM_SUSPENDED(card)) {
-			spin_unlock_irqrestore(&card->lock, flags);
-			continue;
-		}
-
-		dmabuf->swptr = swptr;
-		dmabuf->count += cnt;
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-	}
-	if (swptr % dmabuf->fragsize) {
-		x = dmabuf->fragsize - (swptr % dmabuf->fragsize);
-		memset(dmabuf->rawbuf + swptr, '\0', x);
-	}
-ret:
-	if (codec_independent_spdif_locked > 0) {
-		ali_update_lvi(state, 2);
-	} else {
-		if (controller_independent_spdif_locked > 0) {
-			ali_update_lvi(state, 3);
-		} else {
-			ali_update_lvi(state, 0);
-		}
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&dmabuf->wait, &waita);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int ali_poll(struct file *file, struct poll_table_struct
-			     *wait)
-{
-	struct ali_state *state = (struct ali_state *) file->private_data;
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned long flags;
-	unsigned int mask = 0;
-	if (!dmabuf->ready)
-		return 0;
-	poll_wait(file, &dmabuf->wait, wait);
-	spin_lock_irqsave(&state->card->lock, flags);
-	ali_update_ptr(state);
-	if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING) {
-		if (dmabuf->count >= (signed) dmabuf->fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE  && (dmabuf->enable & (DAC_RUNNING|CODEC_SPDIFOUT_RUNNING|CONTROLLER_SPDIFOUT_RUNNING))) {
-		if ((signed) dmabuf->dmasize >= dmabuf->count + (signed) dmabuf->fragsize)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&state->card->lock, flags);
-	return mask;
-}
-
-static int ali_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct ali_state *state = (struct ali_state *) file->private_data;
-	struct dmabuf *dmabuf = &state->dmabuf;
-	int ret = -EINVAL;
-	unsigned long size;
-	lock_kernel();
-	if (vma->vm_flags & VM_WRITE) {
-		if (!dmabuf->write_channel && (dmabuf->write_channel = state->card->alloc_pcm_channel(state->card)) == NULL) {
-			ret = -EBUSY;
-			goto out;
-		}
-	}
-	if (vma->vm_flags & VM_READ) {
-		if (!dmabuf->read_channel && (dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card)) == NULL) {
-			ret = -EBUSY;
-			goto out;
-		}
-	}
-	if ((ret = prog_dmabuf(state, 0)) != 0)
-		goto out;
-	ret = -EINVAL;
-	if (vma->vm_pgoff != 0)
-		goto out;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << dmabuf->buforder))
-		goto out;
-	ret = -EAGAIN;
-	if (remap_pfn_range(vma, vma->vm_start,
-				virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT,
-				size, vma->vm_page_prot))
-		goto out;
-	dmabuf->mapped = 1;
-	dmabuf->trigger = 0;
-	ret = 0;
-out:
-	unlock_kernel();
-	return ret;
-}
-
-static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct ali_state *state = (struct ali_state *) file->private_data;
-	struct ali_channel *c = NULL;
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned long flags;
-	audio_buf_info abinfo;
-	count_info cinfo;
-	unsigned int i_scr;
-	int val = 0, ret;
-	struct ac97_codec *codec = state->card->ac97_codec[0];
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-#ifdef DEBUG
-	printk("ali_audio: ali_ioctl, arg=0x%x, cmd=",
-	       arg ? *p : 0);
-#endif
-	switch (cmd) {
-	case OSS_GETVERSION:
-#ifdef DEBUG
-		printk("OSS_GETVERSION\n");
-#endif
-		return put_user(SOUND_VERSION, p);
-	case SNDCTL_DSP_RESET:
-#ifdef DEBUG
-		printk("SNDCTL_DSP_RESET\n");
-#endif
-		spin_lock_irqsave(&state->card->lock, flags);
-		if (dmabuf->enable == DAC_RUNNING) {
-			c = dmabuf->write_channel;
-			__stop_dac(state);
-		}
-		if (dmabuf->enable == ADC_RUNNING) {
-			c = dmabuf->read_channel;
-			__stop_adc(state);
-		}
-		if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-			c = dmabuf->codec_spdifout_channel;
-			__stop_spdifout(state);
-		}
-		if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-			c = dmabuf->controller_spdifout_channel;
-			__stop_spdifout(state);
-		}
-		if (c != NULL) {
-			outb(2, state->card->iobase + c->port + OFF_CR);	/* reset DMA machine */
-			outl(virt_to_bus(&c->sg[0]),
-			     state->card->iobase + c->port + OFF_BDBAR);
-			outb(0, state->card->iobase + c->port + OFF_CIV);
-			outb(0, state->card->iobase + c->port + OFF_LVI);
-		}
-
-		spin_unlock_irqrestore(&state->card->lock, flags);
-		synchronize_irq(state->card->pci_dev->irq);
-		dmabuf->ready = 0;
-		dmabuf->swptr = dmabuf->hwptr = 0;
-		dmabuf->count = dmabuf->total_bytes = 0;
-		return 0;
-	case SNDCTL_DSP_SYNC:
-#ifdef DEBUG
-		printk("SNDCTL_DSP_SYNC\n");
-#endif
-		if (codec_independent_spdif_locked > 0) {
-			if (dmabuf->enable != CODEC_SPDIFOUT_RUNNING
-			    || file->f_flags & O_NONBLOCK)
-				return 0;
-			if ((val = drain_spdifout(state, 1)))
-				return val;
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				if (dmabuf->enable !=
-				    CONTROLLER_SPDIFOUT_RUNNING
-				    || file->f_flags & O_NONBLOCK)
-					return 0;
-				if ((val = drain_spdifout(state, 1)))
-					return val;
-			} else {
-				if (dmabuf->enable != DAC_RUNNING
-				    || file->f_flags & O_NONBLOCK)
-					return 0;
-				if ((val = drain_dac(state, 1)))
-					return val;
-			}
-		}
-		dmabuf->total_bytes = 0;
-		return 0;
-	case SNDCTL_DSP_SPEED:	/* set smaple rate */
-#ifdef DEBUG
-		printk("SNDCTL_DSP_SPEED\n");
-#endif
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			if (file->f_mode & FMODE_WRITE) {
-				if ((state->card->ac97_status & SPDIF_ON)) {	/* S/PDIF Enabled */
-					/* RELTEK ALC650 only support 48000, need to check that */
-					if (ali_valid_spdif_rate(codec, val)) {
-						if (codec_independent_spdif_locked > 0) {
-							ali_set_spdif_output(state, -1, 0);
-							stop_spdifout(state);
-							dmabuf->ready = 0;
-							/* I add test codec independent spdif out */
-							spin_lock_irqsave(&state->card->lock, flags);
-							ali_set_codecspdifout_rate(state, val);	// I modified
-							spin_unlock_irqrestore(&state->card->lock, flags);
-							/* Set S/PDIF transmitter rate. */
-							i_scr = inl(state->card->iobase + ALI_SCR);
-							if ((i_scr & 0x00300000) == 0x00100000) {
-								ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-							} else {
-								if ((i_scr&0x00300000)  == 0x00200000)
-								{
-									ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-								} else {
-									if ((i_scr & 0x00300000) == 0x00300000) {
-										ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-									} else {
-										ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-									}
-								}
-							}
-
-							if (!(state->card->ac97_status & SPDIF_ON)) {
-								val = dmabuf->rate;
-							}
-						} else {
-							if (controller_independent_spdif_locked > 0) 
-							{
-								stop_spdifout(state);
-								dmabuf->ready = 0;
-								spin_lock_irqsave(&state->card->lock, flags);
-								ali_set_spdifout_rate(state, controller_independent_spdif_locked);
-								spin_unlock_irqrestore(&state->card->lock, flags);
-							} else {
-								/* Set DAC rate */
-								ali_set_spdif_output(state, -1, 0);
-								stop_dac(state);
-								dmabuf->ready = 0;
-								spin_lock_irqsave(&state->card->lock, flags);
-								ali_set_dac_rate(state, val);
-								spin_unlock_irqrestore(&state->card->lock, flags);
-								/* Set S/PDIF transmitter rate. */
-								ali_set_spdif_output(state, AC97_EA_SPSA_3_4, val);
-								if (!(state->card->ac97_status & SPDIF_ON))
-								{
-									val = dmabuf->rate;
-								}
-							}
-						}
-					} else {	/* Not a valid rate for S/PDIF, ignore it */
-						val = dmabuf->rate;
-					}
-				} else {
-					stop_dac(state);
-					dmabuf->ready = 0;
-					spin_lock_irqsave(&state->card->lock, flags);
-					ali_set_dac_rate(state, val);
-					spin_unlock_irqrestore(&state->card->lock, flags);
-				}
-			}
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(state);
-				dmabuf->ready = 0;
-				spin_lock_irqsave(&state->card->lock, flags);
-				ali_set_adc_rate(state, val);
-				spin_unlock_irqrestore(&state->card->lock, flags);
-			}
-		}
-		return put_user(dmabuf->rate, p);
-	case SNDCTL_DSP_STEREO:	/* set stereo or mono channel */
-#ifdef DEBUG
-		printk("SNDCTL_DSP_STEREO\n");
-#endif
-		if (dmabuf->enable & DAC_RUNNING) {
-			stop_dac(state);
-		}
-		if (dmabuf->enable & ADC_RUNNING) {
-			stop_adc(state);
-		}
-		if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-			stop_spdifout(state);
-		}
-		if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
-			stop_spdifout(state);
-		}
-		return put_user(1, p);
-	case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if (codec_independent_spdif_locked > 0) {
-				if (!dmabuf->ready && (val = prog_dmabuf(state, 2)))
-					return val;
-			} else {
-				if (controller_independent_spdif_locked > 0) {
-					if (!dmabuf->ready && (val = prog_dmabuf(state, 3)))
-						return val;
-				} else {
-					if (!dmabuf->ready && (val = prog_dmabuf(state, 0)))
-						return val;
-				}
-			}
-		}
-
-		if (file->f_mode & FMODE_READ) {
-			if (!dmabuf->ready && (val = prog_dmabuf(state, 1)))
-				return val;
-		}
-#ifdef DEBUG
-		printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize);
-#endif
-		return put_user(dmabuf->userfragsize, p);
-	case SNDCTL_DSP_GETFMTS:	/* Returns a mask of supported sample format */
-#ifdef DEBUG
-		printk("SNDCTL_DSP_GETFMTS\n");
-#endif
-		return put_user(AFMT_S16_LE, p);
-	case SNDCTL_DSP_SETFMT:	/* Select sample format */
-#ifdef DEBUG
-		printk("SNDCTL_DSP_SETFMT\n");
-#endif
-		return put_user(AFMT_S16_LE, p);
-	case SNDCTL_DSP_CHANNELS:	// add support 4,6 channel 
-#ifdef DEBUG
-		printk("SNDCTL_DSP_CHANNELS\n");
-#endif
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val > 0) {
-			if (dmabuf->enable & DAC_RUNNING) {
-				stop_dac(state);
-			}
-			if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-				stop_spdifout(state);
-			}
-			if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
-				stop_spdifout(state);
-			}
-			if (dmabuf->enable & ADC_RUNNING) {
-				stop_adc(state);
-			}
-		} else {
-			return put_user(state->card->channels, p);
-		}
-
-		i_scr = inl(state->card->iobase + ALI_SCR);
-		/* Current # of channels enabled */
-		if (i_scr & 0x00000100)
-			ret = 4;
-		else if (i_scr & 0x00000200)
-			ret = 6;
-		else
-			ret = 2;
-		switch (val) {
-		case 2:	/* 2 channels is always supported */
-			if (codec_independent_spdif_locked > 0) {
-				outl(((i_scr & 0xfffffcff) | 0x00100000), (state->card->iobase + ALI_SCR));
-			} else
-				outl((i_scr & 0xfffffcff), (state->card->iobase + ALI_SCR));
-			/* Do we need to change mixer settings????  */
-			break;
-		case 4:	/* Supported on some chipsets, better check first */
-			if (codec_independent_spdif_locked > 0) {
-				outl(((i_scr & 0xfffffcff) | 0x00000100 | 0x00200000), (state->card->iobase + ALI_SCR));
-			} else
-				outl(((i_scr & 0xfffffcff) | 0x00000100), (state->card->iobase + ALI_SCR));
-			break;
-		case 6:	/* Supported on some chipsets, better check first */
-			if (codec_independent_spdif_locked > 0) {
-				outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000 | 0x00300000), (state->card->iobase + ALI_SCR));
-			} else
-				outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000), (state->card->iobase + ALI_SCR));
-			break;
-		default:	/* nothing else is ever supported by the chipset */
-			val = ret;
-			break;
-		}
-		return put_user(val, p);
-	case SNDCTL_DSP_POST:	/* the user has sent all data and is notifying us */
-		/* we update the swptr to the end of the last sg segment then return */
-#ifdef DEBUG
-		printk("SNDCTL_DSP_POST\n");
-#endif
-		if (codec_independent_spdif_locked > 0) {
-			if (!dmabuf->ready || (dmabuf->enable != CODEC_SPDIFOUT_RUNNING))
-				return 0;
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				if (!dmabuf->ready || (dmabuf->enable != CONTROLLER_SPDIFOUT_RUNNING))
-					return 0;
-			} else {
-				if (!dmabuf->ready || (dmabuf->enable != DAC_RUNNING))
-					return 0;
-			}
-		}
-		if ((dmabuf->swptr % dmabuf->fragsize) != 0) {
-			val = dmabuf->fragsize - (dmabuf->swptr % dmabuf->fragsize);
-			dmabuf->swptr += val;
-			dmabuf->count += val;
-		}
-		return 0;
-	case SNDCTL_DSP_SUBDIVIDE:
-		if (dmabuf->subdivision)
-			return -EINVAL;
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-#ifdef DEBUG
-		printk("SNDCTL_DSP_SUBDIVIDE %d\n", val);
-#endif
-		dmabuf->subdivision = val;
-		dmabuf->ready = 0;
-		return 0;
-	case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(val, p))
-			return -EFAULT;
-		dmabuf->ossfragsize = 1 << (val & 0xffff);
-		dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
-		if (!dmabuf->ossfragsize || !dmabuf->ossmaxfrags)
-			return -EINVAL;
-		/*
-		 * Bound the frag size into our allowed range of 256 - 4096
-		 */
-		if (dmabuf->ossfragsize < 256)
-			dmabuf->ossfragsize = 256;
-		else if (dmabuf->ossfragsize > 4096)
-			dmabuf->ossfragsize = 4096;
-		/*
-		 * The numfrags could be something reasonable, or it could
-		 * be 0xffff meaning "Give me as much as possible".  So,
-		 * we check the numfrags * fragsize doesn't exceed our
-		 * 64k buffer limit, nor is it less than our 8k minimum.
-		 * If it fails either one of these checks, then adjust the
-		 * number of fragments, not the size of them.  It's OK if
-		 * our number of fragments doesn't equal 32 or anything
-		 * like our hardware based number now since we are using
-		 * a different frag count for the hardware.  Before we get
-		 * into this though, bound the maxfrags to avoid overflow
-		 * issues.  A reasonable bound would be 64k / 256 since our
-		 * maximum buffer size is 64k and our minimum frag size is
-		 * 256.  On the other end, our minimum buffer size is 8k and
-		 * our maximum frag size is 4k, so the lower bound should
-		 * be 2.
-		 */
-		if (dmabuf->ossmaxfrags > 256)
-			dmabuf->ossmaxfrags = 256;
-		else if (dmabuf->ossmaxfrags < 2)
-			dmabuf->ossmaxfrags = 2;
-		val = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
-		while (val < 8192) {
-			val <<= 1;
-			dmabuf->ossmaxfrags <<= 1;
-		}
-		while (val > 65536) {
-			val >>= 1;
-			dmabuf->ossmaxfrags >>= 1;
-		}
-		dmabuf->ready = 0;
-#ifdef DEBUG
-		printk("SNDCTL_DSP_SETFRAGMENT 0x%x, %d, %d\n", val,
-		       dmabuf->ossfragsize, dmabuf->ossmaxfrags);
-#endif
-		return 0;
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (codec_independent_spdif_locked > 0) {
-			if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0)
-				return val;
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0)
-					return val;
-			} else {
-				if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-					return val;
-			}
-		}
-		spin_lock_irqsave(&state->card->lock, flags);
-		ali_update_ptr(state);
-		abinfo.fragsize = dmabuf->userfragsize;
-		abinfo.fragstotal = dmabuf->userfrags;
-		if (dmabuf->mapped)
-			abinfo.bytes = dmabuf->dmasize;
-		else
-			abinfo.bytes = ali_get_free_write_space(state);
-		abinfo.fragments = abinfo.bytes / dmabuf->userfragsize;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-		printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n",
-		       abinfo.bytes, abinfo.fragsize, abinfo.fragments,
-		       abinfo.fragstotal);
-#endif
-		return copy_to_user(argp, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-	case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (codec_independent_spdif_locked > 0) {
-			if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0)
-				return val;
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0)
-					return val;
-			} else {
-				if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-					return val;
-			}
-		}
-		spin_lock_irqsave(&state->card->lock, flags);
-		val = ali_get_free_write_space(state);
-		cinfo.bytes = dmabuf->total_bytes;
-		cinfo.ptr = dmabuf->hwptr;
-		cinfo.blocks = val / dmabuf->userfragsize;
-		if (codec_independent_spdif_locked > 0) {
-			if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-				dmabuf->count += val;
-				dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-				__ali_update_lvi(state, 2);
-			}
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-					dmabuf->count += val;
-					dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-					__ali_update_lvi(state, 3);
-				}
-			} else {
-				if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-					dmabuf->count += val;
-					dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-					__ali_update_lvi(state, 0);
-				}
-			}
-		}
-		spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-		printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
-		       cinfo.blocks, cinfo.ptr, dmabuf->count);
-#endif
-		return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT : 0;
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
-			return val;
-		spin_lock_irqsave(&state->card->lock, flags);
-		abinfo.bytes = ali_get_available_read_data(state);
-		abinfo.fragsize = dmabuf->userfragsize;
-		abinfo.fragstotal = dmabuf->userfrags;
-		abinfo.fragments = abinfo.bytes / dmabuf->userfragsize;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-		printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n",
-		       abinfo.bytes, abinfo.fragsize, abinfo.fragments,
-		       abinfo.fragstotal);
-#endif
-		return copy_to_user(argp, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-	case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-			return val;
-		spin_lock_irqsave(&state->card->lock, flags);
-		val = ali_get_available_read_data(state);
-		cinfo.bytes = dmabuf->total_bytes;
-		cinfo.blocks = val / dmabuf->userfragsize;
-		cinfo.ptr = dmabuf->hwptr;
-		if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-			dmabuf->count -= val;
-			dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-			__ali_update_lvi(state, 1);
-		}
-		spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-		printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
-		       cinfo.blocks, cinfo.ptr, dmabuf->count);
-#endif
-		return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT: 0;
-	case SNDCTL_DSP_NONBLOCK:
-#ifdef DEBUG
-		printk("SNDCTL_DSP_NONBLOCK\n");
-#endif
-		file->f_flags |= O_NONBLOCK;
-		return 0;
-	case SNDCTL_DSP_GETCAPS:
-#ifdef DEBUG
-		printk("SNDCTL_DSP_GETCAPS\n");
-#endif
-		return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
-				DSP_CAP_MMAP | DSP_CAP_BIND, p);
-	case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-#ifdef DEBUG
-		printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger);
-#endif
-		return put_user(dmabuf->trigger, p);
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-		printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
-#endif
-		if (!(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) {
-			stop_adc(state);
-		}
-		if (!(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) {
-			stop_dac(state);
-		}
-		if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-			stop_spdifout(state);
-		}
-		if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-			stop_spdifout(state);
-		}
-		dmabuf->trigger = val;
-		if (val & PCM_ENABLE_OUTPUT && !(dmabuf->enable & DAC_RUNNING)) {
-			if (!dmabuf->write_channel) {
-				dmabuf->ready = 0;
-				dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
-				if (!dmabuf->write_channel)
-					return -EBUSY;
-			}
-			if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-				return ret;
-			if (dmabuf->mapped) {
-				spin_lock_irqsave(&state->card->lock, flags);
-				ali_update_ptr(state);
-				dmabuf->count = 0;
-				dmabuf->swptr = dmabuf->hwptr;
-				dmabuf->count = ali_get_free_write_space(state);
-				dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-				__ali_update_lvi(state, 0);
-				spin_unlock_irqrestore(&state->card->lock,
-						       flags);
-			} else
-				start_dac(state);
-		}
-		if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CODEC_SPDIFOUT_RUNNING)) {
-			if (!dmabuf->codec_spdifout_channel) {
-				dmabuf->ready = 0;
-				dmabuf->codec_spdifout_channel = state->card->alloc_codec_spdifout_channel(state->card);
-				if (!dmabuf->codec_spdifout_channel)
-					return -EBUSY;
-			}
-			if (!dmabuf->ready && (ret = prog_dmabuf(state, 2)))
-				return ret;
-			if (dmabuf->mapped) {
-				spin_lock_irqsave(&state->card->lock, flags);
-				ali_update_ptr(state);
-				dmabuf->count = 0;
-				dmabuf->swptr = dmabuf->hwptr;
-				dmabuf->count = ali_get_free_write_space(state);
-				dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-				__ali_update_lvi(state, 2);
-				spin_unlock_irqrestore(&state->card->lock,
-						       flags);
-			} else
-				start_spdifout(state);
-		}
-		if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)) {
-			if (!dmabuf->controller_spdifout_channel) {
-				dmabuf->ready = 0;
-				dmabuf->controller_spdifout_channel = state->card->alloc_controller_spdifout_channel(state->card);
-				if (!dmabuf->controller_spdifout_channel)
-					return -EBUSY;
-			}
-			if (!dmabuf->ready && (ret = prog_dmabuf(state, 3)))
-				return ret;
-			if (dmabuf->mapped) {
-				spin_lock_irqsave(&state->card->lock, flags);
-				ali_update_ptr(state);
-				dmabuf->count = 0;
-				dmabuf->swptr = dmabuf->hwptr;
-				dmabuf->count = ali_get_free_write_space(state);
-				dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-				__ali_update_lvi(state, 3);
-				spin_unlock_irqrestore(&state->card->lock, flags);
-			} else
-				start_spdifout(state);
-		}
-		if (val & PCM_ENABLE_INPUT && !(dmabuf->enable & ADC_RUNNING)) {
-			if (!dmabuf->read_channel) {
-				dmabuf->ready = 0;
-				dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
-				if (!dmabuf->read_channel)
-					return -EBUSY;
-			}
-			if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-				return ret;
-			if (dmabuf->mapped) {
-				spin_lock_irqsave(&state->card->lock,
-						  flags);
-				ali_update_ptr(state);
-				dmabuf->swptr = dmabuf->hwptr;
-				dmabuf->count = 0;
-				spin_unlock_irqrestore(&state->card->lock, flags);
-			}
-			ali_update_lvi(state, 1);
-			start_adc(state);
-		}
-		return 0;
-	case SNDCTL_DSP_SETDUPLEX:
-#ifdef DEBUG
-		printk("SNDCTL_DSP_SETDUPLEX\n");
-#endif
-		return -EINVAL;
-	case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		spin_lock_irqsave(&state->card->lock, flags);
-		ali_update_ptr(state);
-		val = dmabuf->count;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-#ifdef DEBUG
-		printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
-#endif
-		return put_user(val, p);
-	case SOUND_PCM_READ_RATE:
-#ifdef DEBUG
-		printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate);
-#endif
-		return put_user(dmabuf->rate, p);
-	case SOUND_PCM_READ_CHANNELS:
-#ifdef DEBUG
-		printk("SOUND_PCM_READ_CHANNELS\n");
-#endif
-		return put_user(2, p);
-	case SOUND_PCM_READ_BITS:
-#ifdef DEBUG
-		printk("SOUND_PCM_READ_BITS\n");
-#endif
-		return put_user(AFMT_S16_LE, p);
-	case SNDCTL_DSP_SETSPDIF:	/* Set S/PDIF Control register */
-#ifdef DEBUG
-		printk("SNDCTL_DSP_SETSPDIF\n");
-#endif
-		if (get_user(val, p))
-			return -EFAULT;
-		/* Check to make sure the codec supports S/PDIF transmitter */
-		if ((state->card->ac97_features & 4)) {
-			/* mask out the transmitter speed bits so the user can't set them */
-			val &= ~0x3000;
-			/* Add the current transmitter speed bits to the passed value */
-			ret = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-			val |= (ret & 0x3000);
-			ali_ac97_set(codec, AC97_SPDIF_CONTROL, val);
-			if (ali_ac97_get(codec, AC97_SPDIF_CONTROL) != val) {
-				printk(KERN_ERR "ali_audio: Unable to set S/PDIF configuration to 0x%04x.\n", val);
-				return -EFAULT;
-			}
-		}
-#ifdef DEBUG
-		else
-			printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
-#endif
-		return put_user(val, p);
-	case SNDCTL_DSP_GETSPDIF:	/* Get S/PDIF Control register */
-#ifdef DEBUG
-		printk("SNDCTL_DSP_GETSPDIF\n");
-#endif
-		if (get_user(val, p))
-			return -EFAULT;
-		/* Check to make sure the codec supports S/PDIF transmitter */
-		if (!(state->card->ac97_features & 4)) {
-#ifdef DEBUG
-			printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
-#endif
-			val = 0;
-		} else {
-			val = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-		}
-
-		return put_user(val, p);
-//end add support spdif out
-//add support 4,6 channel
-	case SNDCTL_DSP_GETCHANNELMASK:
-#ifdef DEBUG
-		printk("SNDCTL_DSP_GETCHANNELMASK\n");
-#endif
-		if (get_user(val, p))
-			return -EFAULT;
-		/* Based on AC'97 DAC support, not ICH hardware */
-		val = DSP_BIND_FRONT;
-		if (state->card->ac97_features & 0x0004)
-			val |= DSP_BIND_SPDIF;
-		if (state->card->ac97_features & 0x0080)
-			val |= DSP_BIND_SURR;
-		if (state->card->ac97_features & 0x0140)
-			val |= DSP_BIND_CENTER_LFE;
-		return put_user(val, p);
-	case SNDCTL_DSP_BIND_CHANNEL:
-#ifdef DEBUG
-		printk("SNDCTL_DSP_BIND_CHANNEL\n");
-#endif
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val == DSP_BIND_QUERY) {
-			val = DSP_BIND_FRONT;	/* Always report this as being enabled */
-			if (state->card->ac97_status & SPDIF_ON)
-				val |= DSP_BIND_SPDIF;
-			else {
-				if (state->card->ac97_status & SURR_ON)
-					val |= DSP_BIND_SURR;
-				if (state->card->
-				    ac97_status & CENTER_LFE_ON)
-					val |= DSP_BIND_CENTER_LFE;
-			}
-		} else {	/* Not a query, set it */
-			if (!(file->f_mode & FMODE_WRITE))
-				return -EINVAL;
-			if (dmabuf->enable == DAC_RUNNING) {
-				stop_dac(state);
-			}
-			if (val & DSP_BIND_SPDIF) {	/* Turn on SPDIF */
-				/*  Ok, this should probably define what slots
-				 *  to use. For now, we'll only set it to the
-				 *  defaults:
-				 * 
-				 *   non multichannel codec maps to slots 3&4
-				 *   2 channel codec maps to slots 7&8
-				 *   4 channel codec maps to slots 6&9
-				 *   6 channel codec maps to slots 10&11
-				 *
-				 *  there should be some way for the app to
-				 *  select the slot assignment.
-				 */
-				i_scr = inl(state->card->iobase + ALI_SCR);
-				if (codec_independent_spdif_locked > 0) {
-
-					if ((i_scr & 0x00300000) == 0x00100000) {
-						ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-					} else {
-						if ((i_scr & 0x00300000) == 0x00200000) {
-							ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-						} else {
-							if ((i_scr & 0x00300000) == 0x00300000) {
-								ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-							}
-						}
-					}
-				} else {	/* codec spdif out (pcm out share ) */
-					ali_set_spdif_output(state, AC97_EA_SPSA_3_4, dmabuf->rate);	//I do not modify
-				}
-
-				if (!(state->card->ac97_status & SPDIF_ON))
-					val &= ~DSP_BIND_SPDIF;
-			} else {
-				int mask;
-				int channels;
-				/* Turn off S/PDIF if it was on */
-				if (state->card->ac97_status & SPDIF_ON)
-					ali_set_spdif_output(state, -1, 0);
-				mask =
-				    val & (DSP_BIND_FRONT | DSP_BIND_SURR |
-					   DSP_BIND_CENTER_LFE);
-				switch (mask) {
-				case DSP_BIND_FRONT:
-					channels = 2;
-					break;
-				case DSP_BIND_FRONT | DSP_BIND_SURR:
-					channels = 4;
-					break;
-				case DSP_BIND_FRONT | DSP_BIND_SURR | DSP_BIND_CENTER_LFE:
-					channels = 6;
-					break;
-				default:
-					val = DSP_BIND_FRONT;
-					channels = 2;
-					break;
-				}
-				ali_set_dac_channels(state, channels);
-				/* check that they really got turned on */
-				if (!state->card->ac97_status & SURR_ON)
-					val &= ~DSP_BIND_SURR;
-				if (!state->card->
-				    ac97_status & CENTER_LFE_ON)
-					val &= ~DSP_BIND_CENTER_LFE;
-			}
-		}
-		return put_user(val, p);
-	case SNDCTL_DSP_MAPINBUF:
-	case SNDCTL_DSP_MAPOUTBUF:
-	case SNDCTL_DSP_SETSYNCRO:
-	case SOUND_PCM_WRITE_FILTER:
-	case SOUND_PCM_READ_FILTER:
-		return -EINVAL;
-	}
-	return -EINVAL;
-}
-
-static int ali_open(struct inode *inode, struct file *file)
-{
-	int i = 0;
-	struct ali_card *card = devs;
-	struct ali_state *state = NULL;
-	struct dmabuf *dmabuf = NULL;
-	unsigned int i_scr;
-	
-	/* find an available virtual channel (instance of /dev/dsp) */
-	
-	while (card != NULL) {
-
-		/*
-		 * If we are initializing and then fail, card could go
-		 * away unuexpectedly while we are in the for() loop.
-		 * So, check for card on each iteration before we check
-		 * for card->initializing to avoid a possible oops.
-		 * This usually only matters for times when the driver is
-		 * autoloaded by kmod.
-		 */
-		for (i = 0; i < 50 && card && card->initializing; i++) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ / 20);
-		}
-
-		for (i = 0; i < NR_HW_CH && card && !card->initializing; i++) {
-			if (card->states[i] == NULL) {
-				state = card->states[i] = (struct ali_state *) kmalloc(sizeof(struct ali_state), GFP_KERNEL);
-				if (state == NULL)
-					return -ENOMEM;
-				memset(state, 0, sizeof(struct ali_state));
-				dmabuf = &state->dmabuf;
-				goto found_virt;
-			}
-		}
-		card = card->next;
-	}
-
-	/* no more virtual channel avaiable */
-	if (!state)
-		return -ENODEV;
-found_virt:
-	/* initialize the virtual channel */
-
-	state->virt = i;
-	state->card = card;
-	state->magic = ALI5455_STATE_MAGIC;
-	init_waitqueue_head(&dmabuf->wait);
-	mutex_init(&state->open_mutex);
-	file->private_data = state;
-	dmabuf->trigger = 0;
-	/* allocate hardware channels */
-	if (file->f_mode & FMODE_READ) {
-		if ((dmabuf->read_channel =
-		     card->alloc_rec_pcm_channel(card)) == NULL) {
-			kfree(card->states[i]);
-			card->states[i] = NULL;
-			return -EBUSY;
-		}
-		dmabuf->trigger |= PCM_ENABLE_INPUT;
-		ali_set_adc_rate(state, 8000);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (codec_independent_spdif_locked > 0) {
-			if ((dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card)) == NULL) {
-				kfree(card->states[i]);
-				card->states[i] = NULL;
-				return -EBUSY;
-			}
-			dmabuf->trigger |= SPDIF_ENABLE_OUTPUT;
-			ali_set_codecspdifout_rate(state, codec_independent_spdif_locked);	//It must add
-			i_scr = inl(state->card->iobase + ALI_SCR);
-			if ((i_scr & 0x00300000) == 0x00100000) {
-				ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-			} else {
-				if ((i_scr & 0x00300000) == 0x00200000) {
-					ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-				} else {
-					if ((i_scr & 0x00300000) == 0x00300000) {
-						ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-					} else {
-						ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-					}
-				}
-
-			}
-		} else {
-			if (controller_independent_spdif_locked > 0) {
-				if ((dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card)) == NULL) {
-					kfree(card->states[i]);
-					card->states[i] = NULL;
-					return -EBUSY;
-				}
-				dmabuf->trigger |= SPDIF_ENABLE_OUTPUT;
-				ali_set_spdifout_rate(state, controller_independent_spdif_locked);
-			} else {
-				if ((dmabuf->write_channel = card->alloc_pcm_channel(card)) == NULL) {
-					kfree(card->states[i]);
-					card->states[i] = NULL;
-					return -EBUSY;
-				}
-				/* Initialize to 8kHz?  What if we don't support 8kHz? */
-				/*  Let's change this to check for S/PDIF stuff */
-
-				dmabuf->trigger |= PCM_ENABLE_OUTPUT;
-				if (codec_pcmout_share_spdif_locked) {
-					ali_set_dac_rate(state, codec_pcmout_share_spdif_locked);
-					ali_set_spdif_output(state, AC97_EA_SPSA_3_4, codec_pcmout_share_spdif_locked);
-				} else {
-					ali_set_dac_rate(state, 8000);
-				}
-			}
-
-		}
-	}
-
-	/* set default sample format. According to OSS Programmer's Guide  /dev/dsp
-	   should be default to unsigned 8-bits, mono, with sample rate 8kHz and
-	   /dev/dspW will accept 16-bits sample, but we don't support those so we
-	   set it immediately to stereo and 16bit, which is all we do support */
-	dmabuf->fmt |= ALI5455_FMT_16BIT | ALI5455_FMT_STEREO;
-	dmabuf->ossfragsize = 0;
-	dmabuf->ossmaxfrags = 0;
-	dmabuf->subdivision = 0;
-	state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	outl(0x00000000, card->iobase + ALI_INTERRUPTCR);
-	outl(0x00000000, card->iobase + ALI_INTERRUPTSR);
-	return nonseekable_open(inode, file);
-}
-
-static int ali_release(struct inode *inode, struct file *file)
-{
-	struct ali_state *state = (struct ali_state *) file->private_data;
-	struct ali_card *card = state->card;
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned long flags;
-	lock_kernel();
-	
-	/* stop DMA state machine and free DMA buffers/channels */
-	if (dmabuf->trigger & PCM_ENABLE_OUTPUT)
-		drain_dac(state, 0);
-
-	if (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)
-		drain_spdifout(state, 0);
-	
-	if (dmabuf->trigger & PCM_ENABLE_INPUT)
-		stop_adc(state);
-	
-	spin_lock_irqsave(&card->lock, flags);
-	dealloc_dmabuf(state);
-	if (file->f_mode & FMODE_WRITE) {
-		if (codec_independent_spdif_locked > 0) {
-			state->card->free_pcm_channel(state->card, dmabuf->codec_spdifout_channel->num);
-		} else {
-			if (controller_independent_spdif_locked > 0)
-				state->card->free_pcm_channel(state->card,
-							      dmabuf->controller_spdifout_channel->num);
-			else state->card->free_pcm_channel(state->card,
-							      dmabuf->write_channel->num);
-		}
-	}
-	if (file->f_mode & FMODE_READ)
-		state->card->free_pcm_channel(state->card, dmabuf->read_channel->num);
-
-	state->card->states[state->virt] = NULL;
-	kfree(state);
-	spin_unlock_irqrestore(&card->lock, flags);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const */ struct file_operations ali_audio_fops = {
-	.owner		= THIS_MODULE, 
-	.llseek		= no_llseek, 
-	.read		= ali_read,
-	.write		= ali_write, 
-	.poll		= ali_poll,
-	.ioctl		= ali_ioctl,
-	.mmap		= ali_mmap,
-	.open		= ali_open,
-	.release	= ali_release,
-};
-
-/* Read AC97 codec registers */
-static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg)
-{
-	struct ali_card *card = dev->private_data;
-	int count1 = 100;
-	char val;
-	unsigned short int data = 0, count, addr1, addr2 = 0;
-
-	spin_lock(&card->ac97_lock);
-	while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
-		udelay(1);
-
-	addr1 = reg;
-	reg |= 0x0080;
-	for (count = 0; count < 0x7f; count++) {
-		val = inb(card->iobase + ALI_CSPSR);
-		if (val & 0x08)
-			break;
-	}
-	if (count == 0x7f)
-	{
-		spin_unlock(&card->ac97_lock);
-		return -1;
-	}
-	outw(reg, (card->iobase + ALI_CPR) + 2);
-	for (count = 0; count < 0x7f; count++) {
-		val = inb(card->iobase + ALI_CSPSR);
-		if (val & 0x02) {
-			data = inw(card->iobase + ALI_SPR);
-			addr2 = inw((card->iobase + ALI_SPR) + 2);
-			break;
-		}
-	}
-	spin_unlock(&card->ac97_lock);
-	if (count == 0x7f)
-		return -1;
-	if (addr2 != addr1)
-		return -1;
-	return ((u16) data);
-}
-
-/* write ac97 codec register   */
-
-static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
-{
-	struct ali_card *card = dev->private_data;
-	int count1 = 100;
-	char val;
-	unsigned short int count;
-
-	spin_lock(&card->ac97_lock);
-	while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
-		udelay(1);
-
-	for (count = 0; count < 0x7f; count++) {
-		val = inb(card->iobase + ALI_CSPSR);
-		if (val & 0x08)
-			break;
-	}
-	if (count == 0x7f) {
-		printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
-		spin_unlock(&card->ac97_lock);
-		return;
-	}
-	outw(data, (card->iobase + ALI_CPR));
-	outb(reg, (card->iobase + ALI_CPR) + 2);
-	for (count = 0; count < 0x7f; count++) {
-		val = inb(card->iobase + ALI_CSPSR);
-		if (val & 0x01)
-			break;
-	}
-	spin_unlock(&card->ac97_lock);
-	if (count == 0x7f)
-		printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
-	return;
-}
-
-/* OSS /dev/mixer file operation methods */
-
-static int ali_open_mixdev(struct inode *inode, struct file *file)
-{
-	int i;
-	int minor = iminor(inode);
-	struct ali_card *card = devs;
-	for (card = devs; card != NULL; card = card->next) {
-		/*
-		 * If we are initializing and then fail, card could go
-		 * away unuexpectedly while we are in the for() loop.
-		 * So, check for card on each iteration before we check
-		 * for card->initializing to avoid a possible oops.
-		 * This usually only matters for times when the driver is
-		 * autoloaded by kmod.
-		 */
-		for (i = 0; i < 50 && card && card->initializing; i++) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ / 20);
-		}
-		for (i = 0; i < NR_AC97 && card && !card->initializing; i++)
-			if (card->ac97_codec[i] != NULL
-			    && card->ac97_codec[i]->dev_mixer == minor) {
-				file->private_data = card->ac97_codec[i];
-				return nonseekable_open(inode, file);
-			}
-	}
-	return -ENODEV;
-}
-
-static int ali_ioctl_mixdev(struct inode *inode,
-			    struct file *file,
-			    unsigned int cmd, unsigned long arg)
-{
-	struct ac97_codec *codec = (struct ac97_codec *) file->private_data;
-	return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static /*const */ struct file_operations ali_mixer_fops = {
-	.owner	= THIS_MODULE, 
-	.llseek	= no_llseek, 
-	.ioctl	= ali_ioctl_mixdev,
-	.open	= ali_open_mixdev,
-};
-
-/* AC97 codec initialisation.  These small functions exist so we don't
-   duplicate code between module init and apm resume */
-
-static inline int ali_ac97_exists(struct ali_card *card, int ac97_number)
-{
-	unsigned int i = 1;
-	u32 reg = inl(card->iobase + ALI_RTSR);
-	if (ac97_number) {
-		while (i < 100) {
-
-			reg = inl(card->iobase + ALI_RTSR);
-			if (reg & 0x40) {
-				break;
-			} else {
-				outl(reg | 0x00000040,
-				     card->iobase + 0x34);
-				udelay(1);
-			}
-			i++;
-		}
-
-	} else {
-		while (i < 100) {
-			reg = inl(card->iobase + ALI_RTSR);
-			if (reg & 0x80) {
-				break;
-			} else {
-				outl(reg | 0x00000080,
-				     card->iobase + 0x34);
-				udelay(1);
-			}
-			i++;
-		}
-	}
-
-	if (ac97_number)
-		return reg & 0x40;
-	else
-		return reg & 0x80;
-}
-
-static inline int ali_ac97_enable_variable_rate(struct ac97_codec *codec)
-{
-	ali_ac97_set(codec, AC97_EXTENDED_STATUS, 9);
-	ali_ac97_set(codec, AC97_EXTENDED_STATUS, ali_ac97_get(codec, AC97_EXTENDED_STATUS) | 0xE800);
-	return (ali_ac97_get(codec, AC97_EXTENDED_STATUS) & 1);
-}
-
-
-static int ali_ac97_probe_and_powerup(struct ali_card *card, struct ac97_codec *codec)
-{
-	/* Returns 0 on failure */
-	int i;
-	u16 addr;
-	if (ac97_probe_codec(codec) == 0)
-		return 0;
-	/* ac97_probe_codec is success ,then begin to init codec */
-	ali_ac97_set(codec, AC97_RESET, 0xffff);
-	if (card->channel[0].used == 1) {
-		ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000);
-		ali_ac97_set(codec, AC97_LINEIN_VOL, 0x0808);
-		ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F);
-	}
-
-	if (card->channel[2].used == 1)	//if MICin then init codec
-	{
-		ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000);
-		ali_ac97_set(codec, AC97_MIC_VOL, 0x8808);
-		ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F);
-		ali_ac97_set(codec, AC97_RECORD_GAIN_MIC, 0x0000);
-	}
-
-	ali_ac97_set(codec, AC97_MASTER_VOL_STEREO, 0x0000);
-	ali_ac97_set(codec, AC97_HEADPHONE_VOL, 0x0000);
-	ali_ac97_set(codec, AC97_PCMOUT_VOL, 0x0000);
-	ali_ac97_set(codec, AC97_CD_VOL, 0x0808);
-	ali_ac97_set(codec, AC97_VIDEO_VOL, 0x0808);
-	ali_ac97_set(codec, AC97_AUX_VOL, 0x0808);
-	ali_ac97_set(codec, AC97_PHONE_VOL, 0x8048);
-	ali_ac97_set(codec, AC97_PCBEEP_VOL, 0x0000);
-	ali_ac97_set(codec, AC97_GENERAL_PURPOSE, AC97_GP_MIX);
-	ali_ac97_set(codec, AC97_MASTER_VOL_MONO, 0x0000);
-	ali_ac97_set(codec, 0x38, 0x0000);
-	addr = ali_ac97_get(codec, 0x2a);
-	ali_ac97_set(codec, 0x2a, addr | 0x0001);
-	addr = ali_ac97_get(codec, 0x2a);
-	addr = ali_ac97_get(codec, 0x28);
-	ali_ac97_set(codec, 0x2c, 0xbb80);
-	addr = ali_ac97_get(codec, 0x2c);
-	/* power it all up */
-	ali_ac97_set(codec, AC97_POWER_CONTROL,
-		     ali_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
-	/* wait for analog ready */
-	for (i = 10; i && ((ali_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
-	}
-	/* FIXME !! */
-	i++;
-	return i;
-}
-
-
-/* I clone ali5455(2.4.7 )  not clone i810_audio(2.4.18)  */
-
-static int ali_reset_5455(struct ali_card *card)
-{
-	outl(0x80000003, card->iobase + ALI_SCR);
-	outl(0x83838383, card->iobase + ALI_FIFOCR1);
-	outl(0x83838383, card->iobase + ALI_FIFOCR2);
-	if (controller_pcmout_share_spdif_locked > 0) {
-		outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001),
-		     card->iobase + ALI_SPDIFICS);
-		outl(0x0408000a, card->iobase + ALI_INTERFACECR);
-	} else {
-		if (codec_independent_spdif_locked > 0) {
-			outl((inl(card->iobase + ALI_SCR) | 0x00100000), card->iobase + ALI_SCR);	// now I select slot 7 & 8
-			outl(0x00200000, card->iobase + ALI_INTERFACECR);	//enable codec independent spdifout 
-		} else
-			outl(0x04080002, card->iobase + ALI_INTERFACECR);
-	}
-
-	outl(0x00000000, card->iobase + ALI_INTERRUPTCR);
-	outl(0x00000000, card->iobase + ALI_INTERRUPTSR);
-	if (controller_independent_spdif_locked > 0)
-		outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001),
-		     card->iobase + ALI_SPDIFICS);
-	return 1;
-}
-
-
-static int ali_ac97_random_init_stuff(struct ali_card
-				      *card)
-{
-	u32 reg = inl(card->iobase + ALI_SCR);
-	int i = 0;
-	reg = inl(card->iobase + ALI_SCR);
-	if ((reg & 2) == 0)	/* Cold required */
-		reg |= 2;
-	else
-		reg |= 1;	/* Warm */
-	reg &= ~0x80000000;	/* ACLink on */
-	outl(reg, card->iobase + ALI_SCR);
-
-	while (i < 10) {
-		if ((inl(card->iobase + 0x18) & (1 << 1)) == 0)
-			break;
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(HZ / 20);
-		i++;
-	}
-	if (i == 10) {
-		printk(KERN_ERR "ali_audio: AC'97 reset failed.\n");
-		return 0;
-	}
-
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 2);
-	return 1;
-}
-
-/* AC97 codec initialisation. */
-
-static int __devinit ali_ac97_init(struct ali_card *card)
-{
-	int num_ac97 = 0;
-	int total_channels = 0;
-	struct ac97_codec *codec;
-	u16 eid;
-
-	if (!ali_ac97_random_init_stuff(card))
-		return 0;
-
-	/* Number of channels supported */
-	/* What about the codec?  Just because the ICH supports */
-	/* multiple channels doesn't mean the codec does.       */
-	/* we'll have to modify this in the codec section below */
-	/* to reflect what the codec has.                       */
-	/* ICH and ICH0 only support 2 channels so don't bother */
-	/* to check....                                         */
-	inl(card->iobase + ALI_CPR);
-	card->channels = 2;
-
-	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-
-		/* Assume codec isn't available until we go through the
-		 * gauntlet below */
-		card->ac97_codec[num_ac97] = NULL;
-		/* The ICH programmer's reference says you should   */
-		/* check the ready status before probing. So we chk */
-		/*   What do we do if it's not ready?  Wait and try */
-		/*   again, or abort?                               */
-		if (!ali_ac97_exists(card, num_ac97)) {
-			if (num_ac97 == 0)
-				printk(KERN_ERR "ali_audio: Primary codec not ready.\n");
-			break;
-		}
-
-		if ((codec = ac97_alloc_codec()) == NULL)
-			return -ENOMEM;
-		/* initialize some basic codec information, other fields will be filled
-		   in ac97_probe_codec */
-		codec->private_data = card;
-		codec->id = num_ac97;
-		codec->codec_read = ali_ac97_get;
-		codec->codec_write = ali_ac97_set;
-		if (!ali_ac97_probe_and_powerup(card, codec)) {
-			printk(KERN_ERR "ali_audio: timed out waiting for codec %d analog ready",
-			     num_ac97);
-			kfree(codec);
-			break;	/* it didn't work */
-		}
-		
-		/* Store state information about S/PDIF transmitter */
-		card->ac97_status = 0;
-		/* Don't attempt to get eid until powerup is complete */
-		eid = ali_ac97_get(codec, AC97_EXTENDED_ID);
-		if (eid == 0xFFFF) {
-			printk(KERN_ERR "ali_audio: no codec attached ?\n");
-			kfree(codec);
-			break;
-		}
-
-		card->ac97_features = eid;
-		/* Now check the codec for useful features to make up for
-		   the dumbness of the ali5455 hardware engine */
-		if (!(eid & 0x0001))
-			printk(KERN_WARNING
-			       "ali_audio: only 48Khz playback available.\n");
-		else {
-			if (!ali_ac97_enable_variable_rate(codec)) {
-				printk(KERN_WARNING
-				       "ali_audio: Codec refused to allow VRA, using 48Khz only.\n");
-				card->ac97_features &= ~1;
-			}
-		}
-
-		/* Determine how many channels the codec(s) support   */
-		/*   - The primary codec always supports 2            */
-		/*   - If the codec supports AMAP, surround DACs will */
-		/*     automaticlly get assigned to slots.            */
-		/*     * Check for surround DACs and increment if     */
-		/*       found.                                       */
-		/*   - Else check if the codec is revision 2.2        */
-		/*     * If surround DACs exist, assign them to slots */
-		/*       and increment channel count.                 */
-
-		/* All of this only applies to ICH2 and above. ICH    */
-		/* and ICH0 only support 2 channels.  ICH2 will only  */
-		/* support multiple codecs in a "split audio" config. */
-		/* as described above.                                */
-
-		/* TODO: Remove all the debugging messages!           */
-
-		if ((eid & 0xc000) == 0)	/* primary codec */
-			total_channels += 2;
-		if ((codec->dev_mixer = register_sound_mixer(&ali_mixer_fops, -1)) < 0) {
-			printk(KERN_ERR "ali_audio: couldn't register mixer!\n");
-			kfree(codec);
-			break;
-		}
-		card->ac97_codec[num_ac97] = codec;
-	}
-	/* pick the minimum of channels supported by ICHx or codec(s) */
-	card->channels = (card->channels > total_channels) ? total_channels : card->channels;
-	return num_ac97;
-}
-
-static void __devinit ali_configure_clocking(void)
-{
-	struct ali_card *card;
-	struct ali_state *state;
-	struct dmabuf *dmabuf;
-	unsigned int i, offset, new_offset;
-	unsigned long flags;
-	card = devs;
-
-	/* We could try to set the clocking for multiple cards, but can you even have
-	 * more than one ali in a machine?  Besides, clocking is global, so unless
-	 * someone actually thinks more than one ali in a machine is possible and
-	 * decides to rewrite that little bit, setting the rate for more than one card
-	 * is a waste of time.
-	 */
-	if (card != NULL) {
-		state = card->states[0] = (struct ali_state *)
-		    kmalloc(sizeof(struct ali_state), GFP_KERNEL);
-		if (state == NULL)
-			return;
-		memset(state, 0, sizeof(struct ali_state));
-		dmabuf = &state->dmabuf;
-		dmabuf->write_channel = card->alloc_pcm_channel(card);
-		state->virt = 0;
-		state->card = card;
-		state->magic = ALI5455_STATE_MAGIC;
-		init_waitqueue_head(&dmabuf->wait);
-		mutex_init(&state->open_mutex);
-		dmabuf->fmt = ALI5455_FMT_STEREO | ALI5455_FMT_16BIT;
-		dmabuf->trigger = PCM_ENABLE_OUTPUT;
-		ali_set_dac_rate(state, 48000);
-		if (prog_dmabuf(state, 0) != 0)
-			goto config_out_nodmabuf;
-		
-		if (dmabuf->dmasize < 16384)
-			goto config_out;
-		
-		dmabuf->count = dmabuf->dmasize;
-		outb(31, card->iobase + dmabuf->write_channel->port + OFF_LVI);
-
-		local_irq_save(flags);
-		start_dac(state);
-		offset = ali_get_dma_addr(state, 0);
-		mdelay(50);
-		new_offset = ali_get_dma_addr(state, 0);
-		stop_dac(state);
-		
-		outb(2, card->iobase + dmabuf->write_channel->port + OFF_CR);
-		local_irq_restore(flags);
-
-		i = new_offset - offset;
-
-		if (i == 0)
-			goto config_out;
-		i = i / 4 * 20;
-		if (i > 48500 || i < 47500) {
-			clocking = clocking * clocking / i;
-		}
-config_out:
-		dealloc_dmabuf(state);
-config_out_nodmabuf:
-		state->card->free_pcm_channel(state->card, state->dmabuf. write_channel->num);
-		kfree(state);
-		card->states[0] = NULL;
-	}
-}
-
-/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
-   until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
-
-static int __devinit ali_probe(struct pci_dev *pci_dev,
-			       const struct pci_device_id *pci_id)
-{
-	struct ali_card *card;
-	if (pci_enable_device(pci_dev))
-		return -EIO;
-	if (pci_set_dma_mask(pci_dev, ALI5455_DMA_MASK)) {
-		printk(KERN_ERR "ali5455: architecture does not support"
-		       " 32bit PCI busmaster DMA\n");
-		return -ENODEV;
-	}
-
-	if ((card = kmalloc(sizeof(struct ali_card), GFP_KERNEL)) == NULL) {
-		printk(KERN_ERR "ali_audio: out of memory\n");
-		return -ENOMEM;
-	}
-	memset(card, 0, sizeof(*card));
-	card->initializing = 1;
-	card->iobase = pci_resource_start(pci_dev, 0);
-	card->pci_dev = pci_dev;
-	card->pci_id = pci_id->device;
-	card->irq = pci_dev->irq;
-	card->next = devs;
-	card->magic = ALI5455_CARD_MAGIC;
-#ifdef CONFIG_PM
-	card->pm_suspended = 0;
-#endif
-	spin_lock_init(&card->lock);
-	spin_lock_init(&card->ac97_lock);
-	devs = card;
-	pci_set_master(pci_dev);
-	printk(KERN_INFO "ali: %s found at IO 0x%04lx, IRQ %d\n",
-	       card_names[pci_id->driver_data], card->iobase, card->irq);
-	card->alloc_pcm_channel = ali_alloc_pcm_channel;
-	card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel;
-	card->alloc_rec_mic_channel = ali_alloc_rec_mic_channel;
-	card->alloc_codec_spdifout_channel = ali_alloc_codec_spdifout_channel;
-	card->alloc_controller_spdifout_channel = ali_alloc_controller_spdifout_channel;
-	card->free_pcm_channel = ali_free_pcm_channel;
-	card->channel[0].offset = 0;
-	card->channel[0].port = 0x40;
-	card->channel[0].num = 0;
-	card->channel[1].offset = 0;
-	card->channel[1].port = 0x50;
-	card->channel[1].num = 1;
-	card->channel[2].offset = 0;
-	card->channel[2].port = 0x60;
-	card->channel[2].num = 2;
-	card->channel[3].offset = 0;
-	card->channel[3].port = 0x70;
-	card->channel[3].num = 3;
-	card->channel[4].offset = 0;
-	card->channel[4].port = 0xb0;
-	card->channel[4].num = 4;
-	/* claim our iospace and irq */
-	request_region(card->iobase, 256, card_names[pci_id->driver_data]);
-	if (request_irq(card->irq, &ali_interrupt, IRQF_SHARED,
-			card_names[pci_id->driver_data], card)) {
-		printk(KERN_ERR "ali_audio: unable to allocate irq %d\n",
-		       card->irq);
-		release_region(card->iobase, 256);
-		kfree(card);
-		return -ENODEV;
-	}
-
-	if (ali_reset_5455(card) <= 0) {
-		unregister_sound_dsp(card->dev_audio);
-		release_region(card->iobase, 256);
-		free_irq(card->irq, card);
-		kfree(card);
-		return -ENODEV;
-	}
-
-	/* initialize AC97 codec and register /dev/mixer */
-	if (ali_ac97_init(card) < 0) {
-		release_region(card->iobase, 256);
-		free_irq(card->irq, card);
-		kfree(card);
-		return -ENODEV;
-	}
-	
-	pci_set_drvdata(pci_dev, card);
-	
-	if (clocking == 0) {
-		clocking = 48000;
-		ali_configure_clocking();
-	}
-
-	/* register /dev/dsp */
-	if ((card->dev_audio = register_sound_dsp(&ali_audio_fops, -1)) < 0) {
-		int i;
-		printk(KERN_ERR"ali_audio: couldn't register DSP device!\n");
-		release_region(card->iobase, 256);
-		free_irq(card->irq, card);
-		for (i = 0; i < NR_AC97; i++)
-			if (card->ac97_codec[i] != NULL) {
-				unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-				kfree(card->ac97_codec[i]);
-			}
-		kfree(card);
-		return -ENODEV;
-	}
-	card->initializing = 0;
-	return 0;
-}
-
-static void __devexit ali_remove(struct pci_dev *pci_dev)
-{
-	int i;
-	struct ali_card *card = pci_get_drvdata(pci_dev);
-	/* free hardware resources */
-	free_irq(card->irq, devs);
-	release_region(card->iobase, 256);
-	/* unregister audio devices */
-	for (i = 0; i < NR_AC97; i++)
-		if (card->ac97_codec[i] != NULL) {
-			unregister_sound_mixer(card->ac97_codec[i]->
-					       dev_mixer);
-			ac97_release_codec(card->ac97_codec[i]);
-			card->ac97_codec[i] = NULL;
-		}
-	unregister_sound_dsp(card->dev_audio);
-	kfree(card);
-}
-
-#ifdef CONFIG_PM
-static int ali_pm_suspend(struct pci_dev *dev, pm_message_t pm_state)
-{
-	struct ali_card *card = pci_get_drvdata(dev);
-	struct ali_state *state;
-	unsigned long flags;
-	struct dmabuf *dmabuf;
-	int i, num_ac97;
-
-	if (!card)
-		return 0;
-	spin_lock_irqsave(&card->lock, flags);
-	card->pm_suspended = 1;
-	for (i = 0; i < NR_HW_CH; i++) {
-		state = card->states[i];
-		if (!state)
-			continue;
-		/* this happens only if there are open files */
-		dmabuf = &state->dmabuf;
-		if (dmabuf->enable & DAC_RUNNING ||
-		    (dmabuf->count
-		     && (dmabuf->trigger & PCM_ENABLE_OUTPUT))) {
-			state->pm_saved_dac_rate = dmabuf->rate;
-			stop_dac(state);
-		} else {
-			state->pm_saved_dac_rate = 0;
-		}
-		if (dmabuf->enable & ADC_RUNNING) {
-			state->pm_saved_adc_rate = dmabuf->rate;
-			stop_adc(state);
-		} else {
-			state->pm_saved_adc_rate = 0;
-		}
-		dmabuf->ready = 0;
-		dmabuf->swptr = dmabuf->hwptr = 0;
-		dmabuf->count = dmabuf->total_bytes = 0;
-	}
-
-	spin_unlock_irqrestore(&card->lock, flags);
-	/* save mixer settings */
-	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-		struct ac97_codec *codec = card->ac97_codec[num_ac97];
-		if (!codec)
-			continue;
-		for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-			if ((supported_mixer(codec, i)) && (codec->read_mixer)) {
-				card->pm_saved_mixer_settings[i][num_ac97] = codec->read_mixer(codec, i);
-			}
-		}
-	}
-	pci_save_state(dev);	/* XXX do we need this? */
-	pci_disable_device(dev);	/* disable busmastering */
-	pci_set_power_state(dev, 3);	/* Zzz. */
-	return 0;
-}
-
-
-static int ali_pm_resume(struct pci_dev *dev)
-{
-	int num_ac97, i = 0;
-	struct ali_card *card = pci_get_drvdata(dev);
-	pci_enable_device(dev);
-	pci_restore_state(dev);
-	/* observation of a toshiba portege 3440ct suggests that the 
-	   hardware has to be more or less completely reinitialized from
-	   scratch after an apm suspend.  Works For Me.   -dan */
-	ali_ac97_random_init_stuff(card);
-	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-		struct ac97_codec *codec = card->ac97_codec[num_ac97];
-		/* check they haven't stolen the hardware while we were
-		   away */
-		if (!codec || !ali_ac97_exists(card, num_ac97)) {
-			if (num_ac97)
-				continue;
-			else
-				BUG();
-		}
-		if (!ali_ac97_probe_and_powerup(card, codec))
-			BUG();
-		if ((card->ac97_features & 0x0001)) {
-			/* at probe time we found we could do variable
-			   rates, but APM suspend has made it forget
-			   its magical powers */
-			if (!ali_ac97_enable_variable_rate(codec))
-				BUG();
-		}
-		/* we lost our mixer settings, so restore them */
-		for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-			if (supported_mixer(codec, i)) {
-				int val = card->pm_saved_mixer_settings[i][num_ac97];
-				codec->mixer_state[i] = val;
-				codec->write_mixer(codec, i,
-						   (val & 0xff),
-						   ((val >> 8) & 0xff));
-			}
-		}
-	}
-
-	/* we need to restore the sample rate from whatever it was */
-	for (i = 0; i < NR_HW_CH; i++) {
-		struct ali_state *state = card->states[i];
-		if (state) {
-			if (state->pm_saved_adc_rate)
-				ali_set_adc_rate(state, state->pm_saved_adc_rate);
-			if (state->pm_saved_dac_rate)
-				ali_set_dac_rate(state, state->pm_saved_dac_rate);
-		}
-	}
-
-	card->pm_suspended = 0;
-	/* any processes that were reading/writing during the suspend
-	   probably ended up here */
-	for (i = 0; i < NR_HW_CH; i++) {
-		struct ali_state *state = card->states[i];
-		if (state)
-			wake_up(&state->dmabuf.wait);
-	}
-	return 0;
-}
-#endif				/* CONFIG_PM */
-
-MODULE_AUTHOR("");
-MODULE_DESCRIPTION("ALI 5455 audio support");
-MODULE_LICENSE("GPL");
-module_param(clocking, int, 0);
-/* FIXME: bool? */
-module_param(strict_clocking, uint, 0);
-module_param(codec_pcmout_share_spdif_locked, uint, 0);
-module_param(codec_independent_spdif_locked, uint, 0);
-module_param(controller_pcmout_share_spdif_locked, uint, 0);
-module_param(controller_independent_spdif_locked, uint, 0);
-#define ALI5455_MODULE_NAME "ali5455"
-static struct pci_driver ali_pci_driver = {
-	.name		= ALI5455_MODULE_NAME,
-	.id_table	= ali_pci_tbl,
-	.probe		= ali_probe,
-	.remove		= __devexit_p(ali_remove),
-#ifdef CONFIG_PM
-	.suspend	= ali_pm_suspend,
-	.resume		= ali_pm_resume,
-#endif				/* CONFIG_PM */
-};
-
-static int __init ali_init_module(void)
-{
-	printk(KERN_INFO "ALI 5455 + AC97 Audio, version "
-	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
-
-	if (codec_independent_spdif_locked > 0) {
-		if (codec_independent_spdif_locked == 32000
-		    || codec_independent_spdif_locked == 44100
-		    || codec_independent_spdif_locked == 48000) {
-			printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_independent_spdif_locked);
-		} else {
-			printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-			codec_independent_spdif_locked = 0;
-		}
-	}
-	if (controller_independent_spdif_locked > 0) {
-		if (controller_independent_spdif_locked == 32000
-		    || controller_independent_spdif_locked == 44100
-		    || controller_independent_spdif_locked == 48000) {
-			printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", controller_independent_spdif_locked);
-		} else {
-			printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-			controller_independent_spdif_locked = 0;
-		}
-	}
-
-	if (codec_pcmout_share_spdif_locked > 0) {
-		if (codec_pcmout_share_spdif_locked == 32000
-		    || codec_pcmout_share_spdif_locked == 44100
-		    || codec_pcmout_share_spdif_locked == 48000) {
-			printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_pcmout_share_spdif_locked);
-		} else {
-			printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-			codec_pcmout_share_spdif_locked = 0;
-		}
-	}
-	if (controller_pcmout_share_spdif_locked > 0) {
-		if (controller_pcmout_share_spdif_locked == 32000
-		    || controller_pcmout_share_spdif_locked == 44100
-		    || controller_pcmout_share_spdif_locked == 48000) {
-			printk(KERN_INFO "ali_audio: Enabling controller S/PDIF at sample rate %dHz.\n", controller_pcmout_share_spdif_locked);
-		} else {
-			printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-			controller_pcmout_share_spdif_locked = 0;
-		}
-	}
-	return pci_register_driver(&ali_pci_driver);
-}
-
-static void __exit ali_cleanup_module(void)
-{
-	pci_unregister_driver(&ali_pci_driver);
-}
-
-module_init(ali_init_module);
-module_exit(ali_cleanup_module);
-/*
-Local Variables:
-c-basic-offset: 8
-End:
-*/
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c
deleted file mode 100644
index e379623..0000000
--- a/sound/oss/au1000.c
+++ /dev/null
@@ -1,2216 +0,0 @@
-/*
- *      au1000.c  --  Sound driver for Alchemy Au1000 MIPS Internet Edge
- *                    Processor.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * Module command line parameters:
- *
- *  Supported devices:
- *  /dev/dsp    standard OSS /dev/dsp device
- *  /dev/mixer  standard OSS /dev/mixer device
- *
- * Notes:
- *
- *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
- *     taken, slightly modified or not at all, from the ES1371 driver,
- *     so refer to the credits in es1371.c for those. The rest of the
- *     code (probe, open, read, write, the ISR, etc.) is new.
- *
- *  Revision history
- *    06.27.2001  Initial version
- *    03.20.2002  Added mutex locks around read/write methods, to prevent
- *                simultaneous access on SMP or preemptible kernels. Also
- *                removed the counter/pointer fragment aligning at the end
- *                of read/write methods [stevel].
- *    03.21.2002  Add support for coherent DMA on the audio read/write DMA
- *                channels [stevel].
- *
- */
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/init.h>
-#include <linux/page-flags.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1000_dma.h>
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#undef AU1000_DEBUG
-#undef AU1000_VERBOSE_DEBUG
-
-#define AU1000_MODULE_NAME "Au1000 audio"
-#define PFX AU1000_MODULE_NAME
-
-#ifdef AU1000_DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
-
-
-/* misc stuff */
-#define POLL_COUNT   0x5000
-#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
-
-/* Boot options */
-static int      vra = 0;	// 0 = no VRA, 1 = use VRA if codec supports it
-module_param(vra, bool, 0);
-MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
-
-
-/* --------------------------------------------------------------------- */
-
-struct au1000_state {
-	/* soundcore stuff */
-	int             dev_audio;
-
-#ifdef AU1000_DEBUG
-	/* debug /proc entry */
-	struct proc_dir_entry *ps;
-	struct proc_dir_entry *ac97_ps;
-#endif				/* AU1000_DEBUG */
-
-	struct ac97_codec codec;
-	unsigned        codec_base_caps;// AC'97 reg 00h, "Reset Register"
-	unsigned        codec_ext_caps;	// AC'97 reg 28h, "Extended Audio ID"
-	int             no_vra;	// do not use VRA
-
-	spinlock_t      lock;
-	struct mutex open_mutex;
-	struct mutex sem;
-	mode_t          open_mode;
-	wait_queue_head_t open_wait;
-
-	struct dmabuf {
-		unsigned int    dmanr;	// DMA Channel number
-		unsigned        sample_rate;	// Hz
-		unsigned src_factor;     // SRC interp/decimation (no vra)
-		unsigned        sample_size;	// 8 or 16
-		int             num_channels;	// 1 = mono, 2 = stereo, 4, 6
-		int dma_bytes_per_sample;// DMA bytes per audio sample frame
-		int user_bytes_per_sample;// User bytes per audio sample frame
-		int cnt_factor;          // user-to-DMA bytes per audio
-		//  sample frame
-		void           *rawbuf;
-		dma_addr_t      dmaaddr;
-		unsigned        buforder;
-		unsigned numfrag;        // # of DMA fragments in DMA buffer
-		unsigned        fragshift;
-		void           *nextIn;	// ptr to next-in to DMA buffer
-		void           *nextOut;// ptr to next-out from DMA buffer
-		int             count;	// current byte count in DMA buffer
-		unsigned        total_bytes;	// total bytes written or read
-		unsigned        error;	// over/underrun
-		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;       // user perception of fragment size
-		unsigned dma_fragsize;   // DMA (real) fragment size
-		unsigned dmasize;        // Total DMA buffer size
-		//   (mult. of DMA fragsize)
-		/* OSS stuff */
-		unsigned        mapped:1;
-		unsigned        ready:1;
-		unsigned        stopped:1;
-		unsigned        ossfragshift;
-		int             ossmaxfrags;
-		unsigned        subdivision;
-	} dma_dac      , dma_adc;
-} au1000_state;
-
-/* --------------------------------------------------------------------- */
-
-
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned        r = 0;
-
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void au1000_delay(int msec)
-{
-	unsigned long   tmo;
-	signed long     tmo2;
-
-	if (in_interrupt())
-		return;
-
-	tmo = jiffies + (msec * HZ) / 1000;
-	for (;;) {
-		tmo2 = tmo - jiffies;
-		if (tmo2 <= 0)
-			break;
-		schedule_timeout(tmo2);
-	}
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
-	struct au1000_state *s = (struct au1000_state *)codec->private_data;
-	unsigned long   flags;
-	u32             cmd;
-	u16             data;
-	int             i;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	for (i = 0; i < POLL_COUNT; i++)
-		if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-			break;
-	if (i == POLL_COUNT)
-		err("rdcodec: codec cmd pending expired!");
-
-	cmd = (u32) addr & AC97C_INDEX_MASK;
-	cmd |= AC97C_READ;	// read command
-	au_writel(cmd, AC97C_CMD);
-
-	/* now wait for the data */
-	for (i = 0; i < POLL_COUNT; i++)
-		if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-			break;
-	if (i == POLL_COUNT) {
-		err("rdcodec: read poll expired!");
-		return 0;
-	}
-
-	data = au_readl(AC97C_CMD) & 0xffff;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	return data;
-}
-
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
-	struct au1000_state *s = (struct au1000_state *)codec->private_data;
-	unsigned long   flags;
-	u32             cmd;
-	int             i;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	for (i = 0; i < POLL_COUNT; i++)
-		if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-			break;
-	if (i == POLL_COUNT)
-		err("wrcodec: codec cmd pending expired!");
-
-	cmd = (u32) addr & AC97C_INDEX_MASK;
-	cmd &= ~AC97C_READ;	// write command
-	cmd |= ((u32) data << AC97C_WD_BIT);	// OR in the data word
-	au_writel(cmd, AC97C_CMD);
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void waitcodec(struct ac97_codec *codec)
-{
-	u16             temp;
-	int             i;
-
-	/* codec_wait is used to wait for a ready state after
-	   an AC97C_RESET. */
-	au1000_delay(10);
-
-	// first poll the CODEC_READY tag bit
-	for (i = 0; i < POLL_COUNT; i++)
-		if (au_readl(AC97C_STATUS) & AC97C_READY)
-			break;
-	if (i == POLL_COUNT) {
-		err("waitcodec: CODEC_READY poll expired!");
-		return;
-	}
-	// get AC'97 powerdown control/status register
-	temp = rdcodec(codec, AC97_POWER_CONTROL);
-
-	// If anything is powered down, power'em up
-	if (temp & 0x7f00) {
-		// Power on
-		wrcodec(codec, AC97_POWER_CONTROL, 0);
-		au1000_delay(100);
-		// Reread
-		temp = rdcodec(codec, AC97_POWER_CONTROL);
-	}
-    
-	// Check if Codec REF,ANL,DAC,ADC ready
-	if ((temp & 0x7f0f) != 0x000f)
-		err("codec reg 26 status (0x%x) not ready!!", temp);
-}
-
-
-/* --------------------------------------------------------------------- */
-
-/* stop the ADC before calling */
-static void set_adc_rate(struct au1000_state *s, unsigned rate)
-{
-	struct dmabuf  *adc = &s->dma_adc;
-	struct dmabuf  *dac = &s->dma_dac;
-	unsigned        adc_rate, dac_rate;
-	u16             ac97_extstat;
-
-	if (s->no_vra) {
-		// calc SRC factor
-		adc->src_factor = ((96000 / rate) + 1) >> 1;
-		adc->sample_rate = 48000 / adc->src_factor;
-		return;
-	}
-
-	adc->src_factor = 1;
-
-	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-
-	rate = rate > 48000 ? 48000 : rate;
-
-	// enable VRA
-	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-		ac97_extstat | AC97_EXTSTAT_VRA);
-	// now write the sample rate
-	wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
-	// read it back for actual supported rate
-	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
-
-#ifdef AU1000_VERBOSE_DEBUG
-	dbg("%s: set to %d Hz", __FUNCTION__, adc_rate);
-#endif
-
-	// some codec's don't allow unequal DAC and ADC rates, in which case
-	// writing one rate reg actually changes both.
-	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
-	if (dac->num_channels > 2)
-		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
-	if (dac->num_channels > 4)
-		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
-
-	adc->sample_rate = adc_rate;
-	dac->sample_rate = dac_rate;
-}
-
-/* stop the DAC before calling */
-static void set_dac_rate(struct au1000_state *s, unsigned rate)
-{
-	struct dmabuf  *dac = &s->dma_dac;
-	struct dmabuf  *adc = &s->dma_adc;
-	unsigned        adc_rate, dac_rate;
-	u16             ac97_extstat;
-
-	if (s->no_vra) {
-		// calc SRC factor
-		dac->src_factor = ((96000 / rate) + 1) >> 1;
-		dac->sample_rate = 48000 / dac->src_factor;
-		return;
-	}
-
-	dac->src_factor = 1;
-
-	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-
-	rate = rate > 48000 ? 48000 : rate;
-
-	// enable VRA
-	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-		ac97_extstat | AC97_EXTSTAT_VRA);
-	// now write the sample rate
-	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
-	// I don't support different sample rates for multichannel,
-	// so make these channels the same.
-	if (dac->num_channels > 2)
-		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
-	if (dac->num_channels > 4)
-		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
-	// read it back for actual supported rate
-	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
-
-#ifdef AU1000_VERBOSE_DEBUG
-	dbg("%s: set to %d Hz", __FUNCTION__, dac_rate);
-#endif
-
-	// some codec's don't allow unequal DAC and ADC rates, in which case
-	// writing one rate reg actually changes both.
-	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
-
-	dac->sample_rate = dac_rate;
-	adc->sample_rate = adc_rate;
-}
-
-static void stop_dac(struct au1000_state *s)
-{
-	struct dmabuf  *db = &s->dma_dac;
-	unsigned long   flags;
-
-	if (db->stopped)
-		return;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	disable_dma(db->dmanr);
-
-	db->stopped = 1;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void  stop_adc(struct au1000_state *s)
-{
-	struct dmabuf  *db = &s->dma_adc;
-	unsigned long   flags;
-
-	if (db->stopped)
-		return;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	disable_dma(db->dmanr);
-
-	db->stopped = 1;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void set_xmit_slots(int num_channels)
-{
-	u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_XMIT_SLOTS_MASK;
-
-	switch (num_channels) {
-	case 1:		// mono
-	case 2:		// stereo, slots 3,4
-		ac97_config |= (0x3 << AC97C_XMIT_SLOTS_BIT);
-		break;
-	case 4:		// stereo with surround, slots 3,4,7,8
-		ac97_config |= (0x33 << AC97C_XMIT_SLOTS_BIT);
-		break;
-	case 6:		// stereo with surround and center/LFE, slots 3,4,6,7,8,9
-		ac97_config |= (0x7b << AC97C_XMIT_SLOTS_BIT);
-		break;
-	}
-
-	au_writel(ac97_config, AC97C_CONFIG);
-}
-
-static void     set_recv_slots(int num_channels)
-{
-	u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_RECV_SLOTS_MASK;
-
-	/*
-	 * Always enable slots 3 and 4 (stereo). Slot 6 is
-	 * optional Mic ADC, which I don't support yet.
-	 */
-	ac97_config |= (0x3 << AC97C_RECV_SLOTS_BIT);
-
-	au_writel(ac97_config, AC97C_CONFIG);
-}
-
-static void start_dac(struct au1000_state *s)
-{
-	struct dmabuf  *db = &s->dma_dac;
-	unsigned long   flags;
-	unsigned long   buf1, buf2;
-
-	if (!db->stopped)
-		return;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	au_readl(AC97C_STATUS);	// read status to clear sticky bits
-
-	// reset Buffer 1 and 2 pointers to nextOut and nextOut+dma_fragsize
-	buf1 = virt_to_phys(db->nextOut);
-	buf2 = buf1 + db->dma_fragsize;
-	if (buf2 >= db->dmaaddr + db->dmasize)
-		buf2 -= db->dmasize;
-
-	set_xmit_slots(db->num_channels);
-
-	init_dma(db->dmanr);
-	if (get_dma_active_buffer(db->dmanr) == 0) {
-		clear_dma_done0(db->dmanr);	// clear DMA done bit
-		set_dma_addr0(db->dmanr, buf1);
-		set_dma_addr1(db->dmanr, buf2);
-	} else {
-		clear_dma_done1(db->dmanr);	// clear DMA done bit
-		set_dma_addr1(db->dmanr, buf1);
-		set_dma_addr0(db->dmanr, buf2);
-	}
-	set_dma_count(db->dmanr, db->dma_fragsize>>1);
-	enable_dma_buffers(db->dmanr);
-
-	start_dma(db->dmanr);
-
-#ifdef AU1000_VERBOSE_DEBUG
-	dump_au1000_dma_channel(db->dmanr);
-#endif
-
-	db->stopped = 0;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_adc(struct au1000_state *s)
-{
-	struct dmabuf  *db = &s->dma_adc;
-	unsigned long   flags;
-	unsigned long   buf1, buf2;
-
-	if (!db->stopped)
-		return;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	au_readl(AC97C_STATUS);	// read status to clear sticky bits
-
-	// reset Buffer 1 and 2 pointers to nextIn and nextIn+dma_fragsize
-	buf1 = virt_to_phys(db->nextIn);
-	buf2 = buf1 + db->dma_fragsize;
-	if (buf2 >= db->dmaaddr + db->dmasize)
-		buf2 -= db->dmasize;
-
-	set_recv_slots(db->num_channels);
-
-	init_dma(db->dmanr);
-	if (get_dma_active_buffer(db->dmanr) == 0) {
-		clear_dma_done0(db->dmanr);	// clear DMA done bit
-		set_dma_addr0(db->dmanr, buf1);
-		set_dma_addr1(db->dmanr, buf2);
-	} else {
-		clear_dma_done1(db->dmanr);	// clear DMA done bit
-		set_dma_addr1(db->dmanr, buf1);
-		set_dma_addr0(db->dmanr, buf2);
-	}
-	set_dma_count(db->dmanr, db->dma_fragsize>>1);
-	enable_dma_buffers(db->dmanr);
-
-	start_dma(db->dmanr);
-
-#ifdef AU1000_VERBOSE_DEBUG
-	dump_au1000_dma_channel(db->dmanr);
-#endif
-
-	db->stopped = 0;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db)
-{
-	struct page    *page, *pend;
-
-	if (db->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(db->rawbuf +
-				    (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			ClearPageReserved(page);
-		dma_free_noncoherent(NULL,
-				PAGE_SIZE << db->buforder,
-				db->rawbuf,
-				db->dmaaddr);
-	}
-	db->rawbuf = db->nextIn = db->nextOut = NULL;
-	db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db)
-{
-	int             order;
-	unsigned user_bytes_per_sec;
-	unsigned        bufs;
-	struct page    *page, *pend;
-	unsigned        rate = db->sample_rate;
-
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER;
-		     order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf = dma_alloc_noncoherent(NULL,
-						PAGE_SIZE << order,
-						&db->dmaaddr,
-						0)))
-				break;
-		if (!db->rawbuf)
-			return -ENOMEM;
-		db->buforder = order;
-		/* now mark the pages as reserved;
-		   otherwise remap_pfn_range doesn't do what we want */
-		pend = virt_to_page(db->rawbuf +
-				    (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			SetPageReserved(page);
-	}
-
-	db->cnt_factor = 1;
-	if (db->sample_size == 8)
-		db->cnt_factor *= 2;
-	if (db->num_channels == 1)
-		db->cnt_factor *= 2;
-	db->cnt_factor *= db->src_factor;
-
-	db->count = 0;
-	db->nextIn = db->nextOut = db->rawbuf;
-
-	db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
-	db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
-					2 : db->num_channels);
-
-	user_bytes_per_sec = rate * db->user_bytes_per_sample;
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < user_bytes_per_sec)
-			db->fragshift = ld2(user_bytes_per_sec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(user_bytes_per_sec / 100 /
-				    (db->subdivision ? db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3;
-	}
-
-	db->fragsize = 1 << db->fragshift;
-	db->dma_fragsize = db->fragsize * db->cnt_factor;
-	db->numfrag = bufs / db->dma_fragsize;
-
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->fragsize = 1 << db->fragshift;
-		db->dma_fragsize = db->fragsize * db->cnt_factor;
-		db->numfrag = bufs / db->dma_fragsize;
-	}
-
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
-
-	db->dmasize = db->dma_fragsize * db->numfrag;
-	memset(db->rawbuf, 0, bufs);
-
-#ifdef AU1000_VERBOSE_DEBUG
-	dbg("rate=%d, samplesize=%d, channels=%d",
-	    rate, db->sample_size, db->num_channels);
-	dbg("fragsize=%d, cnt_factor=%d, dma_fragsize=%d",
-	    db->fragsize, db->cnt_factor, db->dma_fragsize);
-	dbg("numfrag=%d, dmasize=%d", db->numfrag, db->dmasize);
-#endif
-
-	db->ready = 1;
-	return 0;
-}
-
-static inline int prog_dmabuf_adc(struct au1000_state *s)
-{
-	stop_adc(s);
-	return prog_dmabuf(s, &s->dma_adc);
-
-}
-
-static inline int prog_dmabuf_dac(struct au1000_state *s)
-{
-	stop_dac(s);
-	return prog_dmabuf(s, &s->dma_dac);
-}
-
-
-/* hold spinlock for the following */
-static irqreturn_t dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct au1000_state *s = (struct au1000_state *) dev_id;
-	struct dmabuf  *dac = &s->dma_dac;
-	unsigned long   newptr;
-	u32 ac97c_stat, buff_done;
-
-	ac97c_stat = au_readl(AC97C_STATUS);
-#ifdef AU1000_VERBOSE_DEBUG
-	if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
-		dbg("AC97C status = 0x%08x", ac97c_stat);
-#endif
-
-	if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) {
-		/* fastpath out, to ease interrupt sharing */
-		return IRQ_HANDLED;
-	}
-
-	spin_lock(&s->lock);
-	
-	if (buff_done != (DMA_D0 | DMA_D1)) {
-		dac->nextOut += dac->dma_fragsize;
-		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-			dac->nextOut -= dac->dmasize;
-
-		/* update playback pointers */
-		newptr = virt_to_phys(dac->nextOut) + dac->dma_fragsize;
-		if (newptr >= dac->dmaaddr + dac->dmasize)
-			newptr -= dac->dmasize;
-
-		dac->count -= dac->dma_fragsize;
-		dac->total_bytes += dac->dma_fragsize;
-
-		if (dac->count <= 0) {
-#ifdef AU1000_VERBOSE_DEBUG
-			dbg("dac underrun");
-#endif
-			spin_unlock(&s->lock);
-			stop_dac(s);
-			spin_lock(&s->lock);
-			dac->count = 0;
-			dac->nextIn = dac->nextOut;
-		} else if (buff_done == DMA_D0) {
-			clear_dma_done0(dac->dmanr);	// clear DMA done bit
-			set_dma_count0(dac->dmanr, dac->dma_fragsize>>1);
-			set_dma_addr0(dac->dmanr, newptr);
-			enable_dma_buffer0(dac->dmanr);	// reenable
-		} else {
-			clear_dma_done1(dac->dmanr);	// clear DMA done bit
-			set_dma_count1(dac->dmanr, dac->dma_fragsize>>1);
-			set_dma_addr1(dac->dmanr, newptr);
-			enable_dma_buffer1(dac->dmanr);	// reenable
-		}
-	} else {
-		// both done bits set, we missed an interrupt
-		spin_unlock(&s->lock);
-		stop_dac(s);
-		spin_lock(&s->lock);
-
-		dac->nextOut += 2*dac->dma_fragsize;
-		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-			dac->nextOut -= dac->dmasize;
-
-		dac->count -= 2*dac->dma_fragsize;
-		dac->total_bytes += 2*dac->dma_fragsize;
-
-		if (dac->count > 0) {
-			spin_unlock(&s->lock);
-			start_dac(s);
-			spin_lock(&s->lock);
-		}
-	}
-
-	/* wake up anybody listening */
-	if (waitqueue_active(&dac->wait))
-		wake_up(&dac->wait);
-
-	spin_unlock(&s->lock);
-
-	return IRQ_HANDLED;
-}
-
-
-static irqreturn_t adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct au1000_state *s = (struct au1000_state *) dev_id;
-	struct dmabuf  *adc = &s->dma_adc;
-	unsigned long   newptr;
-	u32 ac97c_stat, buff_done;
-
-	ac97c_stat = au_readl(AC97C_STATUS);
-#ifdef AU1000_VERBOSE_DEBUG
-	if (ac97c_stat & (AC97C_RU | AC97C_RO))
-		dbg("AC97C status = 0x%08x", ac97c_stat);
-#endif
-
-	if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) {
-		/* fastpath out, to ease interrupt sharing */
-		return IRQ_HANDLED;
-	}
-
-	spin_lock(&s->lock);
-	
-	if (buff_done != (DMA_D0 | DMA_D1)) {
-		if (adc->count + adc->dma_fragsize > adc->dmasize) {
-			// Overrun. Stop ADC and log the error
-			spin_unlock(&s->lock);
-			stop_adc(s);
-			adc->error++;
-			err("adc overrun");
-			return IRQ_NONE;
-		}
-
-		adc->nextIn += adc->dma_fragsize;
-		if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-			adc->nextIn -= adc->dmasize;
-
-		/* update capture pointers */
-		newptr = virt_to_phys(adc->nextIn) + adc->dma_fragsize;
-		if (newptr >= adc->dmaaddr + adc->dmasize)
-			newptr -= adc->dmasize;
-
-		adc->count += adc->dma_fragsize;
-		adc->total_bytes += adc->dma_fragsize;
-
-		if (buff_done == DMA_D0) {
-			clear_dma_done0(adc->dmanr);	// clear DMA done bit
-			set_dma_count0(adc->dmanr, adc->dma_fragsize>>1);
-			set_dma_addr0(adc->dmanr, newptr);
-			enable_dma_buffer0(adc->dmanr);	// reenable
-		} else {
-			clear_dma_done1(adc->dmanr);	// clear DMA done bit
-			set_dma_count1(adc->dmanr, adc->dma_fragsize>>1);
-			set_dma_addr1(adc->dmanr, newptr);
-			enable_dma_buffer1(adc->dmanr);	// reenable
-		}
-	} else {
-		// both done bits set, we missed an interrupt
-		spin_unlock(&s->lock);
-		stop_adc(s);
-		spin_lock(&s->lock);
-		
-		if (adc->count + 2*adc->dma_fragsize > adc->dmasize) {
-			// Overrun. Log the error
-			adc->error++;
-			err("adc overrun");
-			spin_unlock(&s->lock);
-			return IRQ_NONE;
-		}
-
-		adc->nextIn += 2*adc->dma_fragsize;
-		if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-			adc->nextIn -= adc->dmasize;
-
-		adc->count += 2*adc->dma_fragsize;
-		adc->total_bytes += 2*adc->dma_fragsize;
-		
-		spin_unlock(&s->lock);
-		start_adc(s);
-		spin_lock(&s->lock);
-	}
-
-	/* wake up anybody listening */
-	if (waitqueue_active(&adc->wait))
-		wake_up(&adc->wait);
-
-	spin_unlock(&s->lock);
-
-	return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static loff_t au1000_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-
-static int au1000_open_mixdev(struct inode *inode, struct file *file)
-{
-	file->private_data = &au1000_state;
-	return nonseekable_open(inode, file);
-}
-
-static int au1000_release_mixdev(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
-                        unsigned long arg)
-{
-	return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int au1000_ioctl_mixdev(struct inode *inode, struct file *file,
-			       unsigned int cmd, unsigned long arg)
-{
-	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	struct ac97_codec *codec = &s->codec;
-
-	return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const */ struct file_operations au1000_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= au1000_llseek,
-	.ioctl		= au1000_ioctl_mixdev,
-	.open		= au1000_open_mixdev,
-	.release	= au1000_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct au1000_state *s, int nonblock)
-{
-	unsigned long   flags;
-	int             count, tmo;
-
-	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
-		return 0;
-
-	for (;;) {
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-			break;
-		if (nonblock)
-			return -EBUSY;
-		tmo = 1000 * count / (s->no_vra ?
-				      48000 : s->dma_dac.sample_rate);
-		tmo /= s->dma_dac.dma_bytes_per_sample;
-		au1000_delay(tmo);
-	}
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline u8 S16_TO_U8(s16 ch)
-{
-	return (u8) (ch >> 8) + 0x80;
-}
-static inline s16 U8_TO_S16(u8 ch)
-{
-	return (s16) (ch - 0x80) << 8;
-}
-
-/*
- * Translates user samples to dma buffer suitable for AC'97 DAC data:
- *     If mono, copy left channel to right channel in dma buffer.
- *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
- *     If interpolating (no VRA), duplicate every audio frame src_factor times.
- */
-static int translate_from_user(struct dmabuf *db,
-			       char* dmabuf,
-			       char* userbuf,
-			       int dmacount)
-{
-	int             sample, i;
-	int             interp_bytes_per_sample;
-	int             num_samples;
-	int             mono = (db->num_channels == 1);
-	char            usersample[12];
-	s16             ch, dmasample[6];
-
-	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
-		// no translation necessary, just copy
-		if (copy_from_user(dmabuf, userbuf, dmacount))
-			return -EFAULT;
-		return dmacount;
-	}
-
-	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
-	num_samples = dmacount / interp_bytes_per_sample;
-
-	for (sample = 0; sample < num_samples; sample++) {
-		if (copy_from_user(usersample, userbuf,
-				   db->user_bytes_per_sample)) {
-			dbg("%s: fault", __FUNCTION__);
-			return -EFAULT;
-		}
-
-		for (i = 0; i < db->num_channels; i++) {
-			if (db->sample_size == 8)
-				ch = U8_TO_S16(usersample[i]);
-			else
-				ch = *((s16 *) (&usersample[i * 2]));
-			dmasample[i] = ch;
-			if (mono)
-				dmasample[i + 1] = ch;	// right channel
-		}
-
-		// duplicate every audio frame src_factor times
-		for (i = 0; i < db->src_factor; i++)
-			memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
-
-		userbuf += db->user_bytes_per_sample;
-		dmabuf += interp_bytes_per_sample;
-	}
-
-	return num_samples * interp_bytes_per_sample;
-}
-
-/*
- * Translates AC'97 ADC samples to user buffer:
- *     If mono, send only left channel to user buffer.
- *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
- *     If decimating (no VRA), skip over src_factor audio frames.
- */
-static int translate_to_user(struct dmabuf *db,
-			     char* userbuf,
-			     char* dmabuf,
-			     int dmacount)
-{
-	int             sample, i;
-	int             interp_bytes_per_sample;
-	int             num_samples;
-	int             mono = (db->num_channels == 1);
-	char            usersample[12];
-
-	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
-		// no translation necessary, just copy
-		if (copy_to_user(userbuf, dmabuf, dmacount))
-			return -EFAULT;
-		return dmacount;
-	}
-
-	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
-	num_samples = dmacount / interp_bytes_per_sample;
-
-	for (sample = 0; sample < num_samples; sample++) {
-		for (i = 0; i < db->num_channels; i++) {
-			if (db->sample_size == 8)
-				usersample[i] =
-					S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
-			else
-				*((s16 *) (&usersample[i * 2])) =
-					*((s16 *) (&dmabuf[i * 2]));
-		}
-
-		if (copy_to_user(userbuf, usersample,
-				 db->user_bytes_per_sample)) {
-			dbg("%s: fault", __FUNCTION__);
-			return -EFAULT;
-		}
-
-		userbuf += db->user_bytes_per_sample;
-		dmabuf += interp_bytes_per_sample;
-	}
-
-	return num_samples * interp_bytes_per_sample;
-}
-
-/*
- * Copy audio data to/from user buffer from/to dma buffer, taking care
- * that we wrap when reading/writing the dma buffer. Returns actual byte
- * count written to or read from the dma buffer.
- */
-static int copy_dmabuf_user(struct dmabuf *db, char* userbuf,
-			    int count, int to_user)
-{
-	char           *bufptr = to_user ? db->nextOut : db->nextIn;
-	char           *bufend = db->rawbuf + db->dmasize;
-	int             cnt, ret;
-
-	if (bufptr + count > bufend) {
-		int             partial = (int) (bufend - bufptr);
-		if (to_user) {
-			if ((cnt = translate_to_user(db, userbuf,
-						     bufptr, partial)) < 0)
-				return cnt;
-			ret = cnt;
-			if ((cnt = translate_to_user(db, userbuf + partial,
-						     db->rawbuf,
-						     count - partial)) < 0)
-				return cnt;
-			ret += cnt;
-		} else {
-			if ((cnt = translate_from_user(db, bufptr, userbuf,
-						       partial)) < 0)
-				return cnt;
-			ret = cnt;
-			if ((cnt = translate_from_user(db, db->rawbuf,
-						       userbuf + partial,
-						       count - partial)) < 0)
-				return cnt;
-			ret += cnt;
-		}
-	} else {
-		if (to_user)
-			ret = translate_to_user(db, userbuf, bufptr, count);
-		else
-			ret = translate_from_user(db, bufptr, userbuf, count);
-	}
-
-	return ret;
-}
-
-
-static ssize_t au1000_read(struct file *file, char *buffer,
-			   size_t count, loff_t *ppos)
-{
-	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	struct dmabuf  *db = &s->dma_adc;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t         ret;
-	unsigned long   flags;
-	int             cnt, usercnt, avail;
-
-	if (db->mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-
-	count *= db->cnt_factor;
-
-	mutex_lock(&s->sem);
-	add_wait_queue(&db->wait, &wait);
-
-	while (count > 0) {
-		// wait for samples in ADC dma buffer
-		do {
-			if (db->stopped)
-				start_adc(s);
-			spin_lock_irqsave(&s->lock, flags);
-			avail = db->count;
-			if (avail <= 0)
-				__set_current_state(TASK_INTERRUPTIBLE);
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (avail <= 0) {
-				if (file->f_flags & O_NONBLOCK) {
-					if (!ret)
-						ret = -EAGAIN;
-					goto out;
-				}
-				mutex_unlock(&s->sem);
-				schedule();
-				if (signal_pending(current)) {
-					if (!ret)
-						ret = -ERESTARTSYS;
-					goto out2;
-				}
-				mutex_lock(&s->sem);
-			}
-		} while (avail <= 0);
-
-		// copy from nextOut to user
-		if ((cnt = copy_dmabuf_user(db, buffer,
-					    count > avail ?
-					    avail : count, 1)) < 0) {
-			if (!ret)
-				ret = -EFAULT;
-			goto out;
-		}
-
-		spin_lock_irqsave(&s->lock, flags);
-		db->count -= cnt;
-		db->nextOut += cnt;
-		if (db->nextOut >= db->rawbuf + db->dmasize)
-			db->nextOut -= db->dmasize;
-		spin_unlock_irqrestore(&s->lock, flags);
-
-		count -= cnt;
-		usercnt = cnt / db->cnt_factor;
-		buffer += usercnt;
-		ret += usercnt;
-	}			// while (count > 0)
-
-out:
-	mutex_unlock(&s->sem);
-out2:
-	remove_wait_queue(&db->wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-static ssize_t au1000_write(struct file *file, const char *buffer,
-	     		    size_t count, loff_t * ppos)
-{
-	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	struct dmabuf  *db = &s->dma_dac;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t         ret = 0;
-	unsigned long   flags;
-	int             cnt, usercnt, avail;
-
-#ifdef AU1000_VERBOSE_DEBUG
-	dbg("write: count=%d", count);
-#endif
-
-	if (db->mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-
-	count *= db->cnt_factor;
-
-	mutex_lock(&s->sem);
-	add_wait_queue(&db->wait, &wait);
-
-	while (count > 0) {
-		// wait for space in playback buffer
-		do {
-			spin_lock_irqsave(&s->lock, flags);
-			avail = (int) db->dmasize - db->count;
-			if (avail <= 0)
-				__set_current_state(TASK_INTERRUPTIBLE);
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (avail <= 0) {
-				if (file->f_flags & O_NONBLOCK) {
-					if (!ret)
-						ret = -EAGAIN;
-					goto out;
-				}
-				mutex_unlock(&s->sem);
-				schedule();
-				if (signal_pending(current)) {
-					if (!ret)
-						ret = -ERESTARTSYS;
-					goto out2;
-				}
-				mutex_lock(&s->sem);
-			}
-		} while (avail <= 0);
-
-		// copy from user to nextIn
-		if ((cnt = copy_dmabuf_user(db, (char *) buffer,
-					    count > avail ?
-					    avail : count, 0)) < 0) {
-			if (!ret)
-				ret = -EFAULT;
-			goto out;
-		}
-
-		spin_lock_irqsave(&s->lock, flags);
-		db->count += cnt;
-		db->nextIn += cnt;
-		if (db->nextIn >= db->rawbuf + db->dmasize)
-			db->nextIn -= db->dmasize;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (db->stopped)
-			start_dac(s);
-
-		count -= cnt;
-		usercnt = cnt / db->cnt_factor;
-		buffer += usercnt;
-		ret += usercnt;
-	}			// while (count > 0)
-
-out:
-	mutex_unlock(&s->sem);
-out2:
-	remove_wait_queue(&db->wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int au1000_poll(struct file *file,
-				struct poll_table_struct *wait)
-{
-	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	unsigned long   flags;
-	unsigned int    mask = 0;
-
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready)
-			return 0;
-		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready)
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-
-	spin_lock_irqsave(&s->lock, flags);
-	
-	if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >=
-			    (signed)s->dma_dac.dma_fragsize) 
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed) s->dma_dac.dmasize >=
-			    s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int au1000_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	struct dmabuf  *db;
-	unsigned long   size;
-	int ret = 0;
-
-	dbg("%s", __FUNCTION__);
-    
-	lock_kernel();
-	mutex_lock(&s->sem);
-	if (vma->vm_flags & VM_WRITE)
-		db = &s->dma_dac;
-	else if (vma->vm_flags & VM_READ)
-		db = &s->dma_adc;
-	else {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (vma->vm_pgoff != 0) {
-		ret = -EINVAL;
-		goto out;
-	}
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder)) {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(db->rawbuf),
-			     size, vma->vm_page_prot)) {
-		ret = -EAGAIN;
-		goto out;
-	}
-	vma->vm_flags &= ~VM_IO;
-	db->mapped = 1;
-out:
-	mutex_unlock(&s->sem);
-	unlock_kernel();
-	return ret;
-}
-
-
-#ifdef AU1000_VERBOSE_DEBUG
-static struct ioctl_str_t {
-	unsigned int    cmd;
-	const char     *str;
-} ioctl_str[] = {
-	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
-	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
-	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
-	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
-	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
-	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
-	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
-	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
-	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
-	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
-	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
-	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
-	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
-	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
-	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
-	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
-	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
-	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
-	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
-	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
-	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
-	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
-	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
-	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
-	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
-	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
-	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
-	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
-	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
-	{OSS_GETVERSION, "OSS_GETVERSION"},
-	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
-	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
-	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
-	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
-};
-#endif
-
-// Need to hold a spin-lock before calling this!
-static int dma_count_done(struct dmabuf *db)
-{
-	if (db->stopped)
-		return 0;
-
-	return db->dma_fragsize - get_dma_residue(db->dmanr);
-}
-
-
-static int au1000_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg)
-{
-	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	unsigned long   flags;
-	audio_buf_info  abinfo;
-	count_info      cinfo;
-	int             count;
-	int             val, mapped, ret, diff;
-
-	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-
-#ifdef AU1000_VERBOSE_DEBUG
-	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
-		if (ioctl_str[count].cmd == cmd)
-			break;
-	}
-	if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
-		dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg);
-	else
-		dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg);
-#endif
-
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, (int *) arg);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s, file->f_flags & O_NONBLOCK);
-		return 0;
-
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
-
-	case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq();
-			s->dma_dac.count = s->dma_dac.total_bytes = 0;
-			s->dma_dac.nextIn = s->dma_dac.nextOut =
-				s->dma_dac.rawbuf;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq();
-			s->dma_adc.count = s->dma_adc.total_bytes = 0;
-			s->dma_adc.nextIn = s->dma_adc.nextOut =
-				s->dma_adc.rawbuf;
-		}
-		return 0;
-
-	case SNDCTL_DSP_SPEED:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (val >= 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				set_adc_rate(s, val);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				set_dac_rate(s, val);
-			}
-			if (s->open_mode & FMODE_READ)
-				if ((ret = prog_dmabuf_adc(s)))
-					return ret;
-			if (s->open_mode & FMODE_WRITE)
-				if ((ret = prog_dmabuf_dac(s)))
-					return ret;
-		}
-		return put_user((file->f_mode & FMODE_READ) ?
-				s->dma_adc.sample_rate :
-				s->dma_dac.sample_rate,
-				(int *)arg);
-
-	case SNDCTL_DSP_STEREO:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.num_channels = val ? 2 : 1;
-			if ((ret = prog_dmabuf_adc(s)))
-				return ret;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.num_channels = val ? 2 : 1;
-			if (s->codec_ext_caps & AC97_EXT_DACS) {
-				// disable surround and center/lfe in AC'97
-				u16 ext_stat = rdcodec(&s->codec,
-						       AC97_EXTENDED_STATUS);
-				wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-					ext_stat | (AC97_EXTSTAT_PRI |
-						    AC97_EXTSTAT_PRJ |
-						    AC97_EXTSTAT_PRK));
-			}
-			if ((ret = prog_dmabuf_dac(s)))
-				return ret;
-		}
-		return 0;
-
-	case SNDCTL_DSP_CHANNELS:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (val != 0) {
-			if (file->f_mode & FMODE_READ) {
-				if (val < 0 || val > 2)
-					return -EINVAL;
-				stop_adc(s);
-				s->dma_adc.num_channels = val;
-				if ((ret = prog_dmabuf_adc(s)))
-					return ret;
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				switch (val) {
-				case 1:
-				case 2:
-					break;
-				case 3:
-				case 5:
-					return -EINVAL;
-				case 4:
-					if (!(s->codec_ext_caps &
-					      AC97_EXTID_SDAC))
-						return -EINVAL;
-					break;
-				case 6:
-					if ((s->codec_ext_caps &
-					     AC97_EXT_DACS) != AC97_EXT_DACS)
-						return -EINVAL;
-					break;
-				default:
-					return -EINVAL;
-				}
-
-				stop_dac(s);
-				if (val <= 2 &&
-				    (s->codec_ext_caps & AC97_EXT_DACS)) {
-					// disable surround and center/lfe
-					// channels in AC'97
-					u16             ext_stat =
-						rdcodec(&s->codec,
-							AC97_EXTENDED_STATUS);
-					wrcodec(&s->codec,
-						AC97_EXTENDED_STATUS,
-						ext_stat | (AC97_EXTSTAT_PRI |
-							    AC97_EXTSTAT_PRJ |
-							    AC97_EXTSTAT_PRK));
-				} else if (val >= 4) {
-					// enable surround, center/lfe
-					// channels in AC'97
-					u16             ext_stat =
-						rdcodec(&s->codec,
-							AC97_EXTENDED_STATUS);
-					ext_stat &= ~AC97_EXTSTAT_PRJ;
-					if (val == 6)
-						ext_stat &=
-							~(AC97_EXTSTAT_PRI |
-							  AC97_EXTSTAT_PRK);
-					wrcodec(&s->codec,
-						AC97_EXTENDED_STATUS,
-						ext_stat);
-				}
-
-				s->dma_dac.num_channels = val;
-				if ((ret = prog_dmabuf_dac(s)))
-					return ret;
-			}
-		}
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_GETFMTS:	/* Returns a mask */
-		return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
-
-	case SNDCTL_DSP_SETFMT:	/* Selects ONE fmt */
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				if (val == AFMT_S16_LE)
-					s->dma_adc.sample_size = 16;
-				else {
-					val = AFMT_U8;
-					s->dma_adc.sample_size = 8;
-				}
-				if ((ret = prog_dmabuf_adc(s)))
-					return ret;
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				if (val == AFMT_S16_LE)
-					s->dma_dac.sample_size = 16;
-				else {
-					val = AFMT_U8;
-					s->dma_dac.sample_size = 8;
-				}
-				if ((ret = prog_dmabuf_dac(s)))
-					return ret;
-			}
-		} else {
-			if (file->f_mode & FMODE_READ)
-				val = (s->dma_adc.sample_size == 16) ?
-					AFMT_S16_LE : AFMT_U8;
-			else
-				val = (s->dma_dac.sample_size == 16) ?
-					AFMT_S16_LE : AFMT_U8;
-		}
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_POST:
-		return 0;
-
-	case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		spin_lock_irqsave(&s->lock, flags);
-		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
-			val |= PCM_ENABLE_OUTPUT;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT)
-				start_adc(s);
-			else
-				stop_adc(s);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT)
-				start_dac(s);
-			else
-				stop_dac(s);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		abinfo.fragsize = s->dma_dac.fragsize;
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		count -= dma_count_done(&s->dma_dac);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		abinfo.bytes = (s->dma_dac.dmasize - count) /
-			s->dma_dac.cnt_factor;
-		abinfo.fragstotal = s->dma_dac.numfrag;
-		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-#ifdef AU1000_VERBOSE_DEBUG
-		dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments);
-#endif
-		return copy_to_user((void *) arg, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		abinfo.fragsize = s->dma_adc.fragsize;
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_adc.count;
-		count += dma_count_done(&s->dma_adc);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		abinfo.bytes = count / s->dma_adc.cnt_factor;
-		abinfo.fragstotal = s->dma_adc.numfrag;
-		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
-		return copy_to_user((void *) arg, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_NONBLOCK:
-		file->f_flags |= O_NONBLOCK;
-		return 0;
-
-	case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		count -= dma_count_done(&s->dma_dac);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		count /= s->dma_dac.cnt_factor;
-		return put_user(count, (int *) arg);
-
-	case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		cinfo.bytes = s->dma_adc.total_bytes;
-		count = s->dma_adc.count;
-		if (!s->dma_adc.stopped) {
-			diff = dma_count_done(&s->dma_adc);
-			count += diff;
-			cinfo.bytes += diff;
-			cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
-				s->dma_adc.dmaaddr;
-		} else
-			cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
-				s->dma_adc.dmaaddr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		cinfo.blocks = count >> s->dma_adc.fragshift;
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		cinfo.bytes = s->dma_dac.total_bytes;
-		count = s->dma_dac.count;
-		if (!s->dma_dac.stopped) {
-			diff = dma_count_done(&s->dma_dac);
-			count -= diff;
-			cinfo.bytes += diff;
-			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
-				s->dma_dac.dmaaddr;
-		} else
-			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
-				s->dma_dac.dmaaddr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		cinfo.blocks = count >> s->dma_dac.fragshift;
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE)
-			return put_user(s->dma_dac.fragsize, (int *) arg);
-		else
-			return put_user(s->dma_adc.fragsize, (int *) arg);
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-			if ((ret = prog_dmabuf_adc(s)))
-				return ret;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.ossfragshift = val & 0xffff;
-			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac.ossfragshift < 4)
-				s->dma_dac.ossfragshift = 4;
-			if (s->dma_dac.ossfragshift > 15)
-				s->dma_dac.ossfragshift = 15;
-			if (s->dma_dac.ossmaxfrags < 4)
-				s->dma_dac.ossmaxfrags = 4;
-			if ((ret = prog_dmabuf_dac(s)))
-				return ret;
-		}
-		return 0;
-
-	case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-			return -EINVAL;
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.subdivision = val;
-			if ((ret = prog_dmabuf_adc(s)))
-				return ret;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.subdivision = val;
-			if ((ret = prog_dmabuf_dac(s)))
-				return ret;
-		}
-		return 0;
-
-	case SOUND_PCM_READ_RATE:
-		return put_user((file->f_mode & FMODE_READ) ?
-				s->dma_adc.sample_rate :
-				s->dma_dac.sample_rate,
-				(int *)arg);
-
-	case SOUND_PCM_READ_CHANNELS:
-		if (file->f_mode & FMODE_READ)
-			return put_user(s->dma_adc.num_channels, (int *)arg);
-		else
-			return put_user(s->dma_dac.num_channels, (int *)arg);
-
-	case SOUND_PCM_READ_BITS:
-		if (file->f_mode & FMODE_READ)
-			return put_user(s->dma_adc.sample_size, (int *)arg);
-		else
-			return put_user(s->dma_dac.sample_size, (int *)arg);
-
-	case SOUND_PCM_WRITE_FILTER:
-	case SNDCTL_DSP_SETSYNCRO:
-	case SOUND_PCM_READ_FILTER:
-		return -EINVAL;
-	}
-
-	return mixdev_ioctl(&s->codec, cmd, arg);
-}
-
-
-static int  au1000_open(struct inode *inode, struct file *file)
-{
-	int             minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	struct au1000_state *s = &au1000_state;
-	int             ret;
-
-#ifdef AU1000_VERBOSE_DEBUG
-	if (file->f_flags & O_NONBLOCK)
-		dbg("%s: non-blocking", __FUNCTION__);
-	else
-		dbg("%s: blocking", __FUNCTION__);
-#endif
-	
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & file->f_mode) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-
-	stop_dac(s);
-	stop_adc(s);
-
-	if (file->f_mode & FMODE_READ) {
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
-		s->dma_adc.num_channels = 1;
-		s->dma_adc.sample_size = 8;
-		set_adc_rate(s, 8000);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->dma_adc.sample_size = 16;
-	}
-
-	if (file->f_mode & FMODE_WRITE) {
-		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
-		s->dma_dac.num_channels = 1;
-		s->dma_dac.sample_size = 8;
-		set_dac_rate(s, 8000);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->dma_dac.sample_size = 16;
-	}
-
-	if (file->f_mode & FMODE_READ) {
-		if ((ret = prog_dmabuf_adc(s)))
-			return ret;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if ((ret = prog_dmabuf_dac(s)))
-			return ret;
-	}
-
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	mutex_unlock(&s->open_mutex);
-	mutex_init(&s->sem);
-	return nonseekable_open(inode, file);
-}
-
-static int au1000_release(struct inode *inode, struct file *file)
-{
-	struct au1000_state *s = (struct au1000_state *)file->private_data;
-
-	lock_kernel();
-	
-	if (file->f_mode & FMODE_WRITE) {
-		unlock_kernel();
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-		lock_kernel();
-	}
-
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-		dealloc_dmabuf(s, &s->dma_dac);
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-	}
-	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
-	mutex_unlock(&s->open_mutex);
-	wake_up(&s->open_wait);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const */ struct file_operations au1000_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= au1000_llseek,
-	.read		= au1000_read,
-	.write		= au1000_write,
-	.poll		= au1000_poll,
-	.ioctl		= au1000_ioctl,
-	.mmap		= au1000_mmap,
-	.open		= au1000_open,
-	.release	= au1000_release,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef AU1000_DEBUG
-static int proc_au1000_dump(char *buf, char **start, off_t fpos,
-			    int length, int *eof, void *data)
-{
-	struct au1000_state *s = &au1000_state;
-	int             cnt, len = 0;
-
-	/* print out header */
-	len += sprintf(buf + len, "\n\t\tAU1000 Audio Debug\n\n");
-
-	// print out digital controller state
-	len += sprintf(buf + len, "AU1000 Audio Controller registers\n");
-	len += sprintf(buf + len, "---------------------------------\n");
-	len += sprintf (buf + len, "AC97C_CONFIG = %08x\n",
-			au_readl(AC97C_CONFIG));
-	len += sprintf (buf + len, "AC97C_STATUS = %08x\n",
-			au_readl(AC97C_STATUS));
-	len += sprintf (buf + len, "AC97C_CNTRL  = %08x\n",
-			au_readl(AC97C_CNTRL));
-
-	/* print out CODEC state */
-	len += sprintf(buf + len, "\nAC97 CODEC registers\n");
-	len += sprintf(buf + len, "----------------------\n");
-	for (cnt = 0; cnt <= 0x7e; cnt += 2)
-		len += sprintf(buf + len, "reg %02x = %04x\n",
-			       cnt, rdcodec(&s->codec, cnt));
-
-	if (fpos >= len) {
-		*start = buf;
-		*eof = 1;
-		return 0;
-	}
-	*start = buf + fpos;
-	if ((len -= fpos) > length)
-		return length;
-	*eof = 1;
-	return len;
-
-}
-#endif /* AU1000_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
-MODULE_DESCRIPTION("Au1000 Audio Driver");
-
-/* --------------------------------------------------------------------- */
-
-static int __devinit au1000_probe(void)
-{
-	struct au1000_state *s = &au1000_state;
-	int             val;
-#ifdef AU1000_DEBUG
-	char            proc_str[80];
-#endif
-
-	memset(s, 0, sizeof(struct au1000_state));
-
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac.wait);
-	init_waitqueue_head(&s->open_wait);
-	mutex_init(&s->open_mutex);
-	spin_lock_init(&s->lock);
-	s->codec.private_data = s;
-	s->codec.id = 0;
-	s->codec.codec_read = rdcodec;
-	s->codec.codec_write = wrcodec;
-	s->codec.codec_wait = waitcodec;
-
-	if (!request_mem_region(CPHYSADDR(AC97C_CONFIG),
-			    0x14, AU1000_MODULE_NAME)) {
-		err("AC'97 ports in use");
-		return -1;
-	}
-	// Allocate the DMA Channels
-	if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
-						   "audio DAC",
-						   dac_dma_interrupt,
-						   IRQF_DISABLED, s)) < 0) {
-		err("Can't get DAC DMA");
-		goto err_dma1;
-	}
-	if ((s->dma_adc.dmanr = request_au1000_dma(DMA_ID_AC97C_RX,
-						   "audio ADC",
-						   adc_dma_interrupt,
-						   IRQF_DISABLED, s)) < 0) {
-		err("Can't get ADC DMA");
-		goto err_dma2;
-	}
-
-	info("DAC: DMA%d/IRQ%d, ADC: DMA%d/IRQ%d",
-	     s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr),
-	     s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr));
-
-	// enable DMA coherency in read/write DMA channels
-	set_dma_mode(s->dma_dac.dmanr,
-		     get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC);
-	set_dma_mode(s->dma_adc.dmanr,
-		     get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC);
-
-	/* register devices */
-
-	if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0)
-		goto err_dev1;
-	if ((s->codec.dev_mixer =
-	     register_sound_mixer(&au1000_mixer_fops, -1)) < 0)
-		goto err_dev2;
-
-#ifdef AU1000_DEBUG
-	/* intialize the debug proc device */
-	s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL,
-				       proc_au1000_dump, NULL);
-#endif /* AU1000_DEBUG */
-
-	// configure pins for AC'97
-	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
-
-	// Assert reset for 10msec to the AC'97 controller, and enable clock
-	au_writel(AC97C_RS | AC97C_CE, AC97C_CNTRL);
-	au1000_delay(10);
-	au_writel(AC97C_CE, AC97C_CNTRL);
-	au1000_delay(10);	// wait for clock to stabilize
-
-	/* cold reset the AC'97 */
-	au_writel(AC97C_RESET, AC97C_CONFIG);
-	au1000_delay(10);
-	au_writel(0, AC97C_CONFIG);
-	/* need to delay around 500msec(bleech) to give
-	   some CODECs enough time to wakeup */
-	au1000_delay(500);
-
-	/* warm reset the AC'97 to start the bitclk */
-	au_writel(AC97C_SG | AC97C_SYNC, AC97C_CONFIG);
-	udelay(100);
-	au_writel(0, AC97C_CONFIG);
-
-	/* codec init */
-	if (!ac97_probe_codec(&s->codec))
-		goto err_dev3;
-
-	s->codec_base_caps = rdcodec(&s->codec, AC97_RESET);
-	s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID);
-	info("AC'97 Base/Extended ID = %04x/%04x",
-	     s->codec_base_caps, s->codec_ext_caps);
-
-	/*
-	 * On the Pb1000, audio playback is on the AUX_OUT
-	 * channel (which defaults to LNLVL_OUT in AC'97
-	 * rev 2.2) so make sure this channel is listed
-	 * as supported (soundcard.h calls this channel
-	 * ALTPCM). ac97_codec.c does not handle detection
-	 * of this channel correctly.
-	 */
-	s->codec.supported_mixers |= SOUND_MASK_ALTPCM;
-	/*
-	 * Now set AUX_OUT's default volume.
-	 */
-	val = 0x4343;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM,
-		     (unsigned long) &val);
-	
-	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
-		// codec does not support VRA
-		s->no_vra = 1;
-	} else if (!vra) {
-		// Boot option says disable VRA
-		u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-		wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-			ac97_extstat & ~AC97_EXTSTAT_VRA);
-		s->no_vra = 1;
-	}
-	if (s->no_vra)
-		info("no VRA, interpolating and decimating");
-
-	/* set mic to be the recording source */
-	val = SOUND_MASK_MIC;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
-		     (unsigned long) &val);
-
-#ifdef AU1000_DEBUG
-	sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME,
-		s->codec.id);
-	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					     ac97_read_proc, &s->codec);
-#endif
-
-#ifdef CONFIG_MIPS_XXS1500
-	/* deassert eapd */
-	wrcodec(&s->codec, AC97_POWER_CONTROL,
-			rdcodec(&s->codec, AC97_POWER_CONTROL) & ~0x8000);
-	/* mute a number of signals which seem to be causing problems
-	 * if not muted.
-	 */
-	wrcodec(&s->codec, AC97_PCBEEP_VOL, 0x8000);
-	wrcodec(&s->codec, AC97_PHONE_VOL, 0x8008);
-	wrcodec(&s->codec, AC97_MIC_VOL, 0x8008);
-	wrcodec(&s->codec, AC97_LINEIN_VOL, 0x8808);
-	wrcodec(&s->codec, AC97_CD_VOL, 0x8808);
-	wrcodec(&s->codec, AC97_VIDEO_VOL, 0x8808);
-	wrcodec(&s->codec, AC97_AUX_VOL, 0x8808);
-	wrcodec(&s->codec, AC97_PCMOUT_VOL, 0x0808);
-	wrcodec(&s->codec, AC97_GENERAL_PURPOSE, 0x2000);
-#endif
-
-	return 0;
-
- err_dev3:
-	unregister_sound_mixer(s->codec.dev_mixer);
- err_dev2:
-	unregister_sound_dsp(s->dev_audio);
- err_dev1:
-	free_au1000_dma(s->dma_adc.dmanr);
- err_dma2:
-	free_au1000_dma(s->dma_dac.dmanr);
- err_dma1:
-	release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
-	return -1;
-}
-
-static void au1000_remove(void)
-{
-	struct au1000_state *s = &au1000_state;
-
-	if (!s)
-		return;
-#ifdef AU1000_DEBUG
-	if (s->ps)
-		remove_proc_entry(AU1000_MODULE_NAME, NULL);
-#endif /* AU1000_DEBUG */
-	synchronize_irq();
-	free_au1000_dma(s->dma_adc.dmanr);
-	free_au1000_dma(s->dma_dac.dmanr);
-	release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec.dev_mixer);
-}
-
-static int __init init_au1000(void)
-{
-	info("stevel@mvista.com, built " __TIME__ " on " __DATE__);
-	return au1000_probe();
-}
-
-static void __exit cleanup_au1000(void)
-{
-	info("unloading");
-	au1000_remove();
-}
-
-module_init(init_au1000);
-module_exit(cleanup_au1000);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-static int __init au1000_setup(char *options)
-{
-	char           *this_opt;
-
-	if (!options || !*options)
-		return 0;
-
-	while ((this_opt = strsep(&options, ","))) {
-		if (!*this_opt)
-			continue;
-		if (!strncmp(this_opt, "vra", 3)) {
-			vra = 1;
-		}
-	}
-
-	return 1;
-}
-
-__setup("au1000_audio=", au1000_setup);
-
-#endif /* MODULE */
diff --git a/sound/oss/audio.c b/sound/oss/audio.c
index 22dd63c..89bd27a 100644
--- a/sound/oss/audio.c
+++ b/sound/oss/audio.c
@@ -1,5 +1,5 @@
 /*
- * sound/audio.c
+ * sound/oss/audio.c
  *
  * Device file manager for /dev/audio
  */
diff --git a/sound/oss/audio_syms.c b/sound/oss/audio_syms.c
deleted file mode 100644
index 5da217f..0000000
--- a/sound/oss/audio_syms.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Exported symbols for audio driver.
- */
-
-#include <linux/module.h>
-
-char audio_syms_symbol;
-
-#include "sound_config.h"
-#include "sound_calls.h"
-
-EXPORT_SYMBOL(DMAbuf_start_dma);
-EXPORT_SYMBOL(DMAbuf_open_dma);
-EXPORT_SYMBOL(DMAbuf_close_dma);
-EXPORT_SYMBOL(DMAbuf_inputintr);
-EXPORT_SYMBOL(DMAbuf_outputintr);
diff --git a/sound/oss/awe_hw.h b/sound/oss/awe_hw.h
deleted file mode 100644
index 7e403ad..0000000
--- a/sound/oss/awe_hw.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * sound/awe_hw.h
- *
- * Access routines and definitions for the low level driver for the 
- * Creative AWE32/SB32/AWE64 wave table synth.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AWE_HW_H_DEF
-#define AWE_HW_H_DEF
-
-/*
- * Emu-8000 control registers
- * name(channel)	reg, port
- */
-
-#define awe_cmd_idx(reg,ch)	(((reg)<< 5) | (ch))
-
-#define Data0    0		/* 0x620: doubleword r/w */
-#define Data1    1		/* 0xA20: doubleword r/w */
-#define Data2    2		/* 0xA22: word r/w */
-#define Data3    3		/* 0xE20: word r/w */
-#define Pointer  4		/* 0xE22 register pointer r/w */
-
-#define AWE_CPF(ch)	awe_cmd_idx(0,ch), Data0	/* DW: current pitch and fractional address */
-#define AWE_PTRX(ch)	awe_cmd_idx(1,ch), Data0	/* DW: pitch target and reverb send */
-#define AWE_CVCF(ch)	awe_cmd_idx(2,ch), Data0	/* DW: current volume and filter cutoff */
-#define AWE_VTFT(ch)	awe_cmd_idx(3,ch), Data0	/* DW: volume and filter cutoff targets */
-#define AWE_0080(ch)	awe_cmd_idx(4,ch), Data0	/* DW: ?? */
-#define AWE_00A0(ch)	awe_cmd_idx(5,ch), Data0	/* DW: ?? */
-#define AWE_PSST(ch)	awe_cmd_idx(6,ch), Data0	/* DW: pan send and loop start address */
-#define AWE_CSL(ch)	awe_cmd_idx(7,ch), Data0	/* DW: chorus send and loop end address */
-#define AWE_CCCA(ch)	awe_cmd_idx(0,ch), Data1	/* DW: Q, control bits, and current address */
-#define AWE_HWCF4	awe_cmd_idx(1,9),  Data1	/* DW: config dw 4 */
-#define AWE_HWCF5	awe_cmd_idx(1,10), Data1	/* DW: config dw 5 */
-#define AWE_HWCF6	awe_cmd_idx(1,13), Data1	/* DW: config dw 6 */
-#define AWE_HWCF7	awe_cmd_idx(1,14), Data1	/* DW: config dw 7? (not documented) */
-#define AWE_SMALR	awe_cmd_idx(1,20), Data1	/* DW: sound memory address for left read */
-#define AWE_SMARR	awe_cmd_idx(1,21), Data1	/* DW:    for right read */
-#define AWE_SMALW	awe_cmd_idx(1,22), Data1	/* DW: sound memory address for left write */
-#define AWE_SMARW	awe_cmd_idx(1,23), Data1	/* DW:    for right write */
-#define AWE_SMLD	awe_cmd_idx(1,26), Data1	/* W: sound memory left data */
-#define AWE_SMRD	awe_cmd_idx(1,26), Data2	/* W:    right data */
-#define AWE_WC		awe_cmd_idx(1,27), Data2	/* W: sample counter */
-#define AWE_WC_Cmd	awe_cmd_idx(1,27)
-#define AWE_WC_Port	Data2
-#define AWE_HWCF1	awe_cmd_idx(1,29), Data1	/* W: config w 1 */
-#define AWE_HWCF2	awe_cmd_idx(1,30), Data1	/* W: config w 2 */
-#define AWE_HWCF3	awe_cmd_idx(1,31), Data1	/* W: config w 3 */
-#define AWE_INIT1(ch)	awe_cmd_idx(2,ch), Data1	/* W: init array 1 */
-#define AWE_INIT2(ch)	awe_cmd_idx(2,ch), Data2	/* W: init array 2 */
-#define AWE_INIT3(ch)	awe_cmd_idx(3,ch), Data1	/* W: init array 3 */
-#define AWE_INIT4(ch)	awe_cmd_idx(3,ch), Data2	/* W: init array 4 */
-#define AWE_ENVVOL(ch)	awe_cmd_idx(4,ch), Data1	/* W: volume envelope delay */
-#define AWE_DCYSUSV(ch)	awe_cmd_idx(5,ch), Data1	/* W: volume envelope sustain and decay */
-#define AWE_ENVVAL(ch)	awe_cmd_idx(6,ch), Data1	/* W: modulation envelope delay */
-#define AWE_DCYSUS(ch)	awe_cmd_idx(7,ch), Data1	/* W: modulation envelope sustain and decay */
-#define AWE_ATKHLDV(ch)	awe_cmd_idx(4,ch), Data2	/* W: volume envelope attack and hold */
-#define AWE_LFO1VAL(ch)	awe_cmd_idx(5,ch), Data2	/* W: LFO#1 Delay */
-#define AWE_ATKHLD(ch)	awe_cmd_idx(6,ch), Data2	/* W: modulation envelope attack and hold */
-#define AWE_LFO2VAL(ch)	awe_cmd_idx(7,ch), Data2	/* W: LFO#2 Delay */
-#define AWE_IP(ch)	awe_cmd_idx(0,ch), Data3	/* W: initial pitch */
-#define AWE_IFATN(ch)	awe_cmd_idx(1,ch), Data3	/* W: initial filter cutoff and attenuation */
-#define AWE_PEFE(ch)	awe_cmd_idx(2,ch), Data3	/* W: pitch and filter envelope heights */
-#define AWE_FMMOD(ch)	awe_cmd_idx(3,ch), Data3	/* W: vibrato and filter modulation freq */
-#define AWE_TREMFRQ(ch)	awe_cmd_idx(4,ch), Data3	/* W: LFO#1 tremolo amount and freq */
-#define AWE_FM2FRQ2(ch)	awe_cmd_idx(5,ch), Data3	/* W: LFO#2 vibrato amount and freq */
-
-/* used during detection (returns ROM version?; not documented in ADIP) */
-#define AWE_U1		0xE0, Data3	  /* (R)(W) used in initialization */
-#define AWE_U2(ch)	0xC0+(ch), Data3  /* (W)(W) used in init envelope  */
-
-
-#define AWE_MAX_VOICES		32
-#define AWE_NORMAL_VOICES	30	/*30&31 are reserved for DRAM refresh*/
-
-#define AWE_MAX_CHANNELS	32	/* max midi channels (must >= voices) */
-#define AWE_MAX_LAYERS	AWE_MAX_VOICES	/* maximum number of multiple layers */
-
-#define AWE_DRAM_OFFSET		0x200000
-#define AWE_MAX_DRAM_SIZE	(28 * 1024)	/* 28 MB is max onboard memory */
-
-#endif
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
deleted file mode 100644
index d1a0eb2..0000000
--- a/sound/oss/awe_wave.c
+++ /dev/null
@@ -1,6149 +0,0 @@
-/*
- * sound/awe_wave.c
- *
- * The low level driver for the AWE32/SB32/AWE64 wave table synth.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Changelog:
- * Aug 18, 2003, Adam Belay <ambx1@neo.rr.com>
- * - detection code rewrite
- */
-
-#include <linux/awe_voice.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/pnp.h>
-
-#include "sound_config.h"
-
-#include "awe_wave.h"
-#include "awe_hw.h"
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-#include "tuning.h"
-#include <linux/ultrasound.h>
-#endif
-
-/*
- * debug message
- */
-
-#ifdef AWE_DEBUG_ON
-#define DEBUG(LVL,XXX)	{if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}
-#define ERRMSG(XXX)	{if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}
-#define FATALERR(XXX)	XXX
-#else
-#define DEBUG(LVL,XXX) /**/
-#define ERRMSG(XXX)	XXX
-#define FATALERR(XXX)	XXX
-#endif
-
-/*
- * bank and voice record
- */
-
-typedef struct _sf_list sf_list;
-typedef struct _awe_voice_list awe_voice_list;
-typedef struct _awe_sample_list awe_sample_list;
-
-/* soundfont record */
-struct _sf_list {
-	unsigned short sf_id;	/* id number */
-	unsigned short type;	/* lock & shared flags */
-	int num_info;		/* current info table index */
-	int num_sample;		/* current sample table index */
-	int mem_ptr;		/* current word byte pointer */
-	awe_voice_list *infos, *last_infos;	/* instruments */
-	awe_sample_list *samples, *last_samples;	/* samples */
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-	sf_list *shared;	/* shared list */
-	unsigned char name[AWE_PATCH_NAME_LEN];	/* sharing id */
-#endif
-	sf_list *next, *prev;
-};
-
-/* instrument list */
-struct _awe_voice_list {
-	awe_voice_info v;	/* instrument information */
-	sf_list *holder;	/* parent sf_list of this record */
-	unsigned char bank, instr;	/* preset number information */
-	char type, disabled;	/* type=normal/mapped, disabled=boolean */
-	awe_voice_list *next;	/* linked list with same sf_id */
-	awe_voice_list *next_instr;	/* instrument list */
-	awe_voice_list *next_bank;	/* hash table list */
-};
-
-/* voice list type */
-#define V_ST_NORMAL	0
-#define V_ST_MAPPED	1
-
-/* sample list */
-struct _awe_sample_list {
-	awe_sample_info v;	/* sample information */
-	sf_list *holder;	/* parent sf_list of this record */
-	awe_sample_list *next;	/* linked list with same sf_id */
-};
-
-/* sample and information table */
-static int current_sf_id;	/* current number of fonts */
-static int locked_sf_id;	/* locked position */
-static sf_list *sfhead, *sftail;	/* linked-lists */
-
-#define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)
-#define awe_free_info() (sftail ? sftail->num_info : 0)
-#define awe_free_sample() (sftail ? sftail->num_sample : 0)
-
-#define AWE_MAX_PRESETS		256
-#define AWE_DEFAULT_PRESET	0
-#define AWE_DEFAULT_BANK	0
-#define AWE_DEFAULT_DRUM	0
-#define AWE_DRUM_BANK		128
-
-#define MAX_LAYERS	AWE_MAX_VOICES
-
-/* preset table index */
-static awe_voice_list *preset_table[AWE_MAX_PRESETS];
-
-/*
- * voice table
- */
-
-/* effects table */
-typedef	struct FX_Rec { /* channel effects */
-	unsigned char flags[AWE_FX_END];
-	short val[AWE_FX_END];
-} FX_Rec;
-
-
-/* channel parameters */
-typedef struct _awe_chan_info {
-	int channel;		/* channel number */
-	int bank;		/* current tone bank */
-	int instr;		/* current program */
-	int bender;		/* midi pitchbend (-8192 - 8192) */
-	int bender_range;	/* midi bender range (x100) */
-	int panning;		/* panning (0-127) */
-	int main_vol;		/* channel volume (0-127) */
-	int expression_vol;	/* midi expression (0-127) */
-	int chan_press;		/* channel pressure */
-	int sustained;		/* sustain status in MIDI */
-	FX_Rec fx;		/* effects */
-	FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
-} awe_chan_info;
-
-/* voice parameters */
-typedef struct _voice_info {
-	int state;
-#define AWE_ST_OFF		(1<<0)	/* no sound */
-#define AWE_ST_ON		(1<<1)	/* playing */
-#define AWE_ST_STANDBY		(1<<2)	/* stand by for playing */
-#define AWE_ST_SUSTAINED	(1<<3)	/* sustained */
-#define AWE_ST_MARK		(1<<4)	/* marked for allocation */
-#define AWE_ST_DRAM		(1<<5)	/* DRAM read/write */
-#define AWE_ST_FM		(1<<6)	/* reserved for FM */
-#define AWE_ST_RELEASED		(1<<7)	/* released */
-
-	int ch;			/* midi channel */
-	int key;		/* internal key for search */
-	int layer;		/* layer number (for channel mode only) */
-	int time;		/* allocated time */
-	awe_chan_info	*cinfo;	/* channel info */
-
-	int note;		/* midi key (0-127) */
-	int velocity;		/* midi velocity (0-127) */
-	int sostenuto;		/* sostenuto on/off */
-	awe_voice_info *sample;	/* assigned voice */
-
-	/* EMU8000 parameters */
-	int apitch;		/* pitch parameter */
-	int avol;		/* volume parameter */
-	int apan;		/* panning parameter */
-	int acutoff;		/* cutoff parameter */
-	short aaux;		/* aux word */
-} voice_info;
-
-/* voice information */
-static voice_info voices[AWE_MAX_VOICES];
-
-#define IS_NO_SOUND(v)	(voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
-#define IS_NO_EFFECT(v)	(voices[v].state != AWE_ST_ON)
-#define IS_PLAYING(v)	(voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
-#define IS_EMPTY(v)	(voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
-
-
-/* MIDI channel effects information (for hw control) */
-static awe_chan_info channels[AWE_MAX_CHANNELS];
-
-
-/*
- * global variables
- */
-
-#ifndef AWE_DEFAULT_BASE_ADDR
-#define AWE_DEFAULT_BASE_ADDR	0	/* autodetect */
-#endif
-
-#ifndef AWE_DEFAULT_MEM_SIZE
-#define AWE_DEFAULT_MEM_SIZE	-1	/* autodetect */
-#endif
-
-static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
-static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
-#ifdef CONFIG_PNP
-static int isapnp = -1;
-#else
-static int isapnp;
-#endif
-
-MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
-MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "base i/o port of Emu8000");
-module_param(memsize, int, 0);
-MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
-module_param(isapnp, bool, 0);
-MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
-
-/* DRAM start offset */
-static int awe_mem_start = AWE_DRAM_OFFSET;
-
-/* maximum channels for playing */
-static int awe_max_voices = AWE_MAX_VOICES;
-
-static int patch_opened;		/* sample already loaded? */
-
-static char atten_relative = FALSE;
-static short atten_offset;
-
-static int awe_present = FALSE;		/* awe device present? */
-static int awe_busy = FALSE;		/* awe device opened? */
-
-static int my_dev = -1;
-
-#define DEFAULT_DRUM_FLAGS	((1 << 9) | (1 << 25))
-#define IS_DRUM_CHANNEL(c)	(drum_flags & (1 << (c)))
-#define DRUM_CHANNEL_ON(c)	(drum_flags |= (1 << (c)))
-#define DRUM_CHANNEL_OFF(c)	(drum_flags &= ~(1 << (c)))
-static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
-
-static int playing_mode = AWE_PLAY_INDIRECT;
-#define SINGLE_LAYER_MODE()	(playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
-#define MULTI_LAYER_MODE()	(playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
-
-static int current_alloc_time;  	/* voice allocation index for channel mode */
-
-static struct synth_info awe_info = {
-	"AWE32 Synth",		/* name */
-	0,			/* device */
-	SYNTH_TYPE_SAMPLE,	/* synth_type */
-	SAMPLE_TYPE_AWE32,	/* synth_subtype */
-	0,			/* perc_mode (obsolete) */
-	AWE_MAX_VOICES,		/* nr_voices */
-	0,			/* nr_drums (obsolete) */
-	400			/* instr_bank_size */
-};
-
-
-static struct voice_alloc_info *voice_alloc;	/* set at initialization */
-
-
-/*
- * function prototypes
- */
-
-static int awe_request_region(void);
-static void awe_release_region(void);
-
-static void awe_reset_samples(void);
-/* emu8000 chip i/o access */
-static void setup_ports(int p1, int p2, int p3);
-static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
-static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
-static unsigned short awe_peek(unsigned short cmd, unsigned short port);
-static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
-static void awe_wait(unsigned short delay);
-
-/* initialize emu8000 chip */
-static void awe_initialize(void);
-
-/* set voice parameters */
-static void awe_init_ctrl_parms(int init_all);
-static void awe_init_voice_info(awe_voice_info *vp);
-static void awe_init_voice_parm(awe_voice_parm *pp);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static int freq_to_note(int freq);
-static int calc_rate_offset(int Hz);
-/*static int calc_parm_delay(int msec);*/
-static int calc_parm_hold(int msec);
-static int calc_parm_attack(int msec);
-static int calc_parm_decay(int msec);
-static int calc_parm_search(int msec, short *table);
-#endif /* gus compat */
-
-/* turn on/off note */
-static void awe_note_on(int voice);
-static void awe_note_off(int voice);
-static void awe_terminate(int voice);
-static void awe_exclusive_off(int voice);
-static void awe_note_off_all(int do_sustain);
-
-/* calculate voice parameters */
-typedef void (*fx_affect_func)(int voice, int forced);
-static void awe_set_pitch(int voice, int forced);
-static void awe_set_voice_pitch(int voice, int forced);
-static void awe_set_volume(int voice, int forced);
-static void awe_set_voice_vol(int voice, int forced);
-static void awe_set_pan(int voice, int forced);
-static void awe_fx_fmmod(int voice, int forced);
-static void awe_fx_tremfrq(int voice, int forced);
-static void awe_fx_fm2frq2(int voice, int forced);
-static void awe_fx_filterQ(int voice, int forced);
-static void awe_calc_pitch(int voice);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static void awe_calc_pitch_from_freq(int voice, int freq);
-#endif
-static void awe_calc_volume(int voice);
-static void awe_update_volume(void);
-static void awe_change_master_volume(short val);
-static void awe_voice_init(int voice, int init_all);
-static void awe_channel_init(int ch, int init_all);
-static void awe_fx_init(int ch);
-static void awe_send_effect(int voice, int layer, int type, int val);
-static void awe_modwheel_change(int voice, int value);
-
-/* sequencer interface */
-static int awe_open(int dev, int mode);
-static void awe_close(int dev);
-static int awe_ioctl(int dev, unsigned int cmd, void __user * arg);
-static int awe_kill_note(int dev, int voice, int note, int velocity);
-static int awe_start_note(int dev, int v, int note_num, int volume);
-static int awe_set_instr(int dev, int voice, int instr_no);
-static int awe_set_instr_2(int dev, int voice, int instr_no);
-static void awe_reset(int dev);
-static void awe_hw_control(int dev, unsigned char *event);
-static int awe_load_patch(int dev, int format, const char __user *addr,
-			  int offs, int count, int pmgr_flag);
-static void awe_aftertouch(int dev, int voice, int pressure);
-static void awe_controller(int dev, int voice, int ctrl_num, int value);
-static void awe_panning(int dev, int voice, int value);
-static void awe_volume_method(int dev, int mode);
-static void awe_bender(int dev, int voice, int value);
-static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
-static void awe_setup_voice(int dev, int voice, int chn);
-
-#define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)
-
-/* hardware controls */
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
-#endif
-static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
-static void awe_voice_change(int voice, fx_affect_func func);
-static void awe_sostenuto_on(int voice, int forced);
-static void awe_sustain_off(int voice, int forced);
-static void awe_terminate_and_init(int voice, int forced);
-
-/* voice search */
-static int awe_search_key(int bank, int preset, int note);
-static awe_voice_list *awe_search_instr(int bank, int preset, int note);
-static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);
-static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
-static void awe_alloc_one_voice(int voice, int note, int velocity);
-static int awe_clear_voice(void);
-
-/* load / remove patches */
-static int awe_open_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_close_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_info(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_remove_info(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_data(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_replace_data(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_map(awe_patch_info *patch, const char __user *addr, int count);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static int awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag);
-#endif
-/*static int awe_probe_info(awe_patch_info *patch, const char __user *addr, int count);*/
-static int awe_probe_data(awe_patch_info *patch, const char __user *addr, int count);
-static sf_list *check_patch_opened(int type, char *name);
-static int awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *sp, int channels);
-static int awe_create_sf(int type, char *name);
-static void awe_free_sf(sf_list *sf);
-static void add_sf_info(sf_list *sf, awe_voice_list *rec);
-static void add_sf_sample(sf_list *sf, awe_sample_list *smp);
-static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);
-static void add_info_list(awe_voice_list *rec);
-static void awe_remove_samples(int sf_id);
-static void rebuild_preset_list(void);
-static short awe_set_sample(awe_voice_list *rec);
-static awe_sample_list *search_sample_index(sf_list *sf, int sample);
-
-static int is_identical_holder(sf_list *sf1, sf_list *sf2);
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-static int is_identical_name(unsigned char *name, sf_list *p);
-static int is_shared_sf(unsigned char *name);
-static int info_duplicated(sf_list *sf, awe_voice_list *rec);
-#endif /* allow sharing */
-
-/* lowlevel functions */
-static void awe_init_audio(void);
-static void awe_init_dma(void);
-static void awe_init_array(void);
-static void awe_send_array(unsigned short *data);
-static void awe_tweak_voice(int voice);
-static void awe_tweak(void);
-static void awe_init_fm(void);
-static int awe_open_dram_for_write(int offset, int channels);
-static void awe_open_dram_for_check(void);
-static void awe_close_dram(void);
-/*static void awe_write_dram(unsigned short c);*/
-static int awe_detect_base(int addr);
-static int awe_detect(void);
-static void awe_check_dram(void);
-static int awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count);
-static void awe_set_chorus_mode(int mode);
-static void awe_update_chorus_mode(void);
-static int awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count);
-static void awe_set_reverb_mode(int mode);
-static void awe_update_reverb_mode(void);
-static void awe_equalizer(int bass, int treble);
-static void awe_update_equalizer(void);
-
-#ifdef CONFIG_AWE32_MIXER
-static void attach_mixer(void);
-static void unload_mixer(void);
-#endif
-
-#ifdef CONFIG_AWE32_MIDIEMU
-static void attach_midiemu(void);
-static void unload_midiemu(void);
-#endif
-
-#define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
-
-/*
- * control parameters
- */
-
-
-#ifdef AWE_USE_NEW_VOLUME_CALC
-#define DEF_VOLUME_CALC	TRUE
-#else
-#define DEF_VOLUME_CALC	FALSE
-#endif /* new volume */
-
-#define DEF_ZERO_ATTEN		32	/* 12dB below */
-#define DEF_MOD_SENSE		18
-#define DEF_CHORUS_MODE		2
-#define DEF_REVERB_MODE		4
-#define DEF_BASS_LEVEL		5
-#define DEF_TREBLE_LEVEL	9
-
-static struct CtrlParmsDef {
-	int value;
-	int init_each_time;
-	void (*update)(void);
-} ctrl_parms[AWE_MD_END] = {
-	{0,0, NULL}, {0,0, NULL}, /* <-- not used */
-	{AWE_VERSION_NUMBER, FALSE, NULL},
-	{TRUE, FALSE, NULL}, /* exclusive */
-	{TRUE, FALSE, NULL}, /* realpan */
-	{AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */
-	{FALSE, TRUE, NULL}, /* keep effect */
-	{DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */
-	{FALSE, FALSE, NULL}, /* chn_prior */
-	{DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */
-	{AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */
-	{AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */
-	{AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */
-	{FALSE, FALSE, NULL}, /* toggle_drum_bank */
-	{DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */
-	{DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */
-	{DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */
-	{DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */
-	{DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */
-	{0, FALSE, NULL},	/* debug mode */
-	{FALSE, FALSE, NULL}, /* pan exchange */
-};
-
-static int ctrls[AWE_MD_END];
-
-
-/*
- * synth operation table
- */
-
-static struct synth_operations awe_operations =
-{
-	.owner		= THIS_MODULE,
-	.id		= "EMU8K",
-	.info		= &awe_info,
-	.midi_dev	= 0,
-	.synth_type	= SYNTH_TYPE_SAMPLE,
-	.synth_subtype	= SAMPLE_TYPE_AWE32,
-	.open		= awe_open,
-	.close		= awe_close,
-	.ioctl		= awe_ioctl,
-	.kill_note	= awe_kill_note,
-	.start_note	= awe_start_note,
-	.set_instr	= awe_set_instr_2,
-	.reset		= awe_reset,
-	.hw_control	= awe_hw_control,
-	.load_patch	= awe_load_patch,
-	.aftertouch	= awe_aftertouch,
-	.controller	= awe_controller,
-	.panning	= awe_panning,
-	.volume_method	= awe_volume_method,
-	.bender		= awe_bender,
-	.alloc_voice	= awe_alloc,
-	.setup_voice	= awe_setup_voice
-};
-
-static void free_tables(void)
-{
-	if (sftail) {
-		sf_list *p, *prev;
-		for (p = sftail; p; p = prev) {
-			prev = p->prev;
-			awe_free_sf(p);
-		}
-	}
-	sfhead = sftail = NULL;
-}
-
-/*
- * clear sample tables 
- */
-
-static void
-awe_reset_samples(void)
-{
-	/* free all bank tables */
-	memset(preset_table, 0, sizeof(preset_table));
-	free_tables();
-
-	current_sf_id = 0;
-	locked_sf_id = 0;
-	patch_opened = 0;
-}
-
-
-/*
- * EMU register access
- */
-
-/* select a given AWE32 pointer */
-static int awe_ports[5];
-static int port_setuped = FALSE;
-static int awe_cur_cmd = -1;
-#define awe_set_cmd(cmd) \
-if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
-
-/* write 16bit data */
-static void
-awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
-{
-	awe_set_cmd(cmd);
-	outw(data, awe_ports[port]);
-}
-
-/* write 32bit data */
-static void
-awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
-{
-	unsigned short addr = awe_ports[port];
-	awe_set_cmd(cmd);
-	outw(data, addr);		/* write lower 16 bits */
-	outw(data >> 16, addr + 2);	/* write higher 16 bits */
-}
-
-/* read 16bit data */
-static unsigned short
-awe_peek(unsigned short cmd, unsigned short port)
-{
-	unsigned short k;
-	awe_set_cmd(cmd);
-	k = inw(awe_ports[port]);
-	return k;
-}
-
-/* read 32bit data */
-static unsigned int
-awe_peek_dw(unsigned short cmd, unsigned short port)
-{
-	unsigned int k1, k2;
-	unsigned short addr = awe_ports[port];
-	awe_set_cmd(cmd);
-	k1 = inw(addr);
-	k2 = inw(addr + 2);
-	k1 |= k2 << 16;
-	return k1;
-}
-
-/* wait delay number of AWE32 44100Hz clocks */
-#ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
-static void
-awe_wait(unsigned short delay)
-{
-	unsigned short clock, target;
-	unsigned short port = awe_ports[AWE_WC_Port];
-	int counter;
-  
-	/* sample counter */
-	awe_set_cmd(AWE_WC_Cmd);
-	clock = (unsigned short)inw(port);
-	target = clock + delay;
-	counter = 0;
-	if (target < clock) {
-		for (; (unsigned short)inw(port) > target; counter++)
-			if (counter > 65536)
-				break;
-	}
-	for (; (unsigned short)inw(port) < target; counter++)
-		if (counter > 65536)
-			break;
-}
-#else
-
-static void awe_wait(unsigned short delay)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
-}
-/*
-static void awe_wait(unsigned short delay)
-{
-	udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
-}
-*/
-#endif /* wait by loop */
-
-/* write a word data */
-#define awe_write_dram(c)	awe_poke(AWE_SMLD, c)
-
-/*
- * AWE32 voice parameters
- */
-
-/* initialize voice_info record */
-static void
-awe_init_voice_info(awe_voice_info *vp)
-{
-	vp->sample = 0;
-	vp->rate_offset = 0;
-
-	vp->start = 0;
-	vp->end = 0;
-	vp->loopstart = 0;
-	vp->loopend = 0;
-	vp->mode = 0;
-	vp->root = 60;
-	vp->tune = 0;
-	vp->low = 0;
-	vp->high = 127;
-	vp->vellow = 0;
-	vp->velhigh = 127;
-
-	vp->fixkey = -1;
-	vp->fixvel = -1;
-	vp->fixpan = -1;
-	vp->pan = -1;
-
-	vp->exclusiveClass = 0;
-	vp->amplitude = 127;
-	vp->attenuation = 0;
-	vp->scaleTuning = 100;
-
-	awe_init_voice_parm(&vp->parm);
-}
-
-/* initialize voice_parm record:
- * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
- * Vibrato and Tremolo effects are zero.
- * Cutoff is maximum.
- * Chorus and Reverb effects are zero.
- */
-static void
-awe_init_voice_parm(awe_voice_parm *pp)
-{
-	pp->moddelay = 0x8000;
-	pp->modatkhld = 0x7f7f;
-	pp->moddcysus = 0x7f7f;
-	pp->modrelease = 0x807f;
-	pp->modkeyhold = 0;
-	pp->modkeydecay = 0;
-
-	pp->voldelay = 0x8000;
-	pp->volatkhld = 0x7f7f;
-	pp->voldcysus = 0x7f7f;
-	pp->volrelease = 0x807f;
-	pp->volkeyhold = 0;
-	pp->volkeydecay = 0;
-
-	pp->lfo1delay = 0x8000;
-	pp->lfo2delay = 0x8000;
-	pp->pefe = 0;
-
-	pp->fmmod = 0;
-	pp->tremfrq = 0;
-	pp->fm2frq2 = 0;
-
-	pp->cutoff = 0xff;
-	pp->filterQ = 0;
-
-	pp->chorus = 0;
-	pp->reverb = 0;
-}	
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* convert frequency mHz to abstract cents (= midi key * 100) */
-static int
-freq_to_note(int mHz)
-{
-	/* abscents = log(mHz/8176) / log(2) * 1200 */
-	unsigned int max_val = (unsigned int)0xffffffff / 10000;
-	int i, times;
-	unsigned int base;
-	unsigned int freq;
-	int note, tune;
-
-	if (mHz == 0)
-		return 0;
-	if (mHz < 0)
-		return 12799; /* maximum */
-
-	freq = mHz;
-	note = 0;
-	for (base = 8176 * 2; freq >= base; base *= 2) {
-		note += 12;
-		if (note >= 128) /* over maximum */
-			return 12799;
-	}
-	base /= 2;
-
-	/* to avoid overflow... */
-	times = 10000;
-	while (freq > max_val) {
-		max_val *= 10;
-		times /= 10;
-		base /= 10;
-	}
-
-	freq = freq * times / base;
-	for (i = 0; i < 12; i++) {
-		if (freq < semitone_tuning[i+1])
-			break;
-		note++;
-	}
-
-	tune = 0;
-	freq = freq * 10000 / semitone_tuning[i];
-	for (i = 0; i < 100; i++) {
-		if (freq < cent_tuning[i+1])
-			break;
-		tune++;
-	}
-
-	return note * 100 + tune;
-}
-
-
-/* convert Hz to AWE32 rate offset:
- * sample pitch offset for the specified sample rate
- * rate=44100 is no offset, each 4096 is 1 octave (twice).
- * eg, when rate is 22050, this offset becomes -4096.
- */
-static int
-calc_rate_offset(int Hz)
-{
-	/* offset = log(Hz / 44100) / log(2) * 4096 */
-	int freq, base, i;
-
-	/* maybe smaller than max (44100Hz) */
-	if (Hz <= 0 || Hz >= 44100) return 0;
-
-	base = 0;
-	for (freq = Hz * 2; freq < 44100; freq *= 2)
-		base++;
-	base *= 1200;
-
-	freq = 44100 * 10000 / (freq/2);
-	for (i = 0; i < 12; i++) {
-		if (freq < semitone_tuning[i+1])
-			break;
-		base += 100;
-	}
-	freq = freq * 10000 / semitone_tuning[i];
-	for (i = 0; i < 100; i++) {
-		if (freq < cent_tuning[i+1])
-			break;
-		base++;
-	}
-	return -base * 4096 / 1200;
-}
-
-
-/*
- * convert envelope time parameter to AWE32 raw parameter
- */
-
-/* attack & decay/release time table (msec) */
-static short attack_time_tbl[128] = {
-32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
-707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
-361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
-180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
-90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
-45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
-22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
-11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
-};
-
-static short decay_time_tbl[128] = {
-32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
-2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
-1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
-691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
-345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
-172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
-86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
-43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
-};
-
-#define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
-
-/* delay time = 0x8000 - msec/92 */
-static int
-calc_parm_hold(int msec)
-{
-	int val = (0x7f * 92 - msec) / 92;
-	if (val < 1) val = 1;
-	if (val > 127) val = 127;
-	return val;
-}
-
-/* attack time: search from time table */
-static int
-calc_parm_attack(int msec)
-{
-	return calc_parm_search(msec, attack_time_tbl);
-}
-
-/* decay/release time: search from time table */
-static int
-calc_parm_decay(int msec)
-{
-	return calc_parm_search(msec, decay_time_tbl);
-}
-
-/* search an index for specified time from given time table */
-static int
-calc_parm_search(int msec, short *table)
-{
-	int left = 1, right = 127, mid;
-	while (left < right) {
-		mid = (left + right) / 2;
-		if (msec < (int)table[mid])
-			left = mid + 1;
-		else
-			right = mid;
-	}
-	return left;
-}
-#endif /* AWE_HAS_GUS_COMPATIBILITY */
-
-
-/*
- * effects table
- */
-
-/* set an effect value */
-#define FX_FLAG_OFF	0
-#define FX_FLAG_SET	1
-#define FX_FLAG_ADD	2
-
-#define FX_SET(rec,type,value) \
-	((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
-#define FX_ADD(rec,type,value) \
-	((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
-#define FX_UNSET(rec,type) \
-	((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
-
-/* check the effect value is set */
-#define FX_ON(rec,type)	((rec)->flags[type])
-
-#define PARM_BYTE	0
-#define PARM_WORD	1
-#define PARM_SIGN	2
-
-static struct PARM_DEFS {
-	int type;	/* byte or word */
-	int low, high;	/* value range */
-	fx_affect_func realtime;	/* realtime paramater change */
-} parm_defs[] = {
-	{PARM_WORD, 0, 0x8000, NULL},	/* env1 delay */
-	{PARM_BYTE, 1, 0x7f, NULL},	/* env1 attack */
-	{PARM_BYTE, 0, 0x7e, NULL},	/* env1 hold */
-	{PARM_BYTE, 1, 0x7f, NULL},	/* env1 decay */
-	{PARM_BYTE, 1, 0x7f, NULL},	/* env1 release */
-	{PARM_BYTE, 0, 0x7f, NULL},	/* env1 sustain */
-	{PARM_BYTE, 0, 0xff, NULL},	/* env1 pitch */
-	{PARM_BYTE, 0, 0xff, NULL},	/* env1 cutoff */
-
-	{PARM_WORD, 0, 0x8000, NULL},	/* env2 delay */
-	{PARM_BYTE, 1, 0x7f, NULL},	/* env2 attack */
-	{PARM_BYTE, 0, 0x7e, NULL},	/* env2 hold */
-	{PARM_BYTE, 1, 0x7f, NULL},	/* env2 decay */
-	{PARM_BYTE, 1, 0x7f, NULL},	/* env2 release */
-	{PARM_BYTE, 0, 0x7f, NULL},	/* env2 sustain */
-
-	{PARM_WORD, 0, 0x8000, NULL},	/* lfo1 delay */
-	{PARM_BYTE, 0, 0xff, awe_fx_tremfrq},	/* lfo1 freq */
-	{PARM_SIGN, -128, 127, awe_fx_tremfrq},	/* lfo1 volume */
-	{PARM_SIGN, -128, 127, awe_fx_fmmod},	/* lfo1 pitch */
-	{PARM_BYTE, 0, 0xff, awe_fx_fmmod},	/* lfo1 cutoff */
-
-	{PARM_WORD, 0, 0x8000, NULL},	/* lfo2 delay */
-	{PARM_BYTE, 0, 0xff, awe_fx_fm2frq2},	/* lfo2 freq */
-	{PARM_SIGN, -128, 127, awe_fx_fm2frq2},	/* lfo2 pitch */
-
-	{PARM_WORD, 0, 0xffff, awe_set_voice_pitch},	/* initial pitch */
-	{PARM_BYTE, 0, 0xff, NULL},	/* chorus */
-	{PARM_BYTE, 0, 0xff, NULL},	/* reverb */
-	{PARM_BYTE, 0, 0xff, awe_set_volume},	/* initial cutoff */
-	{PARM_BYTE, 0, 15, awe_fx_filterQ},	/* initial resonance */
-
-	{PARM_WORD, 0, 0xffff, NULL},	/* sample start */
-	{PARM_WORD, 0, 0xffff, NULL},	/* loop start */
-	{PARM_WORD, 0, 0xffff, NULL},	/* loop end */
-	{PARM_WORD, 0, 0xffff, NULL},	/* coarse sample start */
-	{PARM_WORD, 0, 0xffff, NULL},	/* coarse loop start */
-	{PARM_WORD, 0, 0xffff, NULL},	/* coarse loop end */
-	{PARM_BYTE, 0, 0xff, awe_set_volume},	/* initial attenuation */
-};
-
-
-static unsigned char
-FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
-{
-	int effect = 0;
-	int on = 0;
-	if (lay && (on = FX_ON(lay, type)) != 0)
-		effect = lay->val[type];
-	if (!on && (on = FX_ON(rec, type)) != 0)
-		effect = rec->val[type];
-	if (on == FX_FLAG_ADD) {
-		if (parm_defs[type].type == PARM_SIGN) {
-			if (value > 0x7f)
-				effect += (int)value - 0x100;
-			else
-				effect += (int)value;
-		} else {
-			effect += (int)value;
-		}
-	}
-	if (on) {
-		if (effect < parm_defs[type].low)
-			effect = parm_defs[type].low;
-		else if (effect > parm_defs[type].high)
-			effect = parm_defs[type].high;
-		return (unsigned char)effect;
-	}
-	return value;
-}
-
-/* get word effect value */
-static unsigned short
-FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
-{
-	int effect = 0;
-	int on = 0;
-	if (lay && (on = FX_ON(lay, type)) != 0)
-		effect = lay->val[type];
-	if (!on && (on = FX_ON(rec, type)) != 0)
-		effect = rec->val[type];
-	if (on == FX_FLAG_ADD)
-		effect += (int)value;
-	if (on) {
-		if (effect < parm_defs[type].low)
-			effect = parm_defs[type].low;
-		else if (effect > parm_defs[type].high)
-			effect = parm_defs[type].high;
-		return (unsigned short)effect;
-	}
-	return value;
-}
-
-/* get word (upper=type1/lower=type2) effect value */
-static unsigned short
-FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
-{
-	unsigned short tmp;
-	tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
-	tmp <<= 8;
-	tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
-	return tmp;
-}
-
-/* address offset */
-static int
-FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
-{
-	int addr = 0;
-	if (lay && FX_ON(lay, hi))
-		addr = (short)lay->val[hi];
-	else if (FX_ON(rec, hi))
-		addr = (short)rec->val[hi];
-	addr = addr << 15;
-	if (lay && FX_ON(lay, lo))
-		addr += (short)lay->val[lo];
-	else if (FX_ON(rec, lo))
-		addr += (short)rec->val[lo];
-	if (!(mode & AWE_SAMPLE_8BITS))
-		addr /= 2;
-	return addr;
-}
-
-
-/*
- * turn on/off sample
- */
-
-/* table for volume target calculation */
-static unsigned short voltarget[16] = { 
-   0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
-   0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
-};
-
-static void
-awe_note_on(int voice)
-{
-	unsigned int temp;
-	int addr;
-	int vtarget, ftarget, ptarget, pitch;
-	awe_voice_info *vp;
-	awe_voice_parm_block *parm;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	/* A voice sample must assigned before calling */
-	if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-		return;
-
-	parm = (awe_voice_parm_block*)&vp->parm;
-
-	/* channel to be silent and idle */
-	awe_poke(AWE_DCYSUSV(voice), 0x0080);
-	awe_poke(AWE_VTFT(voice), 0x0000FFFF);
-	awe_poke(AWE_CVCF(voice), 0x0000FFFF);
-	awe_poke(AWE_PTRX(voice), 0);
-	awe_poke(AWE_CPF(voice), 0);
-
-	/* set pitch offset */
-	awe_set_pitch(voice, TRUE);
-
-	/* modulation & volume envelope */
-	if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) {
-		awe_poke(AWE_ENVVAL(voice), 0xBFFF);
-		pitch = (parm->env1pit<<4) + voices[voice].apitch;
-		if (pitch > 0xffff) pitch = 0xffff;
-		/* calculate filter target */
-		ftarget = parm->cutoff + parm->env1fc;
-		limitvalue(ftarget, 0, 255);
-		ftarget <<= 8;
-	} else {
-		awe_poke(AWE_ENVVAL(voice),
-			 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay));
-		ftarget = parm->cutoff;
-		ftarget <<= 8;
-		pitch = voices[voice].apitch;
-	}
-
-	/* calcualte pitch target */
-	if (pitch != 0xffff) {
-		ptarget = 1 << (pitch >> 12);
-		if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710;
-		if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710;
-		if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710;
-		ptarget += (ptarget>>1);
-		if (ptarget > 0xffff) ptarget = 0xffff;
-
-	} else ptarget = 0xffff;
-	if (parm->modatk >= 0x80)
-		awe_poke(AWE_ATKHLD(voice),
-			 FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f);
-	else
-		awe_poke(AWE_ATKHLD(voice),
-			 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
-				 vp->parm.modatkhld));
-	awe_poke(AWE_DCYSUS(voice),
-		 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
-			  vp->parm.moddcysus));
-
-	if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) {
-		awe_poke(AWE_ENVVOL(voice), 0xBFFF);
-		vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4);
-	} else {
-		awe_poke(AWE_ENVVOL(voice),
-			 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
-		vtarget = 0;
-	}
-	if (parm->volatk >= 0x80)
-		awe_poke(AWE_ATKHLDV(voice),
-			 FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f);
-	else
-		awe_poke(AWE_ATKHLDV(voice),
-			 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
-			 vp->parm.volatkhld));
-	/* decay/sustain parameter for volume envelope must be set at last */
-
-	/* cutoff and volume */
-	awe_set_volume(voice, TRUE);
-
-	/* modulation envelope heights */
-	awe_poke(AWE_PEFE(voice),
-		 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
-			 vp->parm.pefe));
-
-	/* lfo1/2 delay */
-	awe_poke(AWE_LFO1VAL(voice),
-		 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
-	awe_poke(AWE_LFO2VAL(voice),
-		 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
-
-	/* lfo1 pitch & cutoff shift */
-	awe_fx_fmmod(voice, TRUE);
-	/* lfo1 volume & freq */
-	awe_fx_tremfrq(voice, TRUE);
-	/* lfo2 pitch & freq */
-	awe_fx_fm2frq2(voice, TRUE);
-	/* pan & loop start */
-	awe_set_pan(voice, TRUE);
-
-	/* chorus & loop end (chorus 8bit, MSB) */
-	addr = vp->loopend - 1;
-	addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
-			  AWE_FX_COARSE_LOOP_END, vp->mode);
-	temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
-	temp = (temp <<24) | (unsigned int)addr;
-	awe_poke_dw(AWE_CSL(voice), temp);
-	DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
-
-	/* Q & current address (Q 4bit value, MSB) */
-	addr = vp->start - 1;
-	addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
-			  AWE_FX_COARSE_SAMPLE_START, vp->mode);
-	temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
-	temp = (temp<<28) | (unsigned int)addr;
-	awe_poke_dw(AWE_CCCA(voice), temp);
-	DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
-
-	/* clear unknown registers */
-	awe_poke_dw(AWE_00A0(voice), 0);
-	awe_poke_dw(AWE_0080(voice), 0);
-
-	/* reset volume */
-	awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
-	awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
-
-	/* set reverb */
-	temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
-	temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux;
-	awe_poke_dw(AWE_PTRX(voice), temp);
-	awe_poke_dw(AWE_CPF(voice), ptarget << 16);
-	/* turn on envelope */
-	awe_poke(AWE_DCYSUSV(voice),
-		 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
-			  vp->parm.voldcysus));
-
-	voices[voice].state = AWE_ST_ON;
-
-	/* clear voice position for the next note on this channel */
-	if (SINGLE_LAYER_MODE()) {
-		FX_UNSET(fx, AWE_FX_SAMPLE_START);
-		FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
-	}
-}
-
-
-/* turn off the voice */
-static void
-awe_note_off(int voice)
-{
-	awe_voice_info *vp;
-	unsigned short tmp;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	if ((vp = voices[voice].sample) == NULL) {
-		voices[voice].state = AWE_ST_OFF;
-		return;
-	}
-
-	tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
-			       (unsigned char)vp->parm.modrelease);
-	awe_poke(AWE_DCYSUS(voice), tmp);
-	tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
-			       (unsigned char)vp->parm.volrelease);
-	awe_poke(AWE_DCYSUSV(voice), tmp);
-	voices[voice].state = AWE_ST_RELEASED;
-}
-
-/* force to terminate the voice (no releasing echo) */
-static void
-awe_terminate(int voice)
-{
-	awe_poke(AWE_DCYSUSV(voice), 0x807F);
-	awe_tweak_voice(voice);
-	voices[voice].state = AWE_ST_OFF;
-}
-
-/* turn off other voices with the same exclusive class (for drums) */
-static void
-awe_exclusive_off(int voice)
-{
-	int i, exclass;
-
-	if (voices[voice].sample == NULL)
-		return;
-	if ((exclass = voices[voice].sample->exclusiveClass) == 0)
-		return;	/* not exclusive */
-
-	/* turn off voices with the same class */
-	for (i = 0; i < awe_max_voices; i++) {
-		if (i != voice && IS_PLAYING(i) &&
-		    voices[i].sample && voices[i].ch == voices[voice].ch &&
-		    voices[i].sample->exclusiveClass == exclass) {
-			DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
-			awe_terminate(i);
-			awe_voice_init(i, TRUE);
-		}
-	}
-}
-
-
-/*
- * change the parameters of an audible voice
- */
-
-/* change pitch */
-static void
-awe_set_pitch(int voice, int forced)
-{
-	if (IS_NO_EFFECT(voice) && !forced) return;
-	awe_poke(AWE_IP(voice), voices[voice].apitch);
-	DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
-}
-
-/* calculate & change pitch */
-static void
-awe_set_voice_pitch(int voice, int forced)
-{
-	awe_calc_pitch(voice);
-	awe_set_pitch(voice, forced);
-}
-
-/* change volume & cutoff */
-static void
-awe_set_volume(int voice, int forced)
-{
-	awe_voice_info *vp;
-	unsigned short tmp2;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	if (!IS_PLAYING(voice) && !forced) return;
-	if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-		return;
-
-	tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF,
-		       (unsigned char)voices[voice].acutoff);
-	tmp2 = (tmp2 << 8);
-	tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
-			(unsigned char)voices[voice].avol);
-	awe_poke(AWE_IFATN(voice), tmp2);
-}
-
-/* calculate & change volume */
-static void
-awe_set_voice_vol(int voice, int forced)
-{
-	if (IS_EMPTY(voice))
-		return;
-	awe_calc_volume(voice);
-	awe_set_volume(voice, forced);
-}
-
-
-/* change pan; this could make a click noise.. */
-static void
-awe_set_pan(int voice, int forced)
-{
-	unsigned int temp;
-	int addr;
-	awe_voice_info *vp;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	if (IS_NO_EFFECT(voice) && !forced) return;
-	if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-		return;
-
-	/* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
-	if (vp->fixpan > 0)	/* 0-127 */
-		temp = 255 - (int)vp->fixpan * 2;
-	else {
-		int pos = 0;
-		if (vp->pan >= 0) /* 0-127 */
-			pos = (int)vp->pan * 2 - 128;
-		pos += voices[voice].cinfo->panning; /* -128 - 127 */
-		temp = 127 - pos;
-	}
-	limitvalue(temp, 0, 255);
-	if (ctrls[AWE_MD_PAN_EXCHANGE]) {
-		temp = 255 - temp;
-	}
-	if (forced || temp != voices[voice].apan) {
-		voices[voice].apan = temp;
-		if (temp == 0)
-			voices[voice].aaux = 0xff;
-		else
-			voices[voice].aaux = (-temp) & 0xff;
-		addr = vp->loopstart - 1;
-		addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
-				  AWE_FX_COARSE_LOOP_START, vp->mode);
-		temp = (temp<<24) | (unsigned int)addr;
-		awe_poke_dw(AWE_PSST(voice), temp);
-		DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
-	}
-}
-
-/* effects change during playing */
-static void
-awe_fx_fmmod(int voice, int forced)
-{
-	awe_voice_info *vp;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	if (IS_NO_EFFECT(voice) && !forced) return;
-	if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-		return;
-	awe_poke(AWE_FMMOD(voice),
-		 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
-			 vp->parm.fmmod));
-}
-
-/* set tremolo (lfo1) volume & frequency */
-static void
-awe_fx_tremfrq(int voice, int forced)
-{
-	awe_voice_info *vp;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	if (IS_NO_EFFECT(voice) && !forced) return;
-	if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-		return;
-	awe_poke(AWE_TREMFRQ(voice),
-		 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
-			 vp->parm.tremfrq));
-}
-
-/* set lfo2 pitch & frequency */
-static void
-awe_fx_fm2frq2(int voice, int forced)
-{
-	awe_voice_info *vp;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	if (IS_NO_EFFECT(voice) && !forced) return;
-	if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-		return;
-	awe_poke(AWE_FM2FRQ2(voice),
-		 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
-			 vp->parm.fm2frq2));
-}
-
-
-/* Q & current address (Q 4bit value, MSB) */
-static void
-awe_fx_filterQ(int voice, int forced)
-{
-	unsigned int addr;
-	awe_voice_info *vp;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	if (IS_NO_EFFECT(voice) && !forced) return;
-	if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-		return;
-
-	addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
-	addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
-	awe_poke_dw(AWE_CCCA(voice), addr);
-}
-
-/*
- * calculate pitch offset
- *
- * 0xE000 is no pitch offset at 44100Hz sample.
- * Every 4096 is one octave.
- */
-
-static void
-awe_calc_pitch(int voice)
-{
-	voice_info *vp = &voices[voice];
-	awe_voice_info *ap;
-	awe_chan_info *cp = voices[voice].cinfo;
-	int offset;
-
-	/* search voice information */
-	if ((ap = vp->sample) == NULL)
-			return;
-	if (ap->index == 0) {
-		DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-		if (awe_set_sample((awe_voice_list*)ap) == 0)
-			return;
-	}
-
-	/* calculate offset */
-	if (ap->fixkey >= 0) {
-		DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
-		offset = (ap->fixkey - ap->root) * 4096 / 12;
-	} else {
-		DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
-		offset = (vp->note - ap->root) * 4096 / 12;
-		DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
-	}
-	offset = (offset * ap->scaleTuning) / 100;
-	DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
-	offset += ap->tune * 4096 / 1200;
-	DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
-	if (cp->bender != 0) {
-		DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
-		/* (819200: 1 semitone) ==> (4096: 12 semitones) */
-		offset += cp->bender * cp->bender_range / 2400;
-	}
-
-	/* add initial pitch correction */
-	if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
-		offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
-	else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
-		offset += cp->fx.val[AWE_FX_INIT_PITCH];
-
-	/* 0xe000: root pitch */
-	vp->apitch = 0xe000 + ap->rate_offset + offset;
-	DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
-	if (vp->apitch > 0xffff)
-		vp->apitch = 0xffff;
-	if (vp->apitch < 0)
-		vp->apitch = 0;
-}
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-/* calculate MIDI key and semitone from the specified frequency */
-static void
-awe_calc_pitch_from_freq(int voice, int freq)
-{
-	voice_info *vp = &voices[voice];
-	awe_voice_info *ap;
-	FX_Rec *fx = &voices[voice].cinfo->fx;
-	FX_Rec *fx_lay = NULL;
-	int offset;
-	int note;
-
-	if (voices[voice].layer < MAX_LAYERS)
-		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-	/* search voice information */
-	if ((ap = vp->sample) == NULL)
-		return;
-	if (ap->index == 0) {
-		DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-		if (awe_set_sample((awe_voice_list*)ap) == 0)
-			return;
-	}
-	note = freq_to_note(freq);
-	offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
-	offset = (offset * ap->scaleTuning) / 100;
-	if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
-		offset += fx_lay->val[AWE_FX_INIT_PITCH];
-	else if (FX_ON(fx, AWE_FX_INIT_PITCH))
-		offset += fx->val[AWE_FX_INIT_PITCH];
-	vp->apitch = 0xe000 + ap->rate_offset + offset;
-	if (vp->apitch > 0xffff)
-		vp->apitch = 0xffff;
-	if (vp->apitch < 0)
-		vp->apitch = 0;
-}
-#endif /* AWE_HAS_GUS_COMPATIBILITY */
-
-
-/*
- * calculate volume attenuation
- *
- * Voice volume is controlled by volume attenuation parameter.
- * So volume becomes maximum when avol is 0 (no attenuation), and
- * minimum when 255 (-96dB or silence).
- */
-
-static int vol_table[128] = {
-	255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
-	47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
-	31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
-	22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
-	15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
-	10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
-	6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
-	2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
-};
-
-/* tables for volume->attenuation calculation */
-static unsigned char voltab1[128] = {
-   0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-   0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
-   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
-   0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
-   0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
-   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
-   0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
-   0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-   0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
-   0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
-   0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
-   0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
-   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char voltab2[128] = {
-   0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
-   0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
-   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
-   0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
-   0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
-   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
-   0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
-   0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
-   0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
-   0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
-   0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
-   0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char expressiontab[128] = {
-   0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
-   0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
-   0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
-   0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
-   0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
-   0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
-   0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
-   0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
-   0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
-   0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
-   0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
-   0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
-   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static void
-awe_calc_volume(int voice)
-{
-	voice_info *vp = &voices[voice];
-	awe_voice_info *ap;
-	awe_chan_info *cp = voices[voice].cinfo;
-	int vol;
-
-	/* search voice information */
-	if ((ap = vp->sample) == NULL)
-		return;
-
-	ap = vp->sample;
-	if (ap->index == 0) {
-		DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-		if (awe_set_sample((awe_voice_list*)ap) == 0)
-			return;
-	}
-	
-	if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {
-		int main_vol = cp->main_vol * ap->amplitude / 127;
-		limitvalue(vp->velocity, 0, 127);
-		limitvalue(main_vol, 0, 127);
-		limitvalue(cp->expression_vol, 0, 127);
-
-		vol = voltab1[main_vol] + voltab2[vp->velocity];
-		vol = (vol * 8) / 3;
-		vol += ap->attenuation;
-		if (cp->expression_vol < 127)
-			vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;
-		vol += atten_offset;
-		if (atten_relative)
-			vol += ctrls[AWE_MD_ZERO_ATTEN];
-		limitvalue(vol, 0, 255);
-		vp->avol = vol;
-		
-	} else {
-		/* 0 - 127 */
-		vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
-		vol = vol * ap->amplitude / 127;
-
-		if (vol < 0) vol = 0;
-		if (vol > 127) vol = 127;
-
-		/* calc to attenuation */
-		vol = vol_table[vol];
-		vol += (int)ap->attenuation;
-		vol += atten_offset;
-		if (atten_relative)
-			vol += ctrls[AWE_MD_ZERO_ATTEN];
-		if (vol > 255) vol = 255;
-
-		vp->avol = vol;
-	}
-	if (cp->bank !=  AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {
-		int atten;
-		if (vp->velocity < 70) atten = 70;
-		else atten = vp->velocity;
-		vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;
-	} else {
-		vp->acutoff = ap->parm.cutoff;
-	}
-	DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
-}
-
-/* change master volume */
-static void
-awe_change_master_volume(short val)
-{
-	limitvalue(val, 0, 127);
-	atten_offset = vol_table[val];
-	atten_relative = TRUE;
-	awe_update_volume();
-}
-
-/* update volumes of all available channels */
-static void awe_update_volume(void)
-{
-	int i;
-	for (i = 0; i < awe_max_voices; i++)
-		awe_set_voice_vol(i, TRUE);
-}
-
-/* set sostenuto on */
-static void awe_sostenuto_on(int voice, int forced)
-{
-	if (IS_NO_EFFECT(voice) && !forced) return;
-	voices[voice].sostenuto = 127;
-}
-
-
-/* drop sustain */
-static void awe_sustain_off(int voice, int forced)
-{
-	if (voices[voice].state == AWE_ST_SUSTAINED) {
-		awe_note_off(voice);
-		awe_fx_init(voices[voice].ch);
-		awe_voice_init(voice, FALSE);
-	}
-}
-
-
-/* terminate and initialize voice */
-static void awe_terminate_and_init(int voice, int forced)
-{
-	awe_terminate(voice);
-	awe_fx_init(voices[voice].ch);
-	awe_voice_init(voice, TRUE);
-}
-
-
-/*
- * synth operation routines
- */
-
-#define AWE_VOICE_KEY(v)	(0x8000 | (v))
-#define AWE_CHAN_KEY(c,n)	(((c) << 8) | ((n) + 1))
-#define KEY_CHAN_MATCH(key,c)	(((key) >> 8) == (c))
-
-/* initialize the voice */
-static void
-awe_voice_init(int voice, int init_all)
-{
-	voice_info *vp = &voices[voice];
-
-	/* reset voice search key */
-	if (playing_mode == AWE_PLAY_DIRECT)
-		vp->key = AWE_VOICE_KEY(voice);
-	else
-		vp->key = 0;
-
-	/* clear voice mapping */
-	voice_alloc->map[voice] = 0;
-
-	/* touch the timing flag */
-	vp->time = current_alloc_time;
-
-	/* initialize other parameters if necessary */
-	if (init_all) {
-		vp->note = -1;
-		vp->velocity = 0;
-		vp->sostenuto = 0;
-
-		vp->sample = NULL;
-		vp->cinfo = &channels[voice];
-		vp->ch = voice;
-		vp->state = AWE_ST_OFF;
-
-		/* emu8000 parameters */
-		vp->apitch = 0;
-		vp->avol = 255;
-		vp->apan = -1;
-	}
-}
-
-/* clear effects */
-static void awe_fx_init(int ch)
-{
-	if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {
-		memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));
-		memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));
-	}
-}
-
-/* initialize channel info */
-static void awe_channel_init(int ch, int init_all)
-{
-	awe_chan_info *cp = &channels[ch];
-	cp->channel = ch;
-	if (init_all) {
-		cp->panning = 0; /* zero center */
-		cp->bender_range = 200; /* sense * 100 */
-		cp->main_vol = 127;
-		if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
-			cp->instr = ctrls[AWE_MD_DEF_DRUM];
-			cp->bank = AWE_DRUM_BANK;
-		} else {
-			cp->instr = ctrls[AWE_MD_DEF_PRESET];
-			cp->bank = ctrls[AWE_MD_DEF_BANK];
-		}
-	}
-
-	cp->bender = 0; /* zero tune skew */
-	cp->expression_vol = 127;
-	cp->chan_press = 0;
-	cp->sustained = 0;
-
-	if (! ctrls[AWE_MD_KEEP_EFFECT]) {
-		memset(&cp->fx, 0, sizeof(cp->fx));
-		memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));
-	}
-}
-
-
-/* change the voice parameters; voice = channel */
-static void awe_voice_change(int voice, fx_affect_func func)
-{
-	int i; 
-	switch (playing_mode) {
-	case AWE_PLAY_DIRECT:
-		func(voice, FALSE);
-		break;
-	case AWE_PLAY_INDIRECT:
-		for (i = 0; i < awe_max_voices; i++)
-			if (voices[i].key == AWE_VOICE_KEY(voice))
-				func(i, FALSE);
-		break;
-	default:
-		for (i = 0; i < awe_max_voices; i++)
-			if (KEY_CHAN_MATCH(voices[i].key, voice))
-				func(i, FALSE);
-		break;
-	}
-}
-
-
-/*
- * device open / close
- */
-
-/* open device:
- *   reset status of all voices, and clear sample position flag
- */
-static int
-awe_open(int dev, int mode)
-{
-	if (awe_busy)
-		return -EBUSY;
-
-	awe_busy = TRUE;
-
-	/* set default mode */
-	awe_init_ctrl_parms(FALSE);
-	atten_relative = TRUE;
-	atten_offset = 0;
-	drum_flags = DEFAULT_DRUM_FLAGS;
-	playing_mode = AWE_PLAY_INDIRECT;
-
-	/* reset voices & channels */
-	awe_reset(dev);
-
-	patch_opened = 0;
-
-	return 0;
-}
-
-
-/* close device:
- *   reset all voices again (terminate sounds)
- */
-static void
-awe_close(int dev)
-{
-	awe_reset(dev);
-	awe_busy = FALSE;
-}
-
-
-/* set miscellaneous mode parameters
- */
-static void
-awe_init_ctrl_parms(int init_all)
-{
-	int i;
-	for (i = 0; i < AWE_MD_END; i++) {
-		if (init_all || ctrl_parms[i].init_each_time)
-			ctrls[i] = ctrl_parms[i].value;
-	}
-}
-
-
-/* sequencer I/O control:
- */
-static int
-awe_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-	switch (cmd) {
-	case SNDCTL_SYNTH_INFO:
-		if (playing_mode == AWE_PLAY_DIRECT)
-			awe_info.nr_voices = awe_max_voices;
-		else
-			awe_info.nr_voices = AWE_MAX_CHANNELS;
-		if (copy_to_user(arg, &awe_info, sizeof(awe_info)))
-			return -EFAULT;
-		return 0;
-		break;
-
-	case SNDCTL_SEQ_RESETSAMPLES:
-		awe_reset(dev);
-		awe_reset_samples();
-		return 0;
-		break;
-
-	case SNDCTL_SEQ_PERCMODE:
-		/* what's this? */
-		return 0;
-		break;
-
-	case SNDCTL_SYNTH_MEMAVL:
-		return memsize - awe_free_mem_ptr() * 2;
-		break;
-
-	default:
-		printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
-		return -EINVAL;
-		break;
-	}
-}
-
-
-static int voice_in_range(int voice)
-{
-	if (playing_mode == AWE_PLAY_DIRECT) {
-		if (voice < 0 || voice >= awe_max_voices)
-			return FALSE;
-	} else {
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return FALSE;
-	}
-	return TRUE;
-}
-
-static void release_voice(int voice, int do_sustain)
-{
-	if (IS_NO_SOUND(voice))
-		return;
-	if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
-			    voices[voice].sostenuto == 127))
-		voices[voice].state = AWE_ST_SUSTAINED;
-	else {
-		awe_note_off(voice);
-		awe_fx_init(voices[voice].ch);
-		awe_voice_init(voice, FALSE);
-	}
-}
-
-/* release all notes */
-static void awe_note_off_all(int do_sustain)
-{
-	int i;
-	for (i = 0; i < awe_max_voices; i++)
-		release_voice(i, do_sustain);
-}
-
-/* kill a voice:
- *   not terminate, just release the voice.
- */
-static int
-awe_kill_note(int dev, int voice, int note, int velocity)
-{
-	int i, v2, key;
-
-	DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
-	if (! voice_in_range(voice))
-		return -EINVAL;
-
-	switch (playing_mode) {
-	case AWE_PLAY_DIRECT:
-	case AWE_PLAY_INDIRECT:
-		key = AWE_VOICE_KEY(voice);
-		break;
-
-	case AWE_PLAY_MULTI2:
-		v2 = voice_alloc->map[voice] >> 8;
-		voice_alloc->map[voice] = 0;
-		voice = v2;
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return -EINVAL;
-		/* continue to below */
-	default:
-		key = AWE_CHAN_KEY(voice, note);
-		break;
-	}
-
-	for (i = 0; i < awe_max_voices; i++) {
-		if (voices[i].key == key)
-			release_voice(i, TRUE);
-	}
-	return 0;
-}
-
-
-static void start_or_volume_change(int voice, int velocity)
-{
-	voices[voice].velocity = velocity;
-	awe_calc_volume(voice);
-	if (voices[voice].state == AWE_ST_STANDBY)
-		awe_note_on(voice);
-	else if (voices[voice].state == AWE_ST_ON)
-		awe_set_volume(voice, FALSE);
-}
-
-static void set_and_start_voice(int voice, int state)
-{
-	/* calculate pitch & volume parameters */
-	voices[voice].state = state;
-	awe_calc_pitch(voice);
-	awe_calc_volume(voice);
-	if (state == AWE_ST_ON)
-		awe_note_on(voice);
-}
-
-/* start a voice:
- *   if note is 255, identical with aftertouch function.
- *   Otherwise, start a voice with specified not and volume.
- */
-static int
-awe_start_note(int dev, int voice, int note, int velocity)
-{
-	int i, key, state, volonly;
-
-	DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
-	if (! voice_in_range(voice))
-		return -EINVAL;
-	    
-	if (velocity == 0)
-		state = AWE_ST_STANDBY; /* stand by for playing */
-	else
-		state = AWE_ST_ON;	/* really play */
-	volonly = FALSE;
-
-	switch (playing_mode) {
-	case AWE_PLAY_DIRECT:
-	case AWE_PLAY_INDIRECT:
-		key = AWE_VOICE_KEY(voice);
-		if (note == 255)
-			volonly = TRUE;
-		break;
-
-	case AWE_PLAY_MULTI2:
-		voice = voice_alloc->map[voice] >> 8;
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return -EINVAL;
-		/* continue to below */
-	default:
-		if (note >= 128) { /* key volume mode */
-			note -= 128;
-			volonly = TRUE;
-		}
-		key = AWE_CHAN_KEY(voice, note);
-		break;
-	}
-
-	/* dynamic volume change */
-	if (volonly) {
-		for (i = 0; i < awe_max_voices; i++) {
-			if (voices[i].key == key)
-				start_or_volume_change(i, velocity);
-		}
-		return 0;
-	}
-
-	/* if the same note still playing, stop it */
-	if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {
-		for (i = 0; i < awe_max_voices; i++)
-			if (voices[i].key == key) {
-				if (voices[i].state == AWE_ST_ON) {
-					awe_note_off(i);
-					awe_voice_init(i, FALSE);
-				} else if (voices[i].state == AWE_ST_STANDBY)
-					awe_voice_init(i, TRUE);
-			}
-	}
-
-	/* allocate voices */
-	if (playing_mode == AWE_PLAY_DIRECT)
-		awe_alloc_one_voice(voice, note, velocity);
-	else
-		awe_alloc_multi_voices(voice, note, velocity, key);
-
-	/* turn off other voices exlusively (for drums) */
-	for (i = 0; i < awe_max_voices; i++)
-		if (voices[i].key == key)
-			awe_exclusive_off(i);
-
-	/* set up pitch and volume parameters */
-	for (i = 0; i < awe_max_voices; i++) {
-		if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
-			set_and_start_voice(i, state);
-	}
-
-	return 0;
-}
-
-
-/* calculate hash key */
-static int
-awe_search_key(int bank, int preset, int note)
-{
-	unsigned int key;
-
-#if 1 /* new hash table */
-	if (bank == AWE_DRUM_BANK)
-		key = preset + note + 128;
-	else
-		key = bank + preset;
-#else
-	key = preset;
-#endif
-	key %= AWE_MAX_PRESETS;
-
-	return (int)key;
-}
-
-
-/* search instrument from hash table */
-static awe_voice_list *
-awe_search_instr(int bank, int preset, int note)
-{
-	awe_voice_list *p;
-	int key, key2;
-
-	key = awe_search_key(bank, preset, note);
-	for (p = preset_table[key]; p; p = p->next_bank) {
-		if (p->instr == preset && p->bank == bank)
-			return p;
-	}
-	key2 = awe_search_key(bank, preset, 0); /* search default */
-	if (key == key2)
-		return NULL;
-	for (p = preset_table[key2]; p; p = p->next_bank) {
-		if (p->instr == preset && p->bank == bank)
-			return p;
-	}
-	return NULL;
-}
-
-
-/* assign the instrument to a voice */
-static int
-awe_set_instr_2(int dev, int voice, int instr_no)
-{
-	if (playing_mode == AWE_PLAY_MULTI2) {
-		voice = voice_alloc->map[voice] >> 8;
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return -EINVAL;
-	}
-	return awe_set_instr(dev, voice, instr_no);
-}
-
-/* assign the instrument to a channel; voice is the channel number */
-static int
-awe_set_instr(int dev, int voice, int instr_no)
-{
-	awe_chan_info *cinfo;
-
-	if (! voice_in_range(voice))
-		return -EINVAL;
-
-	if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
-		return -EINVAL;
-
-	cinfo = &channels[voice];
-	cinfo->instr = instr_no;
-	DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
-
-	return 0;
-}
-
-
-/* reset all voices; terminate sounds and initialize parameters */
-static void
-awe_reset(int dev)
-{
-	int i;
-	current_alloc_time = 0;
-	/* don't turn off voice 31 and 32.  they are used also for FM voices */
-	for (i = 0; i < awe_max_voices; i++) {
-		awe_terminate(i);
-		awe_voice_init(i, TRUE);
-	}
-	for (i = 0; i < AWE_MAX_CHANNELS; i++)
-		awe_channel_init(i, TRUE);
-	for (i = 0; i < 16; i++) {
-		awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
-		awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
-	}
-	awe_init_fm();
-	awe_tweak();
-}
-
-
-/* hardware specific control:
- *   GUS specific and AWE32 specific controls are available.
- */
-static void
-awe_hw_control(int dev, unsigned char *event)
-{
-	int cmd = event[2];
-	if (cmd & _AWE_MODE_FLAG)
-		awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-	else
-		awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
-#endif
-}
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* GUS compatible controls */
-static void
-awe_hw_gus_control(int dev, int cmd, unsigned char *event)
-{
-	int voice, i, key;
-	unsigned short p1;
-	short p2;
-	int plong;
-
-	if (MULTI_LAYER_MODE())
-		return;
-	if (cmd == _GUS_NUMVOICES)
-		return;
-
-	voice = event[3];
-	if (! voice_in_range(voice))
-		return;
-
-	p1 = *(unsigned short *) &event[4];
-	p2 = *(short *) &event[6];
-	plong = *(int*) &event[4];
-
-	switch (cmd) {
-	case _GUS_VOICESAMPLE:
-		awe_set_instr(dev, voice, p1);
-		return;
-
-	case _GUS_VOICEBALA:
-		/* 0 to 15 --> -128 to 127 */
-		awe_panning(dev, voice, ((int)p1 << 4) - 128);
-		return;
-
-	case _GUS_VOICEVOL:
-	case _GUS_VOICEVOL2:
-		/* not supported yet */
-		return;
-
-	case _GUS_RAMPRANGE:
-	case _GUS_RAMPRATE:
-	case _GUS_RAMPMODE:
-	case _GUS_RAMPON:
-	case _GUS_RAMPOFF:
-		/* volume ramping not supported */
-		return;
-
-	case _GUS_VOLUME_SCALE:
-		return;
-
-	case _GUS_VOICE_POS:
-		FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
-		       (short)(plong & 0x7fff));
-		FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
-		       (plong >> 15) & 0xffff);
-		return;
-	}
-
-	key = AWE_VOICE_KEY(voice);
-	for (i = 0; i < awe_max_voices; i++) {
-		if (voices[i].key == key) {
-			switch (cmd) {
-			case _GUS_VOICEON:
-				awe_note_on(i);
-				break;
-
-			case _GUS_VOICEOFF:
-				awe_terminate(i);
-				awe_fx_init(voices[i].ch);
-				awe_voice_init(i, TRUE);
-				break;
-
-			case _GUS_VOICEFADE:
-				awe_note_off(i);
-				awe_fx_init(voices[i].ch);
-				awe_voice_init(i, FALSE);
-				break;
-
-			case _GUS_VOICEFREQ:
-				awe_calc_pitch_from_freq(i, plong);
-				break;
-			}
-		}
-	}
-}
-
-#endif /* gus_compat */
-
-
-/* AWE32 specific controls */
-static void
-awe_hw_awe_control(int dev, int cmd, unsigned char *event)
-{
-	int voice;
-	unsigned short p1;
-	short p2;
-	int i;
-
-	voice = event[3];
-	if (! voice_in_range(voice))
-		return;
-
-	if (playing_mode == AWE_PLAY_MULTI2) {
-		voice = voice_alloc->map[voice] >> 8;
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return;
-	}
-
-	p1 = *(unsigned short *) &event[4];
-	p2 = *(short *) &event[6];
-
-	switch (cmd) {
-	case _AWE_DEBUG_MODE:
-		ctrls[AWE_MD_DEBUG_MODE] = p1;
-		printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]);
-		break;
-	case _AWE_REVERB_MODE:
-		ctrls[AWE_MD_REVERB_MODE] = p1;
-		awe_update_reverb_mode();
-		break;
-
-	case _AWE_CHORUS_MODE:
-		ctrls[AWE_MD_CHORUS_MODE] = p1;
-		awe_update_chorus_mode();
-		break;
-		      
-	case _AWE_REMOVE_LAST_SAMPLES:
-		DEBUG(0,printk("AWE32: remove last samples\n"));
-		awe_reset(0);
-		if (locked_sf_id > 0)
-			awe_remove_samples(locked_sf_id);
-		break;
-
-	case _AWE_INITIALIZE_CHIP:
-		awe_initialize();
-		break;
-
-	case _AWE_SEND_EFFECT:
-		i = -1;
-		if (p1 >= 0x100) {
-			i = (p1 >> 8);
-			if (i < 0 || i >= MAX_LAYERS)
-				break;
-		}
-		awe_send_effect(voice, i, p1, p2);
-		break;
-
-	case _AWE_RESET_CHANNEL:
-		awe_channel_init(voice, !p1);
-		break;
-		
-	case _AWE_TERMINATE_ALL:
-		awe_reset(0);
-		break;
-
-	case _AWE_TERMINATE_CHANNEL:
-		awe_voice_change(voice, awe_terminate_and_init);
-		break;
-
-	case _AWE_RELEASE_ALL:
-		awe_note_off_all(FALSE);
-		break;
-	case _AWE_NOTEOFF_ALL:
-		awe_note_off_all(TRUE);
-		break;
-
-	case _AWE_INITIAL_VOLUME:
-		DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
-		atten_relative = (char)p2;
-		atten_offset = (short)p1;
-		awe_update_volume();
-		break;
-
-	case _AWE_CHN_PRESSURE:
-		channels[voice].chan_press = p1;
-		awe_modwheel_change(voice, p1);
-		break;
-
-	case _AWE_CHANNEL_MODE:
-		DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
-		playing_mode = p1;
-		awe_reset(0);
-		break;
-
-	case _AWE_DRUM_CHANNELS:
-		DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
-		drum_flags = *(unsigned int*)&event[4];
-		break;
-
-	case _AWE_MISC_MODE:
-		DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2));
-		if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) {
-			ctrls[p1] = p2;
-			if (ctrl_parms[p1].update)
-				ctrl_parms[p1].update();
-		}
-		break;
-
-	case _AWE_EQUALIZER:
-		ctrls[AWE_MD_BASS_LEVEL] = p1;
-		ctrls[AWE_MD_TREBLE_LEVEL] = p2;
-		awe_update_equalizer();
-		break;
-
-	default:
-		DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
-		break;
-	}
-}
-
-
-/* change effects */
-static void
-awe_send_effect(int voice, int layer, int type, int val)
-{
-	awe_chan_info *cinfo;
-	FX_Rec *fx;
-	int mode;
-
-	cinfo = &channels[voice];
-	if (layer >= 0 && layer < MAX_LAYERS)
-		fx = &cinfo->fx_layer[layer];
-	else
-		fx = &cinfo->fx;
-
-	if (type & 0x40)
-		mode = FX_FLAG_OFF;
-	else if (type & 0x80)
-		mode = FX_FLAG_ADD;
-	else
-		mode = FX_FLAG_SET;
-	type &= 0x3f;
-
-	if (type >= 0 && type < AWE_FX_END) {
-		DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val));
-		if (mode == FX_FLAG_SET)
-			FX_SET(fx, type, val);
-		else if (mode == FX_FLAG_ADD)
-			FX_ADD(fx, type, val);
-		else
-			FX_UNSET(fx, type);
-		if (mode != FX_FLAG_OFF && parm_defs[type].realtime) {
-			DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice));
-			awe_voice_change(voice, parm_defs[type].realtime);
-		}
-	}
-}
-
-
-/* change modulation wheel; voice is already mapped on multi2 mode */
-static void
-awe_modwheel_change(int voice, int value)
-{
-	int i;
-	awe_chan_info *cinfo;
-
-	cinfo = &channels[voice];
-	i = value * ctrls[AWE_MD_MOD_SENSE] / 1200;
-	FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
-	awe_voice_change(voice, awe_fx_fmmod);
-	FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
-	awe_voice_change(voice, awe_fx_fm2frq2);
-}
-
-
-/* voice pressure change */
-static void
-awe_aftertouch(int dev, int voice, int pressure)
-{
-	int note;
-
-	DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
-	if (! voice_in_range(voice))
-		return;
-
-	switch (playing_mode) {
-	case AWE_PLAY_DIRECT:
-	case AWE_PLAY_INDIRECT:
-		awe_start_note(dev, voice, 255, pressure);
-		break;
-	case AWE_PLAY_MULTI2:
-		note = (voice_alloc->map[voice] & 0xff) - 1;
-		awe_key_pressure(dev, voice, note + 0x80, pressure);
-		break;
-	}
-}
-
-
-/* voice control change */
-static void
-awe_controller(int dev, int voice, int ctrl_num, int value)
-{
-	awe_chan_info *cinfo;
-
-	if (! voice_in_range(voice))
-		return;
-
-	if (playing_mode == AWE_PLAY_MULTI2) {
-		voice = voice_alloc->map[voice] >> 8;
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return;
-	}
-
-	cinfo = &channels[voice];
-
-	switch (ctrl_num) {
-	case CTL_BANK_SELECT: /* MIDI control #0 */
-		DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
-		if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
-		    !ctrls[AWE_MD_TOGGLE_DRUM_BANK])
-			break;
-		if (value < 0 || value > 255)
-			break;
-		cinfo->bank = value;
-		if (cinfo->bank == AWE_DRUM_BANK)
-			DRUM_CHANNEL_ON(cinfo->channel);
-		else
-			DRUM_CHANNEL_OFF(cinfo->channel);
-		awe_set_instr(dev, voice, cinfo->instr);
-		break;
-
-	case CTL_MODWHEEL: /* MIDI control #1 */
-		DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
-		awe_modwheel_change(voice, value);
-		break;
-
-	case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
-		DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
-		/* zero centered */
-		cinfo->bender = value;
-		awe_voice_change(voice, awe_set_voice_pitch);
-		break;
-
-	case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
-		DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
-		/* value = sense x 100 */
-		cinfo->bender_range = value;
-		/* no audible pitch change yet.. */
-		break;
-
-	case CTL_EXPRESSION: /* MIDI control #11 */
-		if (SINGLE_LAYER_MODE())
-			value /= 128;
-	case CTRL_EXPRESSION: /* SEQ1 V2 control */
-		DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
-		/* 0 - 127 */
-		cinfo->expression_vol = value;
-		awe_voice_change(voice, awe_set_voice_vol);
-		break;
-
-	case CTL_PAN:	/* MIDI control #10 */
-		DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
-		/* (0-127) -> signed 8bit */
-		cinfo->panning = value * 2 - 128;
-		if (ctrls[AWE_MD_REALTIME_PAN])
-			awe_voice_change(voice, awe_set_pan);
-		break;
-
-	case CTL_MAIN_VOLUME:	/* MIDI control #7 */
-		if (SINGLE_LAYER_MODE())
-			value = (value * 100) / 16383;
-	case CTRL_MAIN_VOLUME:	/* SEQ1 V2 control */
-		DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
-		/* 0 - 127 */
-		cinfo->main_vol = value;
-		awe_voice_change(voice, awe_set_voice_vol);
-		break;
-
-	case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
-		DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
-		FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
-		break;
-
-	case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
-		DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
-		FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
-		break;
-
-	case 120:  /* all sounds off */
-		awe_note_off_all(FALSE);
-		break;
-	case 123:  /* all notes off */
-		awe_note_off_all(TRUE);
-		break;
-
-	case CTL_SUSTAIN: /* MIDI control #64 */
-		cinfo->sustained = value;
-		if (value != 127)
-			awe_voice_change(voice, awe_sustain_off);
-		break;
-
-	case CTL_SOSTENUTO: /* MIDI control #66 */
-		if (value == 127)
-			awe_voice_change(voice, awe_sostenuto_on);
-		else
-			awe_voice_change(voice, awe_sustain_off);
-		break;
-
-	default:
-		DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
-			   voice, ctrl_num, value));
-		break;
-	}
-}
-
-
-/* voice pan change (value = -128 - 127) */
-static void
-awe_panning(int dev, int voice, int value)
-{
-	awe_chan_info *cinfo;
-
-	if (! voice_in_range(voice))
-		return;
-
-	if (playing_mode == AWE_PLAY_MULTI2) {
-		voice = voice_alloc->map[voice] >> 8;
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return;
-	}
-
-	cinfo = &channels[voice];
-	cinfo->panning = value;
-	DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
-	if (ctrls[AWE_MD_REALTIME_PAN])
-		awe_voice_change(voice, awe_set_pan);
-}
-
-
-/* volume mode change */
-static void
-awe_volume_method(int dev, int mode)
-{
-	/* not impremented */
-	DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
-}
-
-
-/* pitch wheel change: 0-16384 */
-static void
-awe_bender(int dev, int voice, int value)
-{
-	awe_chan_info *cinfo;
-
-	if (! voice_in_range(voice))
-		return;
-
-	if (playing_mode == AWE_PLAY_MULTI2) {
-		voice = voice_alloc->map[voice] >> 8;
-		if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-			return;
-	}
-
-	/* convert to zero centered value */
-	cinfo = &channels[voice];
-	cinfo->bender = value - 8192;
-	DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
-	awe_voice_change(voice, awe_set_voice_pitch);
-}
-
-
-/*
- * load a sound patch:
- *   three types of patches are accepted: AWE, GUS, and SYSEX.
- */
-
-static int
-awe_load_patch(int dev, int format, const char __user *addr,
-	       int offs, int count, int pmgr_flag)
-{
-	awe_patch_info patch;
-	int rc = 0;
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-	if (format == GUS_PATCH) {
-		return awe_load_guspatch(addr, offs, count, pmgr_flag);
-	} else
-#endif
-	if (format == SYSEX_PATCH) {
-		/* no system exclusive message supported yet */
-		return 0;
-	} else if (format != AWE_PATCH) {
-		printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format);
-		return -EINVAL;
-	}
-	
-	if (count < AWE_PATCH_INFO_SIZE) {
-		printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
-		return -EINVAL;
-	}
-	if (copy_from_user(((char*)&patch) + offs, addr + offs, 
-			   AWE_PATCH_INFO_SIZE - offs))
-		return -EFAULT;
-
-	count -= AWE_PATCH_INFO_SIZE;
-	if (count < patch.len) {
-		printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n",
-		       count, patch.len);
-		return -EINVAL;
-	}
-	
-	switch (patch.type) {
-	case AWE_LOAD_INFO:
-		rc = awe_load_info(&patch, addr, count);
-		break;
-	case AWE_LOAD_DATA:
-		rc = awe_load_data(&patch, addr, count);
-		break;
-	case AWE_OPEN_PATCH:
-		rc = awe_open_patch(&patch, addr, count);
-		break;
-	case AWE_CLOSE_PATCH:
-		rc = awe_close_patch(&patch, addr, count);
-		break;
-	case AWE_UNLOAD_PATCH:
-		rc = awe_unload_patch(&patch, addr, count);
-		break;
-	case AWE_REPLACE_DATA:
-		rc = awe_replace_data(&patch, addr, count);
-		break;
-	case AWE_MAP_PRESET:
-		rc = awe_load_map(&patch, addr, count);
-		break;
-	/* case AWE_PROBE_INFO:
-		rc = awe_probe_info(&patch, addr, count);
-		break;*/
-	case AWE_PROBE_DATA:
-		rc = awe_probe_data(&patch, addr, count);
-		break;
-	case AWE_REMOVE_INFO:
-		rc = awe_remove_info(&patch, addr, count);
-		break;
-	case AWE_LOAD_CHORUS_FX:
-		rc = awe_load_chorus_fx(&patch, addr, count);
-		break;
-	case AWE_LOAD_REVERB_FX:
-		rc = awe_load_reverb_fx(&patch, addr, count);
-		break;
-
-	default:
-		printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
-		       patch.type);
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-
-
-/* create an sf list record */
-static int
-awe_create_sf(int type, char *name)
-{
-	sf_list *rec;
-
-	/* terminate sounds */
-	awe_reset(0);
-	rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL);
-	if (rec == NULL)
-		return 1; /* no memory */
-	rec->sf_id = current_sf_id + 1;
-	rec->type = type;
-	if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0)
-		locked_sf_id = current_sf_id + 1;
-	rec->num_info = awe_free_info();
-	rec->num_sample = awe_free_sample();
-	rec->mem_ptr = awe_free_mem_ptr();
-	rec->infos = rec->last_infos = NULL;
-	rec->samples = rec->last_samples = NULL;
-
-	/* add to linked-list */
-	rec->next = NULL;
-	rec->prev = sftail;
-	if (sftail)
-		sftail->next = rec;
-	else
-		sfhead = rec;
-	sftail = rec;
-	current_sf_id++;
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-	rec->shared = NULL;
-	if (name)
-		memcpy(rec->name, name, AWE_PATCH_NAME_LEN);
-	else
-		strcpy(rec->name, "*TEMPORARY*");
-	if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) {
-		/* is the current font really a shared font? */
-		if (is_shared_sf(rec->name)) {
-			/* check if the shared font is already installed */
-			sf_list *p;
-			for (p = rec->prev; p; p = p->prev) {
-				if (is_identical_name(rec->name, p)) {
-					rec->shared = p;
-					break;
-				}
-			}
-		}
-	}
-#endif /* allow sharing */
-
-	return 0;
-}
-
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-
-/* check if the given name is a valid shared name */
-#define ASC_TO_KEY(c) ((c) - 'A' + 1)
-static int is_shared_sf(unsigned char *name)
-{
-	static unsigned char id_head[4] = {
-		ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
-		AWE_MAJOR_VERSION,
-	};
-	if (memcmp(name, id_head, 4) == 0)
-		return TRUE;
-	return FALSE;
-}
-
-/* check if the given name matches to the existing list */
-static int is_identical_name(unsigned char *name, sf_list *p) 
-{
-	char *id = p->name;
-	if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0)
-		return TRUE;
-	return FALSE;
-}
-
-/* check if the given voice info exists */
-static int info_duplicated(sf_list *sf, awe_voice_list *rec)
-{
-	/* search for all sharing lists */
-	for (; sf; sf = sf->shared) {
-		awe_voice_list *p;
-		for (p = sf->infos; p; p = p->next) {
-			if (p->type == V_ST_NORMAL &&
-			    p->bank == rec->bank &&
-			    p->instr == rec->instr &&
-			    p->v.low == rec->v.low &&
-			    p->v.high == rec->v.high &&
-			    p->v.sample == rec->v.sample)
-				return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-#endif /* AWE_ALLOW_SAMPLE_SHARING */
-
-
-/* free sf_list record */
-/* linked-list in this function is not cared */
-static void
-awe_free_sf(sf_list *sf)
-{
-	if (sf->infos) {
-		awe_voice_list *p, *next;
-		for (p = sf->infos; p; p = next) {
-			next = p->next;
-			kfree(p);
-		}
-	}
-	if (sf->samples) {
-		awe_sample_list *p, *next;
-		for (p = sf->samples; p; p = next) {
-			next = p->next;
-			kfree(p);
-		}
-	}
-	kfree(sf);
-}
-
-
-/* open patch; create sf list and set opened flag */
-static int
-awe_open_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-	awe_open_parm parm;
-	int shared;
-
-	if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
-		return -EFAULT;
-	shared = FALSE;
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-	if (sftail && (parm.type & AWE_PAT_SHARED) != 0) {
-		/* is the previous font the same font? */
-		if (is_identical_name(parm.name, sftail)) {
-			/* then append to the previous */
-			shared = TRUE;
-			awe_reset(0);
-			if (parm.type & AWE_PAT_LOCKED)
-				locked_sf_id = current_sf_id;
-		}
-	}
-#endif /* allow sharing */
-	if (! shared) {
-		if (awe_create_sf(parm.type, parm.name)) {
-			printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n");
-			return -ENOMEM;
-		}
-	}
-	patch_opened = TRUE;
-	return current_sf_id;
-}
-
-/* check if the patch is already opened */
-static sf_list *
-check_patch_opened(int type, char *name)
-{
-	if (! patch_opened) {
-		if (awe_create_sf(type, name)) {
-			printk(KERN_ERR "AWE32: failed to alloc new list\n");
-			return NULL;
-		}
-		patch_opened = TRUE;
-		return sftail;
-	}
-	return sftail;
-}
-
-/* close the patch; if no voice is loaded, remove the patch */
-static int
-awe_close_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-	if (patch_opened && sftail) {
-		/* if no voice is loaded, release the current patch */
-		if (sftail->infos == NULL) {
-			awe_reset(0);
-			awe_remove_samples(current_sf_id - 1);
-		}
-	}
-	patch_opened = 0;
-	return 0;
-}
-
-
-/* remove the latest patch */
-static int
-awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-	if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
-		awe_reset(0);
-		awe_remove_samples(current_sf_id - 1);
-	}
-	return 0;
-}
-
-/* allocate voice info list records */
-static awe_voice_list *
-alloc_new_info(void)
-{
-	awe_voice_list *newlist;
-	
-	newlist = kmalloc(sizeof(*newlist), GFP_KERNEL);
-	if (newlist == NULL) {
-		printk(KERN_ERR "AWE32: can't alloc info table\n");
-		return NULL;
-	}
-	return newlist;
-}
-
-/* allocate sample info list records */
-static awe_sample_list *
-alloc_new_sample(void)
-{
-	awe_sample_list *newlist;
-	
-	newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
-	if (newlist == NULL) {
-		printk(KERN_ERR "AWE32: can't alloc sample table\n");
-		return NULL;
-	}
-	return newlist;
-}
-
-/* load voice map */
-static int
-awe_load_map(awe_patch_info *patch, const char __user *addr, int count)
-{
-	awe_voice_map map;
-	awe_voice_list *rec, *p;
-	sf_list *sf;
-
-	/* get the link info */
-	if (count < sizeof(map)) {
-		printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-		return -EINVAL;
-	}
-	if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
-		return -EFAULT;
-	
-	/* check if the identical mapping already exists */
-	p = awe_search_instr(map.map_bank, map.map_instr, map.map_key);
-	for (; p; p = p->next_instr) {
-		if (p->type == V_ST_MAPPED &&
-		    p->v.start == map.src_instr &&
-		    p->v.end == map.src_bank &&
-		    p->v.fixkey == map.src_key)
-			return 0; /* already present! */
-	}
-
-	if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
-		return -ENOMEM;
-
-	if ((rec = alloc_new_info()) == NULL)
-		return -ENOMEM;
-
-	rec->bank = map.map_bank;
-	rec->instr = map.map_instr;
-	rec->type = V_ST_MAPPED;
-	rec->disabled = FALSE;
-	awe_init_voice_info(&rec->v);
-	if (map.map_key >= 0) {
-		rec->v.low = map.map_key;
-		rec->v.high = map.map_key;
-	}
-	rec->v.start = map.src_instr;
-	rec->v.end = map.src_bank;
-	rec->v.fixkey = map.src_key;
-	add_sf_info(sf, rec);
-	add_info_list(rec);
-
-	return 0;
-}
-
-#if 0
-/* probe preset in the current list -- nothing to be loaded */
-static int
-awe_probe_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-	awe_voice_map map;
-	awe_voice_list *p;
-
-	if (! patch_opened)
-		return -EINVAL;
-
-	/* get the link info */
-	if (count < sizeof(map)) {
-		printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-		return -EINVAL;
-	}
-	if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
-		return -EFAULT;
-	
-	/* check if the identical mapping already exists */
-	if (sftail == NULL)
-		return -EINVAL;
-	p = awe_search_instr(map.src_bank, map.src_instr, map.src_key);
-	for (; p; p = p->next_instr) {
-		if (p->type == V_ST_NORMAL &&
-		    is_identical_holder(p->holder, sftail) &&
-		    p->v.low <= map.src_key &&
-		    p->v.high >= map.src_key)
-			return 0; /* already present! */
-	}
-#endif /* allow sharing */
-	return -EINVAL;
-}
-#endif
-
-/* probe sample in the current list -- nothing to be loaded */
-static int
-awe_probe_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-	if (! patch_opened)
-		return -EINVAL;
-
-	/* search the specified sample by optarg */
-	if (search_sample_index(sftail, patch->optarg) != NULL)
-		return 0;
-#endif /* allow sharing */
-	return -EINVAL;
-}
-
-		
-/* remove the present instrument layers */
-static int
-remove_info(sf_list *sf, int bank, int instr)
-{
-	awe_voice_list *prev, *next, *p;
-	int removed = 0;
-
-	prev = NULL;
-	for (p = sf->infos; p; p = next) {
-		next = p->next;
-		if (p->type == V_ST_NORMAL &&
-		    p->bank == bank && p->instr == instr) {
-			/* remove this layer */
-			if (prev)
-				prev->next = next;
-			else
-				sf->infos = next;
-			if (p == sf->last_infos)
-				sf->last_infos = prev;
-			sf->num_info--;
-			removed++;
-			kfree(p);
-		} else
-			prev = p;
-	}
-	if (removed)
-		rebuild_preset_list();
-	return removed;
-}
-
-/* load voice information data */
-static int
-awe_load_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-	int offset;
-	awe_voice_rec_hdr hdr;
-	int i;
-	int total_size;
-	sf_list *sf;
-	awe_voice_list *rec;
-
-	if (count < AWE_VOICE_REC_SIZE) {
-		printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-		return -EINVAL;
-	}
-
-	offset = AWE_PATCH_INFO_SIZE;
-	if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE))
-		return -EFAULT;
-	offset += AWE_VOICE_REC_SIZE;
-
-	if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
-		printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
-		return -EINVAL;
-	}
-	total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
-	if (count < total_size) {
-		printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
-		       count, hdr.nvoices);
-		return -EINVAL;
-	}
-
-	if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
-		return -ENOMEM;
-
-	switch (hdr.write_mode) {
-	case AWE_WR_EXCLUSIVE:
-		/* exclusive mode - if the instrument already exists,
-		   return error */
-		for (rec = sf->infos; rec; rec = rec->next) {
-			if (rec->type == V_ST_NORMAL &&
-			    rec->bank == hdr.bank &&
-			    rec->instr == hdr.instr)
-				return -EINVAL;
-		}
-		break;
-	case AWE_WR_REPLACE:
-		/* replace mode - remove the instrument if it already exists */
-		remove_info(sf, hdr.bank, hdr.instr);
-		break;
-	}
-
-	/* append new layers */
-	for (i = 0; i < hdr.nvoices; i++) {
-		rec = alloc_new_info();
-		if (rec == NULL)
-			return -ENOMEM;
-
-		rec->bank = hdr.bank;
-		rec->instr = hdr.instr;
-		rec->type = V_ST_NORMAL;
-		rec->disabled = FALSE;
-
-		/* copy awe_voice_info parameters */
-		if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) {
-			kfree(rec);
-			return -EFAULT;
-		}
-		offset += AWE_VOICE_INFO_SIZE;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-		if (sf && sf->shared) {
-			if (info_duplicated(sf, rec)) {
-				kfree(rec);
-				continue;
-			}
-		}
-#endif /* allow sharing */
-		if (rec->v.mode & AWE_MODE_INIT_PARM)
-			awe_init_voice_parm(&rec->v.parm);
-		add_sf_info(sf, rec);
-		awe_set_sample(rec);
-		add_info_list(rec);
-	}
-
-	return 0;
-}
-
-
-/* remove instrument layers */
-static int
-awe_remove_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-	unsigned char bank, instr;
-	sf_list *sf;
-
-	if (! patch_opened || (sf = sftail) == NULL) {
-		printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
-		return -EINVAL;
-	}
-
-	bank = ((unsigned short)patch->optarg >> 8) & 0xff;
-	instr = (unsigned short)patch->optarg & 0xff;
-	if (! remove_info(sf, bank, instr))
-		return -EINVAL;
-	return 0;
-}
-
-
-/* load wave sample data */
-static int
-awe_load_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-	int offset, size;
-	int rc;
-	awe_sample_info tmprec;
-	awe_sample_list *rec;
-	sf_list *sf;
-
-	if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
-		return -ENOMEM;
-
-	size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
-	offset = AWE_PATCH_INFO_SIZE;
-	if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE))
-		return -EFAULT;
-	offset += AWE_SAMPLE_INFO_SIZE;
-	if (size != tmprec.size) {
-		printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n",
-		       tmprec.size, size);
-		return -EINVAL;
-	}
-
-	if (search_sample_index(sf, tmprec.sample) != NULL) {
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-		/* if shared sample, skip this data */
-		if (sf->type & AWE_PAT_SHARED)
-			return 0;
-#endif /* allow sharing */
-		DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample));
-		return -EINVAL;
-	}
-
-	if ((rec = alloc_new_sample()) == NULL)
-		return -ENOMEM;
-
-	memcpy(&rec->v, &tmprec, sizeof(tmprec));
-
-	if (rec->v.size > 0) {
-		if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
-			kfree(rec);
-			return rc;
-		}
-		sf->mem_ptr += rc;
-	}
-
-	add_sf_sample(sf, rec);
-	return 0;
-}
-
-
-/* replace wave sample data */
-static int
-awe_replace_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-	int offset;
-	int size;
-	int rc;
-	int channels;
-	awe_sample_info cursmp;
-	int save_mem_ptr;
-	sf_list *sf;
-	awe_sample_list *rec;
-
-	if (! patch_opened || (sf = sftail) == NULL) {
-		printk(KERN_WARNING "AWE32: replace: patch not opened\n");
-		return -EINVAL;
-	}
-
-	size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
-	offset = AWE_PATCH_INFO_SIZE;
-	if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE))
-		return -EFAULT;
-	offset += AWE_SAMPLE_INFO_SIZE;
-	if (cursmp.size == 0 || size != cursmp.size) {
-		printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n",
-		       cursmp.size, size);
-		return -EINVAL;
-	}
-	channels = patch->optarg;
-	if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
-		printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels);
-		return -EINVAL;
-	}
-
-	for (rec = sf->samples; rec; rec = rec->next) {
-		if (rec->v.sample == cursmp.sample)
-			break;
-	}
-	if (rec == NULL) {
-		printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
-		       cursmp.sample);
-		return -EINVAL;
-	}
-		
-	if (rec->v.size != cursmp.size) {
-		printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n",
-		       rec->v.size, cursmp.size);
-		return -EINVAL;
-	}
-
-	save_mem_ptr = awe_free_mem_ptr();
-	sftail->mem_ptr = rec->v.start - awe_mem_start;
-	memcpy(&rec->v, &cursmp, sizeof(cursmp));
-	rec->v.sf_id = current_sf_id;
-	if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0)
-		return rc;
-	sftail->mem_ptr = save_mem_ptr;
-
-	return 0;
-}
-
-
-/*----------------------------------------------------------------*/
-
-static const char __user *readbuf_addr;
-static int readbuf_offs;
-static int readbuf_flags;
-
-/* initialize read buffer */
-static int
-readbuf_init(const char __user *addr, int offset, awe_sample_info *sp)
-{
-	readbuf_addr = addr;
-	readbuf_offs = offset;
-	readbuf_flags = sp->mode_flags;
-	return 0;
-}
-
-/* read directly from user buffer */
-static unsigned short
-readbuf_word(int pos)
-{
-	unsigned short c;
-	/* read from user buffer */
-	if (readbuf_flags & AWE_SAMPLE_8BITS) {
-		unsigned char cc;
-		get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos));
-		c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
-	} else {
-		get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2));
-	}
-	if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
-		c ^= 0x8000; /* unsigned -> signed */
-	return c;
-}
-
-#define readbuf_word_cache	readbuf_word
-#define readbuf_end()		/**/
-
-/*----------------------------------------------------------------*/
-
-#define BLANK_LOOP_START	8
-#define BLANK_LOOP_END		40
-#define BLANK_LOOP_SIZE		48
-
-/* loading onto memory - return the actual written size */
-static int 
-awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *list, int channels)
-{
-	int i, truesize, dram_offset;
-	awe_sample_info *sp = &list->v;
-	int rc;
-
-	/* be sure loop points start < end */
-	if (sp->loopstart > sp->loopend) {
-		int tmp = sp->loopstart;
-		sp->loopstart = sp->loopend;
-		sp->loopend = tmp;
-	}
-
-	/* compute true data size to be loaded */
-	truesize = sp->size;
-	if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))
-		truesize += sp->loopend - sp->loopstart;
-	if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
-		truesize += BLANK_LOOP_SIZE;
-	if (awe_free_mem_ptr() + truesize >= memsize/2) {
-		DEBUG(-1,printk("AWE32 Error: Sample memory full\n"));
-		return -ENOSPC;
-	}
-
-	/* recalculate address offset */
-	sp->end -= sp->start;
-	sp->loopstart -= sp->start;
-	sp->loopend -= sp->start;
-
-	dram_offset = awe_free_mem_ptr() + awe_mem_start;
-	sp->start = dram_offset;
-	sp->end += dram_offset;
-	sp->loopstart += dram_offset;
-	sp->loopend += dram_offset;
-
-	/* set the total size (store onto obsolete checksum value) */
-	if (sp->size == 0)
-		sp->checksum = 0;
-	else
-		sp->checksum = truesize;
-
-	if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
-		return rc;
-
-	if (readbuf_init(addr, offset, sp) < 0)
-		return -ENOSPC;
-
-	for (i = 0; i < sp->size; i++) {
-		unsigned short c;
-		c = readbuf_word(i);
-		awe_write_dram(c);
-		if (i == sp->loopend &&
-		    (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
-			int looplen = sp->loopend - sp->loopstart;
-			/* copy reverse loop */
-			int k;
-			for (k = 1; k <= looplen; k++) {
-				c = readbuf_word_cache(i - k);
-				awe_write_dram(c);
-			}
-			if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
-				sp->end += looplen;
-			} else {
-				sp->start += looplen;
-				sp->end += looplen;
-			}
-		}
-	}
-	readbuf_end();
-
-	/* if no blank loop is attached in the sample, add it */
-	if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
-		for (i = 0; i < BLANK_LOOP_SIZE; i++)
-			awe_write_dram(0);
-		if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
-			sp->loopstart = sp->end + BLANK_LOOP_START;
-			sp->loopend = sp->end + BLANK_LOOP_END;
-		}
-	}
-
-	awe_close_dram();
-
-	/* initialize FM */
-	awe_init_fm();
-
-	return truesize;
-}
-
-
-/*----------------------------------------------------------------*/
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* calculate GUS envelope time:
- * is this correct?  i have no idea..
- */
-static int
-calc_gus_envelope_time(int rate, int start, int end)
-{
-	int r, p, t;
-	r = (3 - ((rate >> 6) & 3)) * 3;
-	p = rate & 0x3f;
-	t = end - start;
-	if (t < 0) t = -t;
-	if (13 > r)
-		t = t << (13 - r);
-	else
-		t = t >> (r - 13);
-	return (t * 10) / (p * 441);
-}
-
-#define calc_gus_sustain(val)  (0x7f - vol_table[(val)/2])
-#define calc_gus_attenuation(val)	vol_table[(val)/2]
-
-/* load GUS patch */
-static int
-awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag)
-{
-	struct patch_info patch;
-	awe_voice_info *rec;
-	awe_sample_info *smp;
-	awe_voice_list *vrec;
-	awe_sample_list *smprec;
-	int sizeof_patch;
-	int note, rc;
-	sf_list *sf;
-
-	sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */
-	if (size < sizeof_patch) {
-		printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
-		return -EINVAL;
-	}
-	if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs))
-		return -EFAULT;
-	size -= sizeof_patch;
-	if (size < patch.len) {
-		printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n",
-		       size, patch.len);
-		return -EINVAL;
-	}
-	if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL)
-		return -ENOMEM;
-	if ((smprec = alloc_new_sample()) == NULL)
-		return -ENOMEM;
-	if ((vrec = alloc_new_info()) == NULL) {
-		kfree(smprec);
-		return -ENOMEM;
-	}
-
-	smp = &smprec->v;
-	smp->sample = sf->num_sample;
-	smp->start = 0;
-	smp->end = patch.len;
-	smp->loopstart = patch.loop_start;
-	smp->loopend = patch.loop_end;
-	smp->size = patch.len;
-
-	/* set up mode flags */
-	smp->mode_flags = 0;
-	if (!(patch.mode & WAVE_16_BITS))
-		smp->mode_flags |= AWE_SAMPLE_8BITS;
-	if (patch.mode & WAVE_UNSIGNED)
-		smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
-	smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
-	if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
-		smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
-	if (patch.mode & WAVE_BIDIR_LOOP)
-		smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
-	if (patch.mode & WAVE_LOOP_BACK)
-		smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
-
-	DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
-	if (patch.mode & WAVE_16_BITS) {
-		/* convert to word offsets */
-		smp->size /= 2;
-		smp->end /= 2;
-		smp->loopstart /= 2;
-		smp->loopend /= 2;
-	}
-	smp->checksum_flag = 0;
-	smp->checksum = 0;
-
-	if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) {
-		kfree(vrec);
-		return rc;
-	}
-	sf->mem_ptr += rc;
-	add_sf_sample(sf, smprec);
-
-	/* set up voice info */
-	rec = &vrec->v;
-	awe_init_voice_info(rec);
-	rec->sample = sf->num_info; /* the last sample */
-	rec->rate_offset = calc_rate_offset(patch.base_freq);
-	note = freq_to_note(patch.base_note);
-	rec->root = note / 100;
-	rec->tune = -(note % 100);
-	rec->low = freq_to_note(patch.low_note) / 100;
-	rec->high = freq_to_note(patch.high_note) / 100;
-	DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
-		       rec->rate_offset, note,
-		       rec->low, rec->high,
-	      patch.low_note, patch.high_note));
-	/* panning position; -128 - 127 => 0-127 */
-	rec->pan = (patch.panning + 128) / 2;
-
-	/* detuning is ignored */
-	/* 6points volume envelope */
-	if (patch.mode & WAVE_ENVELOPES) {
-		int attack, hold, decay, release;
-		attack = calc_gus_envelope_time
-			(patch.env_rate[0], 0, patch.env_offset[0]);
-		hold = calc_gus_envelope_time
-			(patch.env_rate[1], patch.env_offset[0],
-			 patch.env_offset[1]);
-		decay = calc_gus_envelope_time
-			(patch.env_rate[2], patch.env_offset[1],
-			 patch.env_offset[2]);
-		release = calc_gus_envelope_time
-			(patch.env_rate[3], patch.env_offset[1],
-			 patch.env_offset[4]);
-		release += calc_gus_envelope_time
-			(patch.env_rate[4], patch.env_offset[3],
-			 patch.env_offset[4]);
-		release += calc_gus_envelope_time
-			(patch.env_rate[5], patch.env_offset[4],
-			 patch.env_offset[5]);
-		rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
-			calc_parm_attack(attack);
-		rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
-			calc_parm_decay(decay);
-		rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
-		DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
-		rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
-	}
-
-	/* tremolo effect */
-	if (patch.mode & WAVE_TREMOLO) {
-		int rate = (patch.tremolo_rate * 1000 / 38) / 42;
-		rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
-		DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
-			       patch.tremolo_rate, patch.tremolo_depth,
-			       rec->parm.tremfrq));
-	}
-	/* vibrato effect */
-	if (patch.mode & WAVE_VIBRATO) {
-		int rate = (patch.vibrato_rate * 1000 / 38) / 42;
-		rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
-		DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
-			       patch.tremolo_rate, patch.tremolo_depth,
-			       rec->parm.tremfrq));
-	}
-	
-	/* scale_freq, scale_factor, volume, and fractions not implemented */
-
-	/* append to the tail of the list */
-	vrec->bank = ctrls[AWE_MD_GUS_BANK];
-	vrec->instr = patch.instr_no;
-	vrec->disabled = FALSE;
-	vrec->type = V_ST_NORMAL;
-
-	add_sf_info(sf, vrec);
-	add_info_list(vrec);
-
-	/* set the voice index */
-	awe_set_sample(vrec);
-
-	return 0;
-}
-
-#endif  /* AWE_HAS_GUS_COMPATIBILITY */
-
-/*
- * sample and voice list handlers
- */
-
-/* append this to the current sf list */
-static void add_sf_info(sf_list *sf, awe_voice_list *rec)
-{
-	if (sf == NULL)
-		return;
-	rec->holder = sf;
-	rec->v.sf_id = sf->sf_id;
-	if (sf->last_infos)
-		sf->last_infos->next = rec;
-	else
-		sf->infos = rec;
-	sf->last_infos = rec;
-	rec->next = NULL;
-	sf->num_info++;
-}
-
-/* prepend this sample to sf list */
-static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
-{
-	if (sf == NULL)
-		return;
-	rec->holder = sf;
-	rec->v.sf_id = sf->sf_id;
-	if (sf->last_samples)
-		sf->last_samples->next = rec;
-	else
-		sf->samples = rec;
-	sf->last_samples = rec;
-	rec->next = NULL;
-	sf->num_sample++;
-}
-
-/* purge the old records which don't belong with the same file id */
-static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
-{
-	rec->next_instr = next;
-	if (rec->bank == AWE_DRUM_BANK) {
-		/* remove samples with the same note range */
-		awe_voice_list *cur, *prev = rec;
-		int low = rec->v.low;
-		int high = rec->v.high;
-		for (cur = next; cur; cur = cur->next_instr) {
-			if (cur->v.low == low &&
-			    cur->v.high == high &&
-			    ! is_identical_holder(cur->holder, rec->holder))
-				prev->next_instr = cur->next_instr;
-			else
-				prev = cur;
-		}
-	} else {
-		if (! is_identical_holder(next->holder, rec->holder))
-			/* remove all samples */
-			rec->next_instr = NULL;
-	}
-}
-
-/* prepend to top of the preset table */
-static void add_info_list(awe_voice_list *rec)
-{
-	awe_voice_list *prev, *cur;
-	int key;
-
-	if (rec->disabled)
-		return;
-
-	key = awe_search_key(rec->bank, rec->instr, rec->v.low);
-	prev = NULL;
-	for (cur = preset_table[key]; cur; cur = cur->next_bank) {
-		/* search the first record with the same bank number */
-		if (cur->instr == rec->instr && cur->bank == rec->bank) {
-			/* replace the list with the new record */
-			rec->next_bank = cur->next_bank;
-			if (prev)
-				prev->next_bank = rec;
-			else
-				preset_table[key] = rec;
-			purge_old_list(rec, cur);
-			return;
-		}
-		prev = cur;
-	}
-
-	/* this is the first bank record.. just add this */
-	rec->next_instr = NULL;
-	rec->next_bank = preset_table[key];
-	preset_table[key] = rec;
-}
-
-/* remove samples later than the specified sf_id */
-static void
-awe_remove_samples(int sf_id)
-{
-	sf_list *p, *prev;
-
-	if (sf_id <= 0) {
-		awe_reset_samples();
-		return;
-	}
-	/* already removed? */
-	if (current_sf_id <= sf_id)
-		return;
-
-	for (p = sftail; p; p = prev) {
-		if (p->sf_id <= sf_id)
-			break;
-		prev = p->prev;
-		awe_free_sf(p);
-	}
-	sftail = p;
-	if (sftail) {
-		sf_id = sftail->sf_id;
-		sftail->next = NULL;
-	} else {
-		sf_id = 0;
-		sfhead = NULL;
-	}
-	current_sf_id = sf_id;
-	if (locked_sf_id > sf_id)
-		locked_sf_id = sf_id;
-
-	rebuild_preset_list();
-}
-
-/* rebuild preset search list */
-static void rebuild_preset_list(void)
-{
-	sf_list *p;
-	awe_voice_list *rec;
-
-	memset(preset_table, 0, sizeof(preset_table));
-
-	for (p = sfhead; p; p = p->next) {
-		for (rec = p->infos; rec; rec = rec->next)
-			add_info_list(rec);
-	}
-}
-
-/* compare the given sf_id pair */
-static int is_identical_holder(sf_list *sf1, sf_list *sf2)
-{
-	if (sf1 == NULL || sf2 == NULL)
-		return FALSE;
-	if (sf1 == sf2)
-		return TRUE;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-	{
-		/* compare with the sharing id */
-		sf_list *p;
-		int counter = 0;
-		if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
-			sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
-		}
-		for (p = sf1->shared; p; p = p->shared) {
-			if (counter++ > current_sf_id)
-				break; /* strange sharing loop.. quit */
-			if (p == sf2)
-				return TRUE;
-		}
-	}
-#endif /* allow sharing */
-	return FALSE;
-}
-
-/* search the sample index matching with the given sample id */
-static awe_sample_list *
-search_sample_index(sf_list *sf, int sample)
-{
-	awe_sample_list *p;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-	int counter = 0;
-	while (sf) {
-		for (p = sf->samples; p; p = p->next) {
-			if (p->v.sample == sample)
-				return p;
-		}
-		sf = sf->shared;
-		if (counter++ > current_sf_id)
-			break; /* strange sharing loop.. quit */
-	}
-#else
-	if (sf) {
-		for (p = sf->samples; p; p = p->next) {
-			if (p->v.sample == sample)
-				return p;
-		}
-	}
-#endif
-	return NULL;
-}
-
-/* search the specified sample */
-/* non-zero = found */
-static short
-awe_set_sample(awe_voice_list *rec)
-{
-	awe_sample_list *smp;
-	awe_voice_info *vp = &rec->v;
-
-	vp->index = 0;
-	if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
-		return 0;
-
-	/* set the actual sample offsets */
-	vp->start += smp->v.start;
-	vp->end += smp->v.end;
-	vp->loopstart += smp->v.loopstart;
-	vp->loopend += smp->v.loopend;
-	/* copy mode flags */
-	vp->mode = smp->v.mode_flags;
-	/* set flag */
-	vp->index = 1;
-
-	return 1;
-}
-
-
-/*
- * voice allocation
- */
-
-/* look for all voices associated with the specified note & velocity */
-static int
-awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
-			awe_voice_info **vlist)
-{
-	int nvoices;
-
-	nvoices = 0;
-	for (; rec; rec = rec->next_instr) {
-		if (note >= rec->v.low &&
-		    note <= rec->v.high &&
-		    velocity >= rec->v.vellow &&
-		    velocity <= rec->v.velhigh) {
-			if (rec->type == V_ST_MAPPED) {
-				/* mapper */
-				vlist[0] = &rec->v;
-				return -1;
-			}
-			vlist[nvoices++] = &rec->v;
-			if (nvoices >= AWE_MAX_VOICES)
-				break;
-		}
-	}
-	return nvoices;	
-}
-
-/* store the voice list from the specified note and velocity.
-   if the preset is mapped, seek for the destination preset, and rewrite
-   the note number if necessary.
-   */
-static int
-really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
-{
-	int nvoices;
-	awe_voice_list *vrec;
-	int level = 0;
-
-	for (;;) {
-		vrec = awe_search_instr(bank, instr, *note);
-		nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-		if (nvoices == 0) {
-			if (bank == AWE_DRUM_BANK)
-				/* search default drumset */
-				vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
-			else
-				/* search default preset */
-				vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
-			nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-		}
-		if (nvoices == 0) {
-			if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
-				/* search default drumset */
-				vrec = awe_search_instr(bank, 0, *note);
-			else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
-				/* search default preset */
-				vrec = awe_search_instr(0, instr, *note);
-			nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-		}
-		if (nvoices < 0) { /* mapping */
-			int key = vlist[0]->fixkey;
-			instr = vlist[0]->start;
-			bank = vlist[0]->end;
-			if (level++ > 5) {
-				printk(KERN_ERR "AWE32: too deep mapping level\n");
-				return 0;
-			}
-			if (key >= 0)
-				*note = key;
-		} else
-			break;
-	}
-
-	return nvoices;
-}
-
-/* allocate voices corresponding note and velocity; supports multiple insts. */
-static void
-awe_alloc_multi_voices(int ch, int note, int velocity, int key)
-{
-	int i, v, nvoices, bank;
-	awe_voice_info *vlist[AWE_MAX_VOICES];
-
-	if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
-		bank = AWE_DRUM_BANK; /* always search drumset */
-	else
-		bank = channels[ch].bank;
-
-	/* check the possible voices; note may be changeable if mapped */
-	nvoices = really_alloc_voices(bank, channels[ch].instr,
-				      &note, velocity, vlist);
-
-	/* set the voices */
-	current_alloc_time++;
-	for (i = 0; i < nvoices; i++) {
-		v = awe_clear_voice();
-		voices[v].key = key;
-		voices[v].ch = ch;
-		voices[v].note = note;
-		voices[v].velocity = velocity;
-		voices[v].time = current_alloc_time;
-		voices[v].cinfo = &channels[ch];
-		voices[v].sample = vlist[i];
-		voices[v].state = AWE_ST_MARK;
-		voices[v].layer = nvoices - i - 1;  /* in reverse order */
-	}
-
-	/* clear the mark in allocated voices */
-	for (i = 0; i < awe_max_voices; i++) {
-		if (voices[i].state == AWE_ST_MARK)
-			voices[i].state = AWE_ST_OFF;
-			
-	}
-}
-
-
-/* search an empty voice.
-   if no empty voice is found, at least terminate a voice
-   */
-static int
-awe_clear_voice(void)
-{
-	enum {
-		OFF=0, RELEASED, SUSTAINED, PLAYING, END
-	};
-	struct voice_candidate_t {
-		int best;
-		int time;
-		int vtarget;
-	} candidate[END];
-	int i, type, vtarget;
-
-	vtarget = 0xffff;
-	for (type = OFF; type < END; type++) {
-		candidate[type].best = -1;
-		candidate[type].time = current_alloc_time + 1;
-		candidate[type].vtarget = vtarget;
-	}
-
-	for (i = 0; i < awe_max_voices; i++) {
-		if (voices[i].state & AWE_ST_OFF)
-			type = OFF;
-		else if (voices[i].state & AWE_ST_RELEASED)
-			type = RELEASED;
-		else if (voices[i].state & AWE_ST_SUSTAINED)
-			type = SUSTAINED;
-		else if (voices[i].state & ~AWE_ST_MARK)
-			type = PLAYING;
-		else
-			continue;
-#ifdef AWE_CHECK_VTARGET
-		/* get current volume */
-		vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
-#endif
-		if (candidate[type].best < 0 ||
-		    vtarget < candidate[type].vtarget ||
-		    (vtarget == candidate[type].vtarget &&
-		     voices[i].time < candidate[type].time)) {
-			candidate[type].best = i;
-			candidate[type].time = voices[i].time;
-			candidate[type].vtarget = vtarget;
-		}
-	}
-
-	for (type = OFF; type < END; type++) {
-		if ((i = candidate[type].best) >= 0) {
-			if (voices[i].state != AWE_ST_OFF)
-				awe_terminate(i);
-			awe_voice_init(i, TRUE);
-			return i;
-		}
-	}
-	return 0;
-}
-
-
-/* search sample for the specified note & velocity and set it on the voice;
- * note that voice is the voice index (not channel index)
- */
-static void
-awe_alloc_one_voice(int voice, int note, int velocity)
-{
-	int ch, nvoices, bank;
-	awe_voice_info *vlist[AWE_MAX_VOICES];
-
-	ch = voices[voice].ch;
-	if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
-		bank = AWE_DRUM_BANK; /* always search drumset */
-	else
-		bank = voices[voice].cinfo->bank;
-
-	nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
-				      &note, velocity, vlist);
-	if (nvoices > 0) {
-		voices[voice].time = ++current_alloc_time;
-		voices[voice].sample = vlist[0]; /* use the first one */
-		voices[voice].layer = 0;
-		voices[voice].note = note;
-		voices[voice].velocity = velocity;
-	}
-}
-
-
-/*
- * sequencer2 functions
- */
-
-/* search an empty voice; used by sequencer2 */
-static int
-awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
-	playing_mode = AWE_PLAY_MULTI2;
-	awe_info.nr_voices = AWE_MAX_CHANNELS;
-	return awe_clear_voice();
-}
-
-
-/* set up voice; used by sequencer2 */
-static void
-awe_setup_voice(int dev, int voice, int chn)
-{
-	struct channel_info *info;
-	if (synth_devs[dev] == NULL ||
-	    (info = &synth_devs[dev]->chn_info[chn]) == NULL)
-		return;
-
-	if (voice < 0 || voice >= awe_max_voices)
-		return;
-
-	DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
-	channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
-	channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
-	channels[chn].panning =
-		info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
-	channels[chn].bender = info->bender_value; /* zero center */
-	channels[chn].bank = info->controllers[CTL_BANK_SELECT];
-	channels[chn].sustained = info->controllers[CTL_SUSTAIN];
-	if (info->controllers[CTL_EXT_EFF_DEPTH]) {
-		FX_SET(&channels[chn].fx, AWE_FX_REVERB,
-		       info->controllers[CTL_EXT_EFF_DEPTH] * 2);
-	}
-	if (info->controllers[CTL_CHORUS_DEPTH]) {
-		FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
-		       info->controllers[CTL_CHORUS_DEPTH] * 2);
-	}
-	awe_set_instr(dev, chn, info->pgm_num);
-}
-
-
-#ifdef CONFIG_AWE32_MIXER
-/*
- * AWE32 mixer device control
- */
-
-static int awe_mixer_ioctl(int dev, unsigned int cmd, void __user *arg);
-
-static int my_mixerdev = -1;
-
-static struct mixer_operations awe_mixer_operations = {
-	.owner	= THIS_MODULE,
-	.id	= "AWE",
-	.name	= "AWE32 Equalizer",
-	.ioctl	= awe_mixer_ioctl,
-};
-
-static void __init attach_mixer(void)
-{
-	if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
-		mixer_devs[my_mixerdev] = &awe_mixer_operations;
-	}
-}
-
-static void unload_mixer(void)
-{
-	if (my_mixerdev >= 0)
-		sound_unload_mixerdev(my_mixerdev);
-}
-
-static int
-awe_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
-{
-	int i, level, value;
-
-	if (((cmd >> 8) & 0xff) != 'M')
-		return -EINVAL;
-
-	if (get_user(level, (int __user *)arg))
-		return -EFAULT;
-	level = ((level & 0xff) + (level >> 8)) / 2;
-	DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
-
-	if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
-		switch (cmd & 0xff) {
-		case SOUND_MIXER_BASS:
-			value = level * 12 / 100;
-			if (value >= 12)
-				value = 11;
-			ctrls[AWE_MD_BASS_LEVEL] = value;
-			awe_update_equalizer();
-			break;
-		case SOUND_MIXER_TREBLE:
-			value = level * 12 / 100;
-			if (value >= 12)
-				value = 11;
-			ctrls[AWE_MD_TREBLE_LEVEL] = value;
-			awe_update_equalizer();
-			break;
-		case SOUND_MIXER_VOLUME:
-			level = level * 127 / 100;
-			if (level >= 128) level = 127;
-			atten_relative = FALSE;
-			atten_offset = vol_table[level];
-			awe_update_volume();
-			break;
-		}
-	}
-	switch (cmd & 0xff) {
-	case SOUND_MIXER_BASS:
-		level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
-		level = (level << 8) | level;
-		break;
-	case SOUND_MIXER_TREBLE:
-		level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
-		level = (level << 8) | level;
-		break;
-	case SOUND_MIXER_VOLUME:
-		value = atten_offset;
-		if (atten_relative)
-			value += ctrls[AWE_MD_ZERO_ATTEN];
-		for (i = 127; i > 0; i--) {
-			if (value <= vol_table[i])
-				break;
-		}
-		level = i * 100 / 127;
-		level = (level << 8) | level;
-		break;
-	case SOUND_MIXER_DEVMASK:
-		level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
-		break;
-	default:
-		level = 0;
-		break;
-	}
-	if (put_user(level, (int __user *)arg))
-		return -EFAULT;
-	return level;
-}
-#endif /* CONFIG_AWE32_MIXER */
-
-
-/*
- * initialization of Emu8000
- */
-
-/* intiailize audio channels */
-static void
-awe_init_audio(void)
-{
-	int ch;
-
-	/* turn off envelope engines */
-	for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-		awe_poke(AWE_DCYSUSV(ch), 0x80);
-	}
-  
-	/* reset all other parameters to zero */
-	for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-		awe_poke(AWE_ENVVOL(ch), 0);
-		awe_poke(AWE_ENVVAL(ch), 0);
-		awe_poke(AWE_DCYSUS(ch), 0);
-		awe_poke(AWE_ATKHLDV(ch), 0);
-		awe_poke(AWE_LFO1VAL(ch), 0);
-		awe_poke(AWE_ATKHLD(ch), 0);
-		awe_poke(AWE_LFO2VAL(ch), 0);
-		awe_poke(AWE_IP(ch), 0);
-		awe_poke(AWE_IFATN(ch), 0);
-		awe_poke(AWE_PEFE(ch), 0);
-		awe_poke(AWE_FMMOD(ch), 0);
-		awe_poke(AWE_TREMFRQ(ch), 0);
-		awe_poke(AWE_FM2FRQ2(ch), 0);
-		awe_poke_dw(AWE_PTRX(ch), 0);
-		awe_poke_dw(AWE_VTFT(ch), 0);
-		awe_poke_dw(AWE_PSST(ch), 0);
-		awe_poke_dw(AWE_CSL(ch), 0);
-		awe_poke_dw(AWE_CCCA(ch), 0);
-	}
-
-	for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-		awe_poke_dw(AWE_CPF(ch), 0);
-		awe_poke_dw(AWE_CVCF(ch), 0);
-	}
-}
-
-
-/* initialize DMA address */
-static void
-awe_init_dma(void)
-{
-	awe_poke_dw(AWE_SMALR, 0);
-	awe_poke_dw(AWE_SMARR, 0);
-	awe_poke_dw(AWE_SMALW, 0);
-	awe_poke_dw(AWE_SMARW, 0);
-}
-
-
-/* initialization arrays; from ADIP */
-
-static unsigned short init1[128] = {
-	0x03ff, 0x0030,  0x07ff, 0x0130, 0x0bff, 0x0230,  0x0fff, 0x0330,
-	0x13ff, 0x0430,  0x17ff, 0x0530, 0x1bff, 0x0630,  0x1fff, 0x0730,
-	0x23ff, 0x0830,  0x27ff, 0x0930, 0x2bff, 0x0a30,  0x2fff, 0x0b30,
-	0x33ff, 0x0c30,  0x37ff, 0x0d30, 0x3bff, 0x0e30,  0x3fff, 0x0f30,
-
-	0x43ff, 0x0030,  0x47ff, 0x0130, 0x4bff, 0x0230,  0x4fff, 0x0330,
-	0x53ff, 0x0430,  0x57ff, 0x0530, 0x5bff, 0x0630,  0x5fff, 0x0730,
-	0x63ff, 0x0830,  0x67ff, 0x0930, 0x6bff, 0x0a30,  0x6fff, 0x0b30,
-	0x73ff, 0x0c30,  0x77ff, 0x0d30, 0x7bff, 0x0e30,  0x7fff, 0x0f30,
-
-	0x83ff, 0x0030,  0x87ff, 0x0130, 0x8bff, 0x0230,  0x8fff, 0x0330,
-	0x93ff, 0x0430,  0x97ff, 0x0530, 0x9bff, 0x0630,  0x9fff, 0x0730,
-	0xa3ff, 0x0830,  0xa7ff, 0x0930, 0xabff, 0x0a30,  0xafff, 0x0b30,
-	0xb3ff, 0x0c30,  0xb7ff, 0x0d30, 0xbbff, 0x0e30,  0xbfff, 0x0f30,
-
-	0xc3ff, 0x0030,  0xc7ff, 0x0130, 0xcbff, 0x0230,  0xcfff, 0x0330,
-	0xd3ff, 0x0430,  0xd7ff, 0x0530, 0xdbff, 0x0630,  0xdfff, 0x0730,
-	0xe3ff, 0x0830,  0xe7ff, 0x0930, 0xebff, 0x0a30,  0xefff, 0x0b30,
-	0xf3ff, 0x0c30,  0xf7ff, 0x0d30, 0xfbff, 0x0e30,  0xffff, 0x0f30,
-};
-
-static unsigned short init2[128] = {
-	0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
-	0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
-	0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
-	0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
-
-	0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
-	0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
-	0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
-	0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
-
-	0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
-	0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
-	0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
-	0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
-
-	0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
-	0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
-	0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
-	0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
-};
-
-static unsigned short init3[128] = {
-	0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
-	0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
-	0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
-	0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
-
-	0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
-	0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
-	0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
-	0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
-
-	0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
-	0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
-	0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
-	0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
-
-	0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
-	0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
-	0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
-	0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-static unsigned short init4[128] = {
-	0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
-	0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
-	0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
-	0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
-
-	0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
-	0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
-	0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
-	0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
-
-	0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
-	0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
-	0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
-	0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
-
-	0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
-	0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
-	0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
-	0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-
-/* send initialization arrays to start up */
-static void
-awe_init_array(void)
-{
-	awe_send_array(init1);
-	awe_wait(1024);
-	awe_send_array(init2);
-	awe_send_array(init3);
-	awe_poke_dw(AWE_HWCF4, 0);
-	awe_poke_dw(AWE_HWCF5, 0x83);
-	awe_poke_dw(AWE_HWCF6, 0x8000);
-	awe_send_array(init4);
-}
-
-/* send an initialization array */
-static void
-awe_send_array(unsigned short *data)
-{
-	int i;
-	unsigned short *p;
-
-	p = data;
-	for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-		awe_poke(AWE_INIT1(i), *p);
-	for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-		awe_poke(AWE_INIT2(i), *p);
-	for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-		awe_poke(AWE_INIT3(i), *p);
-	for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-		awe_poke(AWE_INIT4(i), *p);
-}
-
-
-/*
- * set up awe32 channels to some known state.
- */
-
-/* set the envelope & LFO parameters to the default values; see ADIP */
-static void
-awe_tweak_voice(int i)
-{
-	/* set all mod/vol envelope shape to minimum */
-	awe_poke(AWE_ENVVOL(i), 0x8000);
-	awe_poke(AWE_ENVVAL(i), 0x8000);
-	awe_poke(AWE_DCYSUS(i), 0x7F7F);
-	awe_poke(AWE_ATKHLDV(i), 0x7F7F);
-	awe_poke(AWE_ATKHLD(i), 0x7F7F);
-	awe_poke(AWE_PEFE(i), 0);  /* mod envelope height to zero */
-	awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
-	awe_poke(AWE_LFO2VAL(i), 0x8000);
-	awe_poke(AWE_IP(i), 0xE000);	/* no pitch shift */
-	awe_poke(AWE_IFATN(i), 0xFF00);	/* volume to minimum */
-	awe_poke(AWE_FMMOD(i), 0);
-	awe_poke(AWE_TREMFRQ(i), 0);
-	awe_poke(AWE_FM2FRQ2(i), 0);
-}
-
-static void
-awe_tweak(void)
-{
-	int i;
-	/* reset all channels */
-	for (i = 0; i < awe_max_voices; i++)
-		awe_tweak_voice(i);
-}
-
-
-/*
- *  initializes the FM section of AWE32;
- *   see Vince Vu's unofficial AWE32 programming guide
- */
-
-static void
-awe_init_fm(void)
-{
-#ifndef AWE_ALWAYS_INIT_FM
-	/* if no extended memory is on board.. */
-	if (memsize <= 0)
-		return;
-#endif
-	DEBUG(3,printk("AWE32: initializing FM\n"));
-
-	/* Initialize the last two channels for DRAM refresh and producing
-	   the reverb and chorus effects for Yamaha OPL-3 synthesizer */
-
-	/* 31: FM left channel, 0xffffe0-0xffffe8 */
-	awe_poke(AWE_DCYSUSV(30), 0x80);
-	awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
-	awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
-		    (DEF_FM_CHORUS_DEPTH << 24));
-	awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
-	awe_poke_dw(AWE_CPF(30), 0);
-	awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
-
-	/* 32: FM right channel, 0xfffff0-0xfffff8 */
-	awe_poke(AWE_DCYSUSV(31), 0x80);
-	awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
-	awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
-		    (DEF_FM_CHORUS_DEPTH << 24));
-	awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
-	awe_poke_dw(AWE_CPF(31), 0x8000);
-	awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
-
-	/* skew volume & cutoff */
-	awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
-	awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
-
-	voices[30].state = AWE_ST_FM;
-	voices[31].state = AWE_ST_FM;
-
-	/* change maximum channels to 30 */
-	awe_max_voices = AWE_NORMAL_VOICES;
-	if (playing_mode == AWE_PLAY_DIRECT)
-		awe_info.nr_voices = awe_max_voices;
-	else
-		awe_info.nr_voices = AWE_MAX_CHANNELS;
-	voice_alloc->max_voice = awe_max_voices;
-}
-
-/*
- *  AWE32 DRAM access routines
- */
-
-/* open DRAM write accessing mode */
-static int
-awe_open_dram_for_write(int offset, int channels)
-{
-	int vidx[AWE_NORMAL_VOICES];
-	int i;
-
-	if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
-		channels = AWE_NORMAL_VOICES;
-		for (i = 0; i < AWE_NORMAL_VOICES; i++)
-			vidx[i] = i;
-	} else {
-		for (i = 0; i < channels; i++) {
-			vidx[i] = awe_clear_voice();
-			voices[vidx[i]].state = AWE_ST_MARK;
-		}
-	}
-
-	/* use all channels for DMA transfer */
-	for (i = 0; i < channels; i++) {
-		if (vidx[i] < 0) continue;
-		awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
-		awe_poke_dw(AWE_VTFT(vidx[i]), 0);
-		awe_poke_dw(AWE_CVCF(vidx[i]), 0);
-		awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
-		awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
-		awe_poke_dw(AWE_PSST(vidx[i]), 0);
-		awe_poke_dw(AWE_CSL(vidx[i]), 0);
-		awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
-		voices[vidx[i]].state = AWE_ST_DRAM;
-	}
-	/* point channels 31 & 32 to ROM samples for DRAM refresh */
-	awe_poke_dw(AWE_VTFT(30), 0);
-	awe_poke_dw(AWE_PSST(30), 0x1d8);
-	awe_poke_dw(AWE_CSL(30), 0x1e0);
-	awe_poke_dw(AWE_CCCA(30), 0x1d8);
-	awe_poke_dw(AWE_VTFT(31), 0);
-	awe_poke_dw(AWE_PSST(31), 0x1d8);
-	awe_poke_dw(AWE_CSL(31), 0x1e0);
-	awe_poke_dw(AWE_CCCA(31), 0x1d8);
-	voices[30].state = AWE_ST_FM;
-	voices[31].state = AWE_ST_FM;
-
-	/* if full bit is on, not ready to write on */
-	if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
-		for (i = 0; i < channels; i++) {
-			awe_poke_dw(AWE_CCCA(vidx[i]), 0);
-			voices[vidx[i]].state = AWE_ST_OFF;
-		}
-		printk("awe: not ready to write..\n");
-		return -EPERM;
-	}
-
-	/* set address to write */
-	awe_poke_dw(AWE_SMALW, offset);
-
-	return 0;
-}
-
-/* open DRAM for RAM size detection */
-static void
-awe_open_dram_for_check(void)
-{
-	int i;
-	for (i = 0; i < AWE_NORMAL_VOICES; i++) {
-		awe_poke(AWE_DCYSUSV(i), 0x80);
-		awe_poke_dw(AWE_VTFT(i), 0);
-		awe_poke_dw(AWE_CVCF(i), 0);
-		awe_poke_dw(AWE_PTRX(i), 0x40000000);
-		awe_poke_dw(AWE_CPF(i), 0x40000000);
-		awe_poke_dw(AWE_PSST(i), 0);
-		awe_poke_dw(AWE_CSL(i), 0);
-		if (i & 1) /* DMA write */
-			awe_poke_dw(AWE_CCCA(i), 0x06000000);
-		else	   /* DMA read */
-			awe_poke_dw(AWE_CCCA(i), 0x04000000);
-		voices[i].state = AWE_ST_DRAM;
-	}
-}
-
-
-/* close dram access */
-static void
-awe_close_dram(void)
-{
-	int i;
-	/* wait until FULL bit in SMAxW register be false */
-	for (i = 0; i < 10000; i++) {
-		if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
-			break;
-		awe_wait(10);
-	}
-
-	for (i = 0; i < AWE_NORMAL_VOICES; i++) {
-		if (voices[i].state == AWE_ST_DRAM) {
-			awe_poke_dw(AWE_CCCA(i), 0);
-			awe_poke(AWE_DCYSUSV(i), 0x807F);
-			voices[i].state = AWE_ST_OFF;
-		}
-	}
-}
-
-
-/*
- * check dram size on AWE board
- */
-
-/* any three numbers you like */
-#define UNIQUE_ID1	0x1234
-#define UNIQUE_ID2	0x4321
-#define UNIQUE_ID3	0xABCD
-
-static void __init
-awe_check_dram(void)
-{
-	if (awe_present) /* already initialized */
-		return;
-
-	if (memsize >= 0) { /* given by config file or module option */
-		memsize *= 1024; /* convert to Kbytes */
-		return;
-	}
-
-	awe_open_dram_for_check();
-
-	memsize = 0;
-
-	/* set up unique two id numbers */
-	awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
-	awe_poke(AWE_SMLD, UNIQUE_ID1);
-	awe_poke(AWE_SMLD, UNIQUE_ID2);
-
-	while (memsize < AWE_MAX_DRAM_SIZE) {
-		awe_wait(5);
-		/* read a data on the DRAM start address */
-		awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
-		awe_peek(AWE_SMLD); /* discard stale data  */
-		if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
-			break;
-		if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
-			break;
-		memsize += 512;  /* increment 512kbytes */
-		/* Write a unique data on the test address;
-		 * if the address is out of range, the data is written on
-		 * 0x200000(=AWE_DRAM_OFFSET).  Then the two id words are
-		 * broken by this data.
-		 */
-		awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
-		awe_poke(AWE_SMLD, UNIQUE_ID3);
-		awe_wait(5);
-		/* read a data on the just written DRAM address */
-		awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
-		awe_peek(AWE_SMLD); /* discard stale data  */
-		if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
-			break;
-	}
-	awe_close_dram();
-
-	DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
-
-	/* convert to Kbytes */
-	memsize *= 1024;
-}
-
-
-/*----------------------------------------------------------------*/
-
-/*
- * chorus and reverb controls; from VV's guide
- */
-
-/* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
-static char chorus_defined[AWE_CHORUS_NUMBERS];
-static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
-	{0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
-	{0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
-	{0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
-	{0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
-	{0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
-	{0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
-	{0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
-	{0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
-};
-
-static int
-awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count)
-{
-	if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
-		printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
-		return -EINVAL;
-	}
-	if (count < sizeof(awe_chorus_fx_rec)) {
-		printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
-		return -EINVAL;
-	}
-	if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
-			   sizeof(awe_chorus_fx_rec)))
-		return -EFAULT;
-	chorus_defined[patch->optarg] = TRUE;
-	return 0;
-}
-
-static void
-awe_set_chorus_mode(int effect)
-{
-	if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
-	    (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
-		return;
-	awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
-	awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
-	awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
-	awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
-	awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
-	awe_poke_dw(AWE_HWCF6, 0x8000);
-	awe_poke_dw(AWE_HWCF7, 0x0000);
-}
-
-static void
-awe_update_chorus_mode(void)
-{
-	awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
-}
-
-/*----------------------------------------------------------------*/
-
-/* reverb mode settings; write the following 28 data of 16 bit length
- *   on the corresponding ports in the reverb_cmds array
- */
-static char reverb_defined[AWE_CHORUS_NUMBERS];
-static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
-{{  /* room 1 */
-	0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
-	0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
-	0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* room 2 */
-	0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
-	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* room 3 */
-	0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
-	0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
-	0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
-}},
-{{  /* hall 1 */
-	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
-	0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
-	0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
-}},
-{{  /* hall 2 */
-	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
-	0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
-	0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* plate */
-	0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
-	0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
-	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* delay */
-	0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
-	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
-	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
-	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-{{  /* panning delay */
-	0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
-	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
-	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
-	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-};
-
-static struct ReverbCmdPair {
-	unsigned short cmd, port;
-} reverb_cmds[28] = {
-  {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
-  {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
-  {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
-  {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
-  {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
-  {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
-  {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
-};
-
-static int
-awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count)
-{
-	if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
-		printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
-		return -EINVAL;
-	}
-	if (count < sizeof(awe_reverb_fx_rec)) {
-		printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
-		return -EINVAL;
-	}
-	if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
-			   sizeof(awe_reverb_fx_rec)))
-		return -EFAULT;
-	reverb_defined[patch->optarg] = TRUE;
-	return 0;
-}
-
-static void
-awe_set_reverb_mode(int effect)
-{
-	int i;
-	if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
-	    (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
-		return;
-	for (i = 0; i < 28; i++)
-		awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
-			 reverb_parm[effect].parms[i]);
-}
-
-static void
-awe_update_reverb_mode(void)
-{
-	awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
-}
-
-/*
- * treble/bass equalizer control
- */
-
-static unsigned short bass_parm[12][3] = {
-	{0xD26A, 0xD36A, 0x0000}, /* -12 dB */
-	{0xD25B, 0xD35B, 0x0000}, /*  -8 */
-	{0xD24C, 0xD34C, 0x0000}, /*  -6 */
-	{0xD23D, 0xD33D, 0x0000}, /*  -4 */
-	{0xD21F, 0xD31F, 0x0000}, /*  -2 */
-	{0xC208, 0xC308, 0x0001}, /*   0 (HW default) */
-	{0xC219, 0xC319, 0x0001}, /*  +2 */
-	{0xC22A, 0xC32A, 0x0001}, /*  +4 */
-	{0xC24C, 0xC34C, 0x0001}, /*  +6 */
-	{0xC26E, 0xC36E, 0x0001}, /*  +8 */
-	{0xC248, 0xC348, 0x0002}, /* +10 */
-	{0xC26A, 0xC36A, 0x0002}, /* +12 dB */
-};
-
-static unsigned short treble_parm[12][9] = {
-	{0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
-	{0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-	{0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-	{0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-	{0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-	{0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
-	{0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
-	{0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
-	{0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
-	{0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
-	{0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
-	{0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
-};
-
-
-/*
- * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
- */
-static void
-awe_equalizer(int bass, int treble)
-{
-	unsigned short w;
-
-	if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
-		return;
-	awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
-	awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
-	awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
-	awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
-	awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
-	awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
-	awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
-	awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
-	awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
-	awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
-	w = bass_parm[bass][2] + treble_parm[treble][8];
-	awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
-	awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
-}
-
-static void awe_update_equalizer(void)
-{
-	awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
-}
-
-
-/*----------------------------------------------------------------*/
-
-#ifdef CONFIG_AWE32_MIDIEMU
-
-/*
- * Emu8000 MIDI Emulation
- */
-
-/*
- * midi queue record
- */
-
-/* queue type */
-enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
-
-#define MAX_MIDIBUF	64
-
-/* midi status */
-typedef struct MidiStatus {
-	int queue;	/* queue type */
-	int qlen;	/* queue length */
-	int read;	/* chars read */
-	int status;	/* current status */
-	int chan;	/* current channel */
-	unsigned char buf[MAX_MIDIBUF];
-} MidiStatus;
-
-/* MIDI mode type */
-enum { MODE_GM, MODE_GS, MODE_XG, };
-
-/* NRPN / CC -> Emu8000 parameter converter */
-typedef struct {
-	int control;
-	int awe_effect;
-	unsigned short (*convert)(int val);
-} ConvTable;
-
-
-/*
- * prototypes
- */
-
-static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
-static void awe_midi_close(int dev);
-static int awe_midi_ioctl(int dev, unsigned cmd, void __user * arg);
-static int awe_midi_outputc(int dev, unsigned char midi_byte);
-
-static void init_midi_status(MidiStatus *st);
-static void clear_rpn(void);
-static void get_midi_char(MidiStatus *st, int c);
-/*static void queue_varlen(MidiStatus *st, int c);*/
-static void special_event(MidiStatus *st, int c);
-static void queue_read(MidiStatus *st, int c);
-static void midi_note_on(MidiStatus *st);
-static void midi_note_off(MidiStatus *st);
-static void midi_key_pressure(MidiStatus *st);
-static void midi_channel_pressure(MidiStatus *st);
-static void midi_pitch_wheel(MidiStatus *st);
-static void midi_program_change(MidiStatus *st);
-static void midi_control_change(MidiStatus *st);
-static void midi_select_bank(MidiStatus *st, int val);
-static void midi_nrpn_event(MidiStatus *st);
-static void midi_rpn_event(MidiStatus *st);
-static void midi_detune(int chan, int coarse, int fine);
-static void midi_system_exclusive(MidiStatus *st);
-static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
-static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
-static int xg_control_change(MidiStatus *st, int cmd, int val);
-
-#define numberof(ary)	(sizeof(ary)/sizeof(ary[0]))
-
-
-/*
- * OSS Midi device record
- */
-
-static struct midi_operations awe_midi_operations =
-{
-	.owner		= THIS_MODULE,
-	.info		= {"AWE Midi Emu", 0, 0, SNDCARD_SB},
-	.in_info	= {0},
-	.open		= awe_midi_open, /*open*/
-	.close		= awe_midi_close, /*close*/
-	.ioctl		= awe_midi_ioctl, /*ioctl*/
-	.outputc	= awe_midi_outputc, /*outputc*/
-};
-
-static int my_mididev = -1;
-
-static void __init attach_midiemu(void)
-{
-	if ((my_mididev = sound_alloc_mididev()) < 0)
-		printk ("Sound: Too many midi devices detected\n");
-	else
-		midi_devs[my_mididev] = &awe_midi_operations;
-}
-
-static void unload_midiemu(void)
-{
-	if (my_mididev >= 0)
-		sound_unload_mididev(my_mididev);
-}
-
-
-/*
- * open/close midi device
- */
-
-static int midi_opened = FALSE;
-
-static int midi_mode;
-static int coarsetune, finetune;
-
-static int xg_mapping = TRUE;
-static int xg_bankmode;
-
-/* effect sensitivity */
-
-#define FX_CUTOFF	0
-#define FX_RESONANCE	1
-#define FX_ATTACK	2
-#define FX_RELEASE	3
-#define FX_VIBRATE	4
-#define FX_VIBDEPTH	5
-#define FX_VIBDELAY	6
-#define FX_NUMS		7
-
-#define DEF_FX_CUTOFF		170
-#define DEF_FX_RESONANCE	6
-#define DEF_FX_ATTACK		50
-#define DEF_FX_RELEASE		50
-#define DEF_FX_VIBRATE		30
-#define DEF_FX_VIBDEPTH		4
-#define DEF_FX_VIBDELAY		1500
-
-/* effect sense: */
-static int gs_sense[] = 
-{
-	DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
-	DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-static int xg_sense[] = 
-{
-	DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
-	DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-
-
-/* current status */
-static MidiStatus curst;
-
-
-static int
-awe_midi_open (int dev, int mode,
-	       void (*input)(int,unsigned char),
-	       void (*output)(int))
-{
-	if (midi_opened)
-		return -EBUSY;
-
-	midi_opened = TRUE;
-
-	midi_mode = MODE_GM;
-
-	curst.queue = Q_NONE;
-	curst.qlen = 0;
-	curst.read = 0;
-	curst.status = 0;
-	curst.chan = 0;
-	memset(curst.buf, 0, sizeof(curst.buf));
-
-	init_midi_status(&curst);
-
-	return 0;
-}
-
-static void
-awe_midi_close (int dev)
-{
-	midi_opened = FALSE;
-}
-
-
-static int
-awe_midi_ioctl (int dev, unsigned cmd, void __user *arg)
-{
-	return -EPERM;
-}
-
-static int
-awe_midi_outputc (int dev, unsigned char midi_byte)
-{
-	if (! midi_opened)
-		return 1;
-
-	/* force to change playing mode */
-	playing_mode = AWE_PLAY_MULTI;
-
-	get_midi_char(&curst, midi_byte);
-	return 1;
-}
-
-
-/*
- * initialize
- */
-
-static void init_midi_status(MidiStatus *st)
-{
-	clear_rpn();
-	coarsetune = 0;
-	finetune = 0;
-}
-
-
-/*
- * RPN & NRPN
- */
-
-#define MAX_MIDI_CHANNELS	16
-
-/* RPN & NRPN */
-static unsigned char nrpn[MAX_MIDI_CHANNELS];  /* current event is NRPN? */
-static int msb_bit;  /* current event is msb for RPN/NRPN */
-/* RPN & NRPN indeces */
-static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
-/* RPN & NRPN values */
-static int rpn_val[MAX_MIDI_CHANNELS];
-
-static void clear_rpn(void)
-{
-	int i;
-	for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
-		nrpn[i] = 0;
-		rpn_msb[i] = 127;
-		rpn_lsb[i] = 127;
-		rpn_val[i] = 0;
-	}
-	msb_bit = 0;
-}
-
-
-/*
- * process midi queue
- */
-
-/* status event types */
-typedef void (*StatusEvent)(MidiStatus *st);
-static struct StatusEventList {
-	StatusEvent process;
-	int qlen;
-} status_event[8] = {
-	{midi_note_off, 2},
-	{midi_note_on, 2},
-	{midi_key_pressure, 2},
-	{midi_control_change, 2},
-	{midi_program_change, 1},
-	{midi_channel_pressure, 1},
-	{midi_pitch_wheel, 2},
-	{NULL, 0},
-};
-
-
-/* read a char from fifo and process it */
-static void get_midi_char(MidiStatus *st, int c)
-{
-	if (c == 0xfe) {
-		/* ignore active sense */
-		st->queue = Q_NONE;
-		return;
-	}
-
-	switch (st->queue) {
-	/* case Q_VARLEN: queue_varlen(st, c); break;*/
-	case Q_READ:
-	case Q_SYSEX:
-		queue_read(st, c);
-		break;
-	case Q_NONE:
-		st->read = 0;
-		if ((c & 0xf0) == 0xf0) {
-			special_event(st, c);
-		} else if (c & 0x80) { /* status change */
-			st->status = (c >> 4) & 0x07;
-			st->chan = c & 0x0f;
-			st->queue = Q_READ;
-			st->qlen = status_event[st->status].qlen;
-			if (st->qlen == 0)
-				st->queue = Q_NONE;
-		}
-		break;
-	}
-}
-
-/* 0xfx events */
-static void special_event(MidiStatus *st, int c)
-{
-	switch (c) {
-	case 0xf0: /* system exclusive */
-		st->queue = Q_SYSEX;
-		st->qlen = 0;
-		break;
-	case 0xf1: /* MTC quarter frame */
-	case 0xf3: /* song select */
-		st->queue = Q_READ;
-		st->qlen = 1;
-		break;
-	case 0xf2: /* song position */
-		st->queue = Q_READ;
-		st->qlen = 2;
-		break;
-	}
-}
-
-#if 0
-/* read variable length value */
-static void queue_varlen(MidiStatus *st, int c)
-{
-	st->qlen += (c & 0x7f);
-	if (c & 0x80) {
-		st->qlen <<= 7;
-		return;
-	}
-	if (st->qlen <= 0) {
-		st->qlen = 0;
-		st->queue = Q_NONE;
-	}
-	st->queue = Q_READ;
-	st->read = 0;
-}
-#endif
-
-
-/* read a char */
-static void queue_read(MidiStatus *st, int c)
-{
-	if (st->read < MAX_MIDIBUF) {
-		if (st->queue != Q_SYSEX)
-			c &= 0x7f;
-		st->buf[st->read] = (unsigned char)c;
-	}
-	st->read++;
-	if (st->queue == Q_SYSEX && c == 0xf7) {
-		midi_system_exclusive(st);
-		st->queue = Q_NONE;
-	} else if (st->queue == Q_READ && st->read >= st->qlen) {
-		if (status_event[st->status].process)
-			status_event[st->status].process(st);
-		st->queue = Q_NONE;
-	}
-}
-
-
-/*
- * status events
- */
-
-/* note on */
-static void midi_note_on(MidiStatus *st)
-{
-	DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
-	if (st->buf[1] == 0)
-		midi_note_off(st);
-	else
-		awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* note off */
-static void midi_note_off(MidiStatus *st)
-{
-	DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
-	awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* key pressure change */
-static void midi_key_pressure(MidiStatus *st)
-{
-	awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* channel pressure change */
-static void midi_channel_pressure(MidiStatus *st)
-{
-	channels[st->chan].chan_press = st->buf[0];
-	awe_modwheel_change(st->chan, st->buf[0]);
-}
-
-/* pitch wheel change */
-static void midi_pitch_wheel(MidiStatus *st)
-{
-	int val = (int)st->buf[1] * 128 + st->buf[0];
-	awe_bender(0, st->chan, val);
-}
-
-/* program change */
-static void midi_program_change(MidiStatus *st)
-{
-	int preset;
-	preset = st->buf[0];
-	if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
-		preset = 0;
-	else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
-		preset += 64;
-
-	awe_set_instr(0, st->chan, preset);
-}
-
-#define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
-#define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
-#define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
-
-/* midi control change */
-static void midi_control_change(MidiStatus *st)
-{
-	int cmd = st->buf[0];
-	int val = st->buf[1];
-
-	DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
-	if (midi_mode == MODE_XG) {
-		if (xg_control_change(st, cmd, val))
-			return;
-	}
-
-	/* controls #31 - #64 are LSB of #0 - #31 */
-	msb_bit = 1;
-	if (cmd >= 0x20 && cmd < 0x40) {
-		msb_bit = 0;
-		cmd -= 0x20;
-	}
-
-	switch (cmd) {
-	case CTL_SOFT_PEDAL:
-		if (val == 127)
-			add_effect(st->chan, AWE_FX_CUTOFF, -160);
-		else
-			unset_effect(st->chan, AWE_FX_CUTOFF);
-		break;
-
-	case CTL_BANK_SELECT:
-		midi_select_bank(st, val);
-		break;
-		
-	/* set RPN/NRPN parameter */
-	case CTL_REGIST_PARM_NUM_MSB:
-		nrpn[st->chan]=0; rpn_msb[st->chan]=val;
-		break;
-	case CTL_REGIST_PARM_NUM_LSB:
-		nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
-		break;
-	case CTL_NONREG_PARM_NUM_MSB:
-		nrpn[st->chan]=1; rpn_msb[st->chan]=val;
-		break;
-	case CTL_NONREG_PARM_NUM_LSB:
-		nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
-		break;
-
-	/* send RPN/NRPN entry */
-	case CTL_DATA_ENTRY:
-		if (msb_bit)
-			rpn_val[st->chan] = val * 128;
-		else
-			rpn_val[st->chan] |= val;
-		if (nrpn[st->chan])
-			midi_nrpn_event(st);
-		else
-			midi_rpn_event(st);
-		break;
-
-	/* increase/decrease data entry */
-	case CTL_DATA_INCREMENT:
-		rpn_val[st->chan]++;
-		midi_rpn_event(st);
-		break;
-	case CTL_DATA_DECREMENT:
-		rpn_val[st->chan]--;
-		midi_rpn_event(st);
-		break;
-
-	/* default */
-	default:
-		awe_controller(0, st->chan, cmd, val);
-		break;
-	}
-}
-
-/* tone bank change */
-static void midi_select_bank(MidiStatus *st, int val)
-{
-	if (midi_mode == MODE_XG && msb_bit) {
-		xg_bankmode = val;
-		/* XG MSB value; not normal bank selection */
-		switch (val) {
-		case 127: /* remap to drum channel */
-			awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
-			break;
-		default: /* remap to normal channel */
-			awe_controller(0, st->chan, CTL_BANK_SELECT, val);
-			break;
-		}
-		return;
-	} else if (midi_mode == MODE_GS && !msb_bit)
-		/* ignore LSB bank in GS mode (used for mapping) */
-		return;
-
-	/* normal bank controls; accept both MSB and LSB */
-	if (! IS_DRUM_CHANNEL(st->chan)) {
-		if (midi_mode == MODE_XG) {
-			if (xg_bankmode) return;
-			if (val == 64 || val == 126)
-				val = 0;
-		} else if (midi_mode == MODE_GS && val == 127)
-			val = 0;
-		awe_controller(0, st->chan, CTL_BANK_SELECT, val);
-	}
-}
-
-
-/*
- * RPN events
- */
-
-static void midi_rpn_event(MidiStatus *st)
-{
-	int type;
-	type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
-	switch (type) {
-	case 0x0000: /* Pitch bend sensitivity */
-		/* MSB only / 1 semitone per 128 */
-		if (msb_bit) {
-			channels[st->chan].bender_range = 
-				rpn_val[st->chan] * 100 / 128;
-		}
-		break;
-					
-	case 0x0001: /* fine tuning: */
-		/* MSB/LSB, 8192=center, 100/8192 cent step */
-		finetune = rpn_val[st->chan] - 8192;
-		midi_detune(st->chan, coarsetune, finetune);
-		break;
-
-	case 0x0002: /* coarse tuning */
-		/* MSB only / 8192=center, 1 semitone per 128 */
-		if (msb_bit) {
-			coarsetune = rpn_val[st->chan] - 8192;
-			midi_detune(st->chan, coarsetune, finetune);
-		}
-		break;
-
-	case 0x7F7F: /* "lock-in" RPN */
-		break;
-	}
-}
-
-
-/* tuning:
- *   coarse = -8192 to 8192 (100 cent per 128)
- *   fine = -8192 to 8192 (max=100cent)
- */
-static void midi_detune(int chan, int coarse, int fine)
-{
-	/* 4096 = 1200 cents in AWE parameter */
-	int val;
-	val = coarse * 4096 / (12 * 128);
-	val += fine / 24;
-	if (val)
-		send_effect(chan, AWE_FX_INIT_PITCH, val);
-	else
-		unset_effect(chan, AWE_FX_INIT_PITCH);
-}
-
-
-/*
- * system exclusive message
- * GM/GS/XG macros are accepted
- */
-
-static void midi_system_exclusive(MidiStatus *st)
-{
-	/* GM on */
-	static unsigned char gm_on_macro[] = {
-		0x7e,0x7f,0x09,0x01,
-	};
-	/* XG on */
-	static unsigned char xg_on_macro[] = {
-		0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
-	};
-	/* GS prefix
-	 * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
-	 * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
-	 * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
-	 */
-	static unsigned char gs_pfx_macro[] = {
-		0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
-	};
-
-#if 0
-	/* SC88 system mode set
-	 * single module mode: XX=1
-	 * double module mode: XX=0
-	 */
-	static unsigned char gs_mode_macro[] = {
-		0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
-	};
-	/* SC88 display macro: XX=01:bitmap, 00:text
-	 */
-	static unsigned char gs_disp_macro[] = {
-		0x41,0x10,0x45,0x12,0x10,/*XX,00*/
-	};
-#endif
-
-	/* GM on */
-	if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
-		if (midi_mode != MODE_GS && midi_mode != MODE_XG)
-			midi_mode = MODE_GM;
-		init_midi_status(st);
-	}
-
-	/* GS macros */
-	else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
-		if (midi_mode != MODE_GS && midi_mode != MODE_XG)
-			midi_mode = MODE_GS;
-
-		if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
-			/* GS reset */
-			init_midi_status(st);
-		}
-
-		else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
-			/* drum pattern */
-			int p = st->buf[5] & 0x0f;
-			if (p == 0) p = 9;
-			else if (p < 10) p--;
-			if (st->buf[7] == 0)
-				DRUM_CHANNEL_OFF(p);
-			else
-				DRUM_CHANNEL_ON(p);
-
-		} else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
-			/* program */
-			int p = st->buf[5] & 0x0f;
-			if (p == 0) p = 9;
-			else if (p < 10) p--;
-			if (! IS_DRUM_CHANNEL(p))
-				awe_set_instr(0, p, st->buf[7]);
-
-		} else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
-			/* reverb mode */
-			awe_set_reverb_mode(st->buf[7]);
-
-		} else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
-			/* chorus mode */
-			awe_set_chorus_mode(st->buf[7]);
-
-		} else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
-			/* master volume */
-			awe_change_master_volume(st->buf[7]);
-
-		}
-	}
-
-	/* XG on */
-	else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
-		midi_mode = MODE_XG;
-		xg_mapping = TRUE;
-		xg_bankmode = 0;
-	}
-}
-
-
-/*----------------------------------------------------------------*/
-
-/*
- * convert NRPN/control values
- */
-
-static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
-{
-	int i, cval;
-	for (i = 0; i < num_tables; i++) {
-		if (table[i].control == type) {
-			cval = table[i].convert(val);
-			send_effect(st->chan, table[i].awe_effect, cval);
-			return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
-{
-	int i, cval;
-	for (i = 0; i < num_tables; i++) {
-		if (table[i].control == type) {
-			cval = table[i].convert(val);
-			add_effect(st->chan, table[i].awe_effect|0x80, cval);
-			return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-
-/*
- * AWE32 NRPN effects
- */
-
-static unsigned short fx_delay(int val);
-static unsigned short fx_attack(int val);
-static unsigned short fx_hold(int val);
-static unsigned short fx_decay(int val);
-static unsigned short fx_the_value(int val);
-static unsigned short fx_twice_value(int val);
-static unsigned short fx_conv_pitch(int val);
-static unsigned short fx_conv_Q(int val);
-
-/* function for each NRPN */		/* [range]  units */
-#define fx_env1_delay	fx_delay	/* [0,5900] 4msec */
-#define fx_env1_attack	fx_attack	/* [0,5940] 1msec */
-#define fx_env1_hold	fx_hold		/* [0,8191] 1msec */
-#define fx_env1_decay	fx_decay	/* [0,5940] 4msec */
-#define fx_env1_release	fx_decay	/* [0,5940] 4msec */
-#define fx_env1_sustain	fx_the_value	/* [0,127] 0.75dB */
-#define fx_env1_pitch	fx_the_value	/* [-127,127] 9.375cents */
-#define fx_env1_cutoff	fx_the_value	/* [-127,127] 56.25cents */
-
-#define fx_env2_delay	fx_delay	/* [0,5900] 4msec */
-#define fx_env2_attack	fx_attack	/* [0,5940] 1msec */
-#define fx_env2_hold	fx_hold		/* [0,8191] 1msec */
-#define fx_env2_decay	fx_decay	/* [0,5940] 4msec */
-#define fx_env2_release	fx_decay	/* [0,5940] 4msec */
-#define fx_env2_sustain	fx_the_value	/* [0,127] 0.75dB */
-
-#define fx_lfo1_delay	fx_delay	/* [0,5900] 4msec */
-#define fx_lfo1_freq	fx_twice_value	/* [0,127] 84mHz */
-#define fx_lfo1_volume	fx_twice_value	/* [0,127] 0.1875dB */
-#define fx_lfo1_pitch	fx_the_value	/* [-127,127] 9.375cents */
-#define fx_lfo1_cutoff	fx_twice_value	/* [-64,63] 56.25cents */
-
-#define fx_lfo2_delay	fx_delay	/* [0,5900] 4msec */
-#define fx_lfo2_freq	fx_twice_value	/* [0,127] 84mHz */
-#define fx_lfo2_pitch	fx_the_value	/* [-127,127] 9.375cents */
-
-#define fx_init_pitch	fx_conv_pitch	/* [-8192,8192] cents */
-#define fx_chorus	fx_the_value	/* [0,255] -- */
-#define fx_reverb	fx_the_value	/* [0,255] -- */
-#define fx_cutoff	fx_twice_value	/* [0,127] 62Hz */
-#define fx_filterQ	fx_conv_Q	/* [0,127] -- */
-
-static unsigned short fx_delay(int val)
-{
-	return (unsigned short)calc_parm_delay(val);
-}
-
-static unsigned short fx_attack(int val)
-{
-	return (unsigned short)calc_parm_attack(val);
-}
-
-static unsigned short fx_hold(int val)
-{
-	return (unsigned short)calc_parm_hold(val);
-}
-
-static unsigned short fx_decay(int val)
-{
-	return (unsigned short)calc_parm_decay(val);
-}
-
-static unsigned short fx_the_value(int val)
-{
-	return (unsigned short)(val & 0xff);
-}
-
-static unsigned short fx_twice_value(int val)
-{
-	return (unsigned short)((val * 2) & 0xff);
-}
-
-static unsigned short fx_conv_pitch(int val)
-{
-	return (short)(val * 4096 / 1200);
-}
-
-static unsigned short fx_conv_Q(int val)
-{
-	return (unsigned short)((val / 8) & 0xff);
-}
-
-
-static ConvTable awe_effects[] =
-{
-	{ 0, AWE_FX_LFO1_DELAY,	fx_lfo1_delay},
-	{ 1, AWE_FX_LFO1_FREQ,	fx_lfo1_freq},
-	{ 2, AWE_FX_LFO2_DELAY,	fx_lfo2_delay},
-	{ 3, AWE_FX_LFO2_FREQ,	fx_lfo2_freq},
-
-	{ 4, AWE_FX_ENV1_DELAY,	fx_env1_delay},
-	{ 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
-	{ 6, AWE_FX_ENV1_HOLD,	fx_env1_hold},
-	{ 7, AWE_FX_ENV1_DECAY,	fx_env1_decay},
-	{ 8, AWE_FX_ENV1_SUSTAIN,	fx_env1_sustain},
-	{ 9, AWE_FX_ENV1_RELEASE,	fx_env1_release},
-
-	{10, AWE_FX_ENV2_DELAY,	fx_env2_delay},
-	{11, AWE_FX_ENV2_ATTACK,	fx_env2_attack},
-	{12, AWE_FX_ENV2_HOLD,	fx_env2_hold},
-	{13, AWE_FX_ENV2_DECAY,	fx_env2_decay},
-	{14, AWE_FX_ENV2_SUSTAIN,	fx_env2_sustain},
-	{15, AWE_FX_ENV2_RELEASE,	fx_env2_release},
-
-	{16, AWE_FX_INIT_PITCH,	fx_init_pitch},
-	{17, AWE_FX_LFO1_PITCH,	fx_lfo1_pitch},
-	{18, AWE_FX_LFO2_PITCH,	fx_lfo2_pitch},
-	{19, AWE_FX_ENV1_PITCH,	fx_env1_pitch},
-	{20, AWE_FX_LFO1_VOLUME,	fx_lfo1_volume},
-	{21, AWE_FX_CUTOFF,		fx_cutoff},
-	{22, AWE_FX_FILTERQ,	fx_filterQ},
-	{23, AWE_FX_LFO1_CUTOFF,	fx_lfo1_cutoff},
-	{24, AWE_FX_ENV1_CUTOFF,	fx_env1_cutoff},
-	{25, AWE_FX_CHORUS,		fx_chorus},
-	{26, AWE_FX_REVERB,		fx_reverb},
-};
-
-static int num_awe_effects = numberof(awe_effects);
-
-
-/*
- * GS(SC88) NRPN effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static unsigned short gs_cutoff(int val)
-{
-	return (val - 64) * gs_sense[FX_CUTOFF] / 50;
-}
-
-/* resonance: 0 to 15(max) */
-static unsigned short gs_filterQ(int val)
-{
-	return (val - 64) * gs_sense[FX_RESONANCE] / 50;
-}
-
-/* attack: */
-static unsigned short gs_attack(int val)
-{
-	return -(val - 64) * gs_sense[FX_ATTACK] / 50;
-}
-
-/* decay: */
-static unsigned short gs_decay(int val)
-{
-	return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* release: */
-static unsigned short gs_release(int val)
-{
-	return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* vibrato freq: 0.042Hz step, max=255 */
-static unsigned short gs_vib_rate(int val)
-{
-	return (val - 64) * gs_sense[FX_VIBRATE] / 50;
-}
-
-/* vibrato depth: max=127, 1 octave */
-static unsigned short gs_vib_depth(int val)
-{
-	return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
-}
-
-/* vibrato delay: -0.725msec step */
-static unsigned short gs_vib_delay(int val)
-{
-	return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
-}
-
-static ConvTable gs_effects[] =
-{
-	{32, AWE_FX_CUTOFF,	gs_cutoff},
-	{33, AWE_FX_FILTERQ,	gs_filterQ},
-	{99, AWE_FX_ENV2_ATTACK, gs_attack},
-	{100, AWE_FX_ENV2_DECAY, gs_decay},
-	{102, AWE_FX_ENV2_RELEASE, gs_release},
-	{8, AWE_FX_LFO1_FREQ, gs_vib_rate},
-	{9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
-	{10, AWE_FX_LFO1_DELAY, gs_vib_delay},
-};
-
-static int num_gs_effects = numberof(gs_effects);
-
-
-/*
- * NRPN events: accept as AWE32/SC88 specific controls
- */
-
-static void midi_nrpn_event(MidiStatus *st)
-{
-	if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
-		if (! msb_bit) /* both MSB/LSB necessary */
-			send_converted_effect(awe_effects, num_awe_effects,
-					      st, rpn_lsb[st->chan],
-					      rpn_val[st->chan] - 8192);
-	} else if (rpn_msb[st->chan] == 1) {
-		if (msb_bit) /* only MSB is valid */
-			add_converted_effect(gs_effects, num_gs_effects,
-					     st, rpn_lsb[st->chan],
-					     rpn_val[st->chan] / 128);
-	}
-}
-
-
-/*
- * XG control effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static unsigned short xg_cutoff(int val)
-{
-	return (val - 64) * xg_sense[FX_CUTOFF] / 64;
-}
-
-/* resonance: 0(open) to 15(most nasal) */
-static unsigned short xg_filterQ(int val)
-{
-	return (val - 64) * xg_sense[FX_RESONANCE] / 64;
-}
-
-/* attack: */
-static unsigned short xg_attack(int val)
-{
-	return -(val - 64) * xg_sense[FX_ATTACK] / 64;
-}
-
-/* release: */
-static unsigned short xg_release(int val)
-{
-	return -(val - 64) * xg_sense[FX_RELEASE] / 64;
-}
-
-static ConvTable xg_effects[] =
-{
-	{71, AWE_FX_CUTOFF,	xg_cutoff},
-	{74, AWE_FX_FILTERQ,	xg_filterQ},
-	{72, AWE_FX_ENV2_RELEASE, xg_release},
-	{73, AWE_FX_ENV2_ATTACK, xg_attack},
-};
-
-static int num_xg_effects = numberof(xg_effects);
-
-static int xg_control_change(MidiStatus *st, int cmd, int val)
-{
-	return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
-}
-
-#endif /* CONFIG_AWE32_MIDIEMU */
-
-
-/*----------------------------------------------------------------*/
-
-
-/*
- * initialization of AWE driver
- */
-
-static void
-awe_initialize(void)
-{
-	DEBUG(0,printk("AWE32: initializing..\n"));
-
-	/* initialize hardware configuration */
-	awe_poke(AWE_HWCF1, 0x0059);
-	awe_poke(AWE_HWCF2, 0x0020);
-
-	/* disable audio; this seems to reduce a clicking noise a bit.. */
-	awe_poke(AWE_HWCF3, 0);
-
-	/* initialize audio channels */
-	awe_init_audio();
-
-	/* initialize DMA */
-	awe_init_dma();
-
-	/* initialize init array */
-	awe_init_array();
-
-	/* check DRAM memory size */
-	awe_check_dram();
-
-	/* initialize the FM section of the AWE32 */
-	awe_init_fm();
-
-	/* set up voice envelopes */
-	awe_tweak();
-
-	/* enable audio */
-	awe_poke(AWE_HWCF3, 0x0004);
-
-	/* set default values */
-	awe_init_ctrl_parms(TRUE);
-
-	/* set equalizer */
-	awe_update_equalizer();
-
-	/* set reverb & chorus modes */
-	awe_update_reverb_mode();
-	awe_update_chorus_mode();
-}
-
-
-/*
- * Core Device Management Functions
- */
-
-/* store values to i/o port array */
-static void setup_ports(int port1, int port2, int port3)
-{
-	awe_ports[0] = port1;
-	if (port2 == 0)
-		port2 = port1 + 0x400;
-	awe_ports[1] = port2;
-	awe_ports[2] = port2 + 2;
-	if (port3 == 0)
-		port3 = port1 + 0x800;
-	awe_ports[3] = port3;
-	awe_ports[4] = port3 + 2;
-
-	port_setuped = TRUE;
-}
-
-/*
- * port request
- *  0x620-623, 0xA20-A23, 0xE20-E23
- */
-
-static int
-awe_request_region(void)
-{
-	if (! port_setuped)
-		return 0;
-	if (! request_region(awe_ports[0], 4, "sound driver (AWE32)"))
-		return 0;
-	if (! request_region(awe_ports[1], 4, "sound driver (AWE32)"))
-		goto err_out;
-	if (! request_region(awe_ports[3], 4, "sound driver (AWE32)"))
-		goto err_out1;
-	return 1;
-err_out1:
-	release_region(awe_ports[1], 4);
-err_out:
-	release_region(awe_ports[0], 4);
-	return 0;
-}
-
-static void
-awe_release_region(void)
-{
-	if (! port_setuped) return;
-	release_region(awe_ports[0], 4);
-	release_region(awe_ports[1], 4);
-	release_region(awe_ports[3], 4);
-}
-
-static int awe_attach_device(void)
-{
-	if (awe_present) return 0; /* for OSS38.. called twice? */
-
-	/* reserve I/O ports for awedrv */
-	if (! awe_request_region()) {
-		printk(KERN_ERR "AWE32: I/O area already used.\n");
-		return 0;
-	}
-
-	/* set buffers to NULL */
-	sfhead = sftail = NULL;
-
-	my_dev = sound_alloc_synthdev();
-	if (my_dev == -1) {
-		printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
-		awe_release_region();
-		return 0;
-	}
-
-	voice_alloc = &awe_operations.alloc;
-	voice_alloc->max_voice = awe_max_voices;
-	synth_devs[my_dev] = &awe_operations;
-
-#ifdef CONFIG_AWE32_MIXER
-	attach_mixer();
-#endif
-#ifdef CONFIG_AWE32_MIDIEMU
-	attach_midiemu();
-#endif
-
-	/* clear all samples */
-	awe_reset_samples();
-
-	/* initialize AWE32 hardware */
-	awe_initialize();
-
-	sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
-		AWEDRV_VERSION, memsize/1024);
-	printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);
-
-	awe_present = TRUE;
-
-	return 1;
-}
-
-static void awe_dettach_device(void)
-{
-	if (awe_present) {
-		awe_reset_samples();
-		awe_release_region();
-		free_tables();
-#ifdef CONFIG_AWE32_MIXER
-		unload_mixer();
-#endif
-#ifdef CONFIG_AWE32_MIDIEMU
-		unload_midiemu();
-#endif
-		sound_unload_synthdev(my_dev);
-		awe_present = FALSE;
-	}
-}
-
-
-/*
- * Legacy device Probing
- */
-
-/* detect emu8000 chip on the specified address; from VV's guide */
-
-static int __init
-awe_detect_base(int addr)
-{
-	setup_ports(addr, 0, 0);
-	if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
-		return 0;
-	if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
-		return 0;
-	if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
-		return 0;
-        DEBUG(0,printk("AWE32 found at %x\n", addr));
-	return 1;
-}
-
-static int __init awe_detect_legacy_devices(void)
-{
-	int base;
-	for (base = 0x620; base <= 0x680; base += 0x20)
-		if (awe_detect_base(base)) {
-			awe_attach_device();
-			return 1;
-			}
-	DEBUG(0,printk("AWE32 Legacy detection failed\n"));
-	return 0;
-}
-
-
-/*
- * PnP device Probing
- */
-
-static struct pnp_device_id awe_pnp_ids[] = {
-	{.id = "CTL0021", .driver_data = 0}, /* AWE32 WaveTable */
-	{.id = "CTL0022", .driver_data = 0}, /* AWE64 WaveTable */
-	{.id = "CTL0023", .driver_data = 0}, /* AWE64 Gold WaveTable */
-	{ } /* terminator */
-};
-
-MODULE_DEVICE_TABLE(pnp, awe_pnp_ids);
-
-static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
-{
-	int io1, io2, io3;
-
-	if (awe_present) {
-		printk(KERN_ERR "AWE32: This driver only supports one AWE32 device, skipping.\n");
-	}
-
-	if (!pnp_port_valid(dev,0) ||
-	    !pnp_port_valid(dev,1) ||
-	    !pnp_port_valid(dev,2)) {
-		printk(KERN_ERR "AWE32: The PnP device does not have the required resources.\n");
-		return -EINVAL;
-	}
-	io1 = pnp_port_start(dev,0);
-	io2 = pnp_port_start(dev,1);
-	io3 = pnp_port_start(dev,2);
-	printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
-	       io1, io2, io3);
-	setup_ports(io1, io2, io3);
-
-	awe_attach_device();
-	return 0;
-}
-
-static void awe_pnp_remove(struct pnp_dev *dev)
-{
-	awe_dettach_device();
-}
-
-static struct pnp_driver awe_pnp_driver = {
-	.name		= "AWE32",
-	.id_table	= awe_pnp_ids,
-	.probe		= awe_pnp_probe,
-	.remove		= awe_pnp_remove,
-};
-
-static int __init awe_detect_pnp_devices(void)
-{
-	int ret;
-
-	ret = pnp_register_driver(&awe_pnp_driver);
-	if (ret<0)
-		printk(KERN_ERR "AWE32: PnP support is unavailable.\n");
-	return ret;
-}
-
-
-/*
- * device / lowlevel (module) interface
- */
-
-static int __init
-awe_detect(void)
-{
-	printk(KERN_INFO "AWE32: Probing for WaveTable...\n");
-	if (isapnp) {
-		if (awe_detect_pnp_devices()>=0)
-			return 1;
-	} else
-		printk(KERN_INFO "AWE32: Skipping PnP detection.\n");
-
-	if (awe_detect_legacy_devices())
-		return 1;
-
-	return 0;
-}
-
-static int __init attach_awe(void)
-{
-	return awe_detect() ? 0 : -ENODEV;
-}
-
-static void __exit unload_awe(void)
-{
-	pnp_unregister_driver(&awe_pnp_driver);
-	awe_dettach_device();
-}
-
-
-module_init(attach_awe);
-module_exit(unload_awe);
-
-#ifndef MODULE
-static int __init setup_awe(char *str)
-{
-	/* io, memsize, isapnp */
-	int ints[4];
-
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-
-	io = ints[1];
-	memsize = ints[2];
-	isapnp = ints[3];
-
-	return 1;
-}
-
-__setup("awe=", setup_awe);
-#endif
diff --git a/sound/oss/awe_wave.h b/sound/oss/awe_wave.h
deleted file mode 100644
index a3aa018..0000000
--- a/sound/oss/awe_wave.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * sound/awe_config.h
- *
- * Configuration of AWE32/SB32/AWE64 wave table synth driver.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-1998 Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * chorus & reverb effects send for FM chip: from 0 to 0xff
- * larger numbers often cause weird sounds.
- */
-
-#define DEF_FM_CHORUS_DEPTH	0x10
-#define DEF_FM_REVERB_DEPTH	0x10
-
-
-/*
- * other compile conditions
- */
-
-/* initialize FM passthrough even without extended RAM */
-#undef AWE_ALWAYS_INIT_FM
-
-/* debug on */
-#define AWE_DEBUG_ON
-
-/* GUS compatible mode */
-#define AWE_HAS_GUS_COMPATIBILITY
-
-/* add MIDI emulation by wavetable */
-#define CONFIG_AWE32_MIDIEMU
-
-/* add mixer control of emu8000 equalizer */
-#undef CONFIG_AWE32_MIXER
-
-/* use new volume calculation method as default */
-#define AWE_USE_NEW_VOLUME_CALC
-
-/* check current volume target for searching empty voices */
-#define AWE_CHECK_VTARGET
-
-/* allow sample sharing */
-#define AWE_ALLOW_SAMPLE_SHARING
-
-/*
- * AWE32 card configuration:
- * uncomment the following lines *ONLY* when auto detection doesn't
- * work properly on your machine.
- */
-
-/*#define AWE_DEFAULT_BASE_ADDR	0x620*/	/* base port address */
-/*#define AWE_DEFAULT_MEM_SIZE	512*/	/* kbytes */
-
-/*
- * AWE driver version number
- */
-#define AWE_MAJOR_VERSION	0
-#define AWE_MINOR_VERSION	4
-#define AWE_TINY_VERSION	4
-#define AWE_VERSION_NUMBER	((AWE_MAJOR_VERSION<<16)|(AWE_MINOR_VERSION<<8)|AWE_TINY_VERSION)
-#define AWEDRV_VERSION		"0.4.4"
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c
deleted file mode 100644
index ea51aaf..0000000
--- a/sound/oss/cmpci.c
+++ /dev/null
@@ -1,3381 +0,0 @@
-/*
- *      cmpci.c  --  C-Media PCI audio driver.
- *
- *      Copyright (C) 1999  C-media support (support@cmedia.com.tw)
- *
- *      Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 	For update, visit:
- * 		http://www.cmedia.com.tw
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi, Jan Pfeifer
- *
- *
- * Module command line parameters:
- *   none so far
- *
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  The card has both an FM and a Wavetable synth, but I have to figure
- *  out first how to drive them...
- *
- *  Revision history
- *    06.05.98   0.1   Initial release
- *    10.05.98   0.2   Fixed many bugs, esp. ADC rate calculation
- *                     First stab at a simple midi interface (no bells&whistles)
- *    13.05.98   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of
- *                     set_dac_rate in the FMODE_WRITE case in cm_open
- *                     Fix hwptr out of bounds (now mpg123 works)
- *    14.05.98   0.4   Don't allow excessive interrupt rates
- *    08.06.98   0.5   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.98   0.6   Do not include modversions.h
- *                     Now mixer behaviour can basically be selected between
- *                     "OSS documented" and "OSS actual" behaviour
- *    31.08.98   0.7   Fix realplayer problems - dac.count issues
- *    10.12.98   0.8   Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.98   0.9   Fix a few f_file & FMODE_ bugs
- *    06.01.99   0.10  remove the silly SA_INTERRUPT flag.
- *                     hopefully killed the egcs section type conflict
- *    12.03.99   0.11  cinfo.blocks should be reset after GETxPTR ioctl.
- *                     reported by Johan Maes <joma@telindus.be>
- *    22.03.99   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                     read/write cannot be executed
- *    18.08.99   1.5   Only deallocate DMA buffer when unloading.
- *    02.09.99   1.6   Enable SPDIF LOOP
- *                     Change the mixer read back
- *    21.09.99   2.33  Use RCS version as driver version.
- *                     Add support for modem, S/PDIF loop and 4 channels.
- *                     (8738 only)
- *                     Fix bug cause x11amp cannot play.
- *
- *    Fixes:
- *    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *    18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it
- *    		   was calling prog_dmabuf with s->lock held, call missing
- *    		   unlock_kernel in cm_midi_release
- *    08/10/2001 - use set_current_state in some more places
- *
- *	Carlos Eduardo Gorges <carlos@techlinux.com.br>
- *	Fri May 25 2001
- *	- SMP support ( spin[un]lock* revision )
- *	- speaker mixer support
- *	Mon Aug 13 2001
- *	- optimizations and cleanups
- *
- *    03/01/2003 - open_mode fixes from Georg Acher <acher@in.tum.de>
- *	Simon Braunschmidt <brasimon@web.de>
- *     Sat Jan 31 2004
- *	- provide support for opl3 FM by releasing IO range after initialization
- *
- *    ChenLi Tien <cltien@cmedia.com.tw>
- *    Mar 9 2004
- *	- Fix S/PDIF out if spdif_loop enabled
- *	- Load opl3 driver if enabled (fmio in proper range)
- *	- Load mpu401 if enabled (mpuio in proper range)
- *    Apr 5 2004
- *	- Fix DUAL_DAC dma synchronization bug
- *	- Check exist FM/MPU401 I/O before activate.
- *	- Add AFTM_S16_BE format support, so MPlayer/Xine can play AC3/mutlichannel
- *	  on Mac
- *	- Change to support kernel 2.6 so only small patch needed
- *	- All parameters default to 0
- *	- Add spdif_out to send PCM through S/PDIF out jack
- *	- Add hw_copy to get 4-spaker output for general PCM/analog output
- *
- *    Stefan Thater <stefan.thaeter@gmx.de>
- *    Apr 5 2004
- *	- Fix mute single channel for CD/Line-in/AUX-in
- */
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-#include "sound_config.h"
-#include "mpu401.h"
-#endif
-#ifdef CONFIG_SOUND_CMPCI_FM
-#include "opl3.h"
-#endif
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-#include <linux/gameport.h>
-#include <linux/mutex.h>
-
-#endif
-
-/* --------------------------------------------------------------------- */
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#undef DMABYTEIO
-#define	DBG(x) {}
-/* --------------------------------------------------------------------- */
-
-#define CM_MAGIC  ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
-
-/* CM8338 registers definition ****************/
-
-#define CODEC_CMI_FUNCTRL0		(0x00)
-#define CODEC_CMI_FUNCTRL1		(0x04)
-#define CODEC_CMI_CHFORMAT		(0x08)
-#define CODEC_CMI_INT_HLDCLR		(0x0C)
-#define CODEC_CMI_INT_STATUS		(0x10)
-#define CODEC_CMI_LEGACY_CTRL		(0x14)
-#define CODEC_CMI_MISC_CTRL		(0x18)
-#define CODEC_CMI_TDMA_POS		(0x1C)
-#define CODEC_CMI_MIXER			(0x20)
-#define CODEC_SB16_DATA			(0x22)
-#define CODEC_SB16_ADDR			(0x23)
-#define CODEC_CMI_MIXER1		(0x24)
-#define CODEC_CMI_MIXER2		(0x25)
-#define CODEC_CMI_AUX_VOL		(0x26)
-#define CODEC_CMI_MISC			(0x27)
-#define CODEC_CMI_AC97			(0x28)
-
-#define CODEC_CMI_CH0_FRAME1		(0x80)
-#define CODEC_CMI_CH0_FRAME2		(0x84)
-#define CODEC_CMI_CH1_FRAME1		(0x88)
-#define CODEC_CMI_CH1_FRAME2		(0x8C)
-
-#define CODEC_CMI_SPDIF_CTRL		(0x90)
-#define CODEC_CMI_MISC_CTRL2		(0x92)
-
-#define CODEC_CMI_EXT_REG		(0xF0)
-
-/*  Mixer registers for SB16 ******************/
-
-#define DSP_MIX_DATARESETIDX		((unsigned char)(0x00))
-
-#define DSP_MIX_MASTERVOLIDX_L		((unsigned char)(0x30))
-#define DSP_MIX_MASTERVOLIDX_R		((unsigned char)(0x31))
-#define DSP_MIX_VOICEVOLIDX_L		((unsigned char)(0x32))
-#define DSP_MIX_VOICEVOLIDX_R		((unsigned char)(0x33))
-#define DSP_MIX_FMVOLIDX_L		((unsigned char)(0x34))
-#define DSP_MIX_FMVOLIDX_R		((unsigned char)(0x35))
-#define DSP_MIX_CDVOLIDX_L		((unsigned char)(0x36))
-#define DSP_MIX_CDVOLIDX_R		((unsigned char)(0x37))
-#define DSP_MIX_LINEVOLIDX_L		((unsigned char)(0x38))
-#define DSP_MIX_LINEVOLIDX_R		((unsigned char)(0x39))
-
-#define DSP_MIX_MICVOLIDX		((unsigned char)(0x3A))
-#define DSP_MIX_SPKRVOLIDX		((unsigned char)(0x3B))
-
-#define DSP_MIX_OUTMIXIDX		((unsigned char)(0x3C))
-
-#define DSP_MIX_ADCMIXIDX_L		((unsigned char)(0x3D))
-#define DSP_MIX_ADCMIXIDX_R		((unsigned char)(0x3E))
-
-#define DSP_MIX_INGAINIDX_L		((unsigned char)(0x3F))
-#define DSP_MIX_INGAINIDX_R		((unsigned char)(0x40))
-#define DSP_MIX_OUTGAINIDX_L		((unsigned char)(0x41))
-#define DSP_MIX_OUTGAINIDX_R		((unsigned char)(0x42))
-
-#define DSP_MIX_AGCIDX			((unsigned char)(0x43))
-
-#define DSP_MIX_TREBLEIDX_L		((unsigned char)(0x44))
-#define DSP_MIX_TREBLEIDX_R		((unsigned char)(0x45))
-#define DSP_MIX_BASSIDX_L		((unsigned char)(0x46))
-#define DSP_MIX_BASSIDX_R		((unsigned char)(0x47))
-#define DSP_MIX_EXTENSION		((unsigned char)(0xf0))
-// pseudo register for AUX
-#define	DSP_MIX_AUXVOL_L		((unsigned char)(0x50))
-#define	DSP_MIX_AUXVOL_R		((unsigned char)(0x51))
-
-// I/O length
-#define CM_EXTENT_CODEC	  0x100
-#define CM_EXTENT_MIDI	  0x2
-#define CM_EXTENT_SYNTH	  0x4
-#define CM_EXTENT_GAME	  0x8
-
-// Function Control Register 0 (00h)
-#define CHADC0    	0x01
-#define CHADC1    	0x02
-#define PAUSE0	  	0x04
-#define PAUSE1	  	0x08
-
-// Function Control Register 0+2 (02h)
-#define CHEN0     	0x01
-#define CHEN1     	0x02
-#define RST_CH0	  	0x04
-#define RST_CH1	  	0x08
-
-// Function Control Register 1 (04h)
-#define JYSTK_EN	0x02
-#define UART_EN		0x04
-#define	SPDO2DAC	0x40
-#define	SPDFLOOP	0x80
-
-// Function Control Register 1+1 (05h)
-#define	SPDF_0		0x01
-#define	SPDF_1		0x02
-#define	ASFC		0x1c
-#define	DSFC		0xe0
-#define	SPDIF2DAC	(SPDF_1 << 8 | SPDO2DAC)
-
-// Channel Format Register (08h)
-#define CM_CFMT_STEREO	0x01
-#define CM_CFMT_16BIT	0x02
-#define CM_CFMT_MASK	0x03
-#define	POLVALID	0x20
-#define	INVSPDIFI	0x80
-
-// Channel Format Register+2 (0ah)
-#define SPD24SEL	0x20
-
-// Channel Format Register+3 (0bh)
-#define CHB3D		0x20
-#define CHB3D5C		0x80
-
-// Interrupt Hold/Clear Register+2 (0eh)
-#define	CH0_INT_EN	0x01
-#define	CH1_INT_EN	0x02
-
-// Interrupt Register (10h)
-#define CHINT0		0x01
-#define CHINT1		0x02
-#define	CH0BUSY		0x04
-#define	CH1BUSY		0x08
-
-// Legacy Control/Status Register+1 (15h)
-#define	EXBASEN		0x10
-#define	BASE2LIN	0x20
-#define	CENTR2LIN	0x40
-#define	CB2LIN		(BASE2LIN | CENTR2LIN)
-#define	CHB3D6C		0x80
-
-// Legacy Control/Status Register+2 (16h)
-#define	DAC2SPDO	0x20
-#define	SPDCOPYRHT	0x40
-#define	ENSPDOUT	0x80
-
-// Legacy Control/Status Register+3 (17h)
-#define	FMSEL		0x03
-#define	VSBSEL		0x0c
-#define	VMPU		0x60
-#define	NXCHG		0x80
-
-// Miscellaneous Control Register (18h)
-#define	REAR2LIN	0x20
-#define	MUTECH1		0x40
-#define	ENCENTER	0x80
-
-// Miscellaneous Control Register+1 (19h)
-#define	SELSPDIFI2	0x01
-#define	SPDF_AC97	0x80
-
-// Miscellaneous Control Register+2 (1ah)
-#define	AC3_EN		0x04
-#define	FM_EN		0x08
-#define	SPD32SEL	0x20
-#define	XCHGDAC		0x40
-#define	ENDBDAC		0x80
-
-// Miscellaneous Control Register+3 (1bh)
-#define	SPDIFI48K	0x01
-#define	SPDO5V		0x02
-#define	N4SPK3D		0x04
-#define	RESET		0x40
-#define	PWD		0x80
-#define	SPDIF48K	(SPDIFI48K << 24 | SPDF_AC97 << 8)
-
-// Mixer1 (24h)
-#define	CDPLAY		0x01
-#define	X3DEN		0x02
-#define	REAR2FRONT	0x10
-#define	SPK4		0x20
-#define	WSMUTE		0x40
-#define	FMMUTE		0x80
-
-// Miscellaneous Register (27h)
-#define	SPDVALID	0x02
-#define	CENTR2MIC	0x04
-
-// Miscellaneous Register2 (92h)
-#define	SPD32KFMT	0x10
-
-#define CM_CFMT_DACSHIFT   2
-#define CM_CFMT_ADCSHIFT   0
-#define CM_FREQ_DACSHIFT   5
-#define CM_FREQ_ADCSHIFT   2
-#define	RSTDAC	RST_CH1
-#define	RSTADC	RST_CH0
-#define	ENDAC	CHEN1
-#define	ENADC	CHEN0
-#define	PAUSEDAC	PAUSE1
-#define	PAUSEADC	PAUSE0
-#define CODEC_CMI_ADC_FRAME1	CODEC_CMI_CH0_FRAME1
-#define CODEC_CMI_ADC_FRAME2	CODEC_CMI_CH0_FRAME2
-#define CODEC_CMI_DAC_FRAME1	CODEC_CMI_CH1_FRAME1
-#define CODEC_CMI_DAC_FRAME2	CODEC_CMI_CH1_FRAME2
-#define	DACINT	CHINT1
-#define	ADCINT	CHINT0
-#define	DACBUSY	CH1BUSY
-#define	ADCBUSY	CH0BUSY
-#define	ENDACINT	CH1_INT_EN
-#define	ENADCINT	CH0_INT_EN
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[]	= { 0, 1, 1, 2 };
-
-#define SND_DEV_DSP16   5
-
-#define NR_DEVICE 3		/* maximum number of devices */
-
-#define	set_dac1_rate	set_adc_rate
-#define	set_dac1_rate_unlocked	set_adc_rate_unlocked
-#define	stop_dac1	stop_adc
-#define	stop_dac1_unlocked	stop_adc_unlocked
-#define	get_dmadac1	get_dmaadc
-
-static unsigned int devindex = 0;
-
-//*********************************************/
-
-struct cm_state {
-	/* magic */
-	unsigned int magic;
-
-	/* list of cmedia devices */
-	struct list_head devs;
-
-	/* the corresponding pci_dev structure */
-	struct pci_dev *dev;
-
-	int dev_audio;			/* soundcore stuff */
-	int dev_mixer;
-
-	unsigned int iosb, iobase, iosynth,
-			 iomidi, iogame, irq;	/* hardware resources */
-	unsigned short deviceid;		/* pci_id */
-
-        struct {				/* mixer stuff */
-                unsigned int modcnt;
-		unsigned short vol[13];
-        } mix;
-
-	unsigned int rateadc, ratedac;		/* wave stuff */
-	unsigned char fmt, enable;
-
-	spinlock_t lock;
-	struct mutex open_mutex;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-
-	struct dmabuf {
-		void *rawbuf;
-		dma_addr_t dmaaddr;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-		unsigned hwptr, swptr;
-		unsigned total_bytes;
-		int count;
-		unsigned error;		/* over/underrun */
-		wait_queue_head_t wait;
-
-		unsigned fragsize;	/* redundant, but makes calculations easier */
-		unsigned dmasize;
-		unsigned fragsamples;
-		unsigned dmasamples;
-
-		unsigned mapped:1;	/* OSS stuff */
-		unsigned ready:1;
-		unsigned endcleared:1;
-		unsigned enabled:1;
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac, dma_adc;
-
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-	int midi_devc;
-	struct address_info mpu_data;
-#endif
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-	struct gameport *gameport;
-#endif
-
-	int	chip_version;
-	int	max_channels;
-	int	curr_channels;
-	int	capability;		/* HW capability, various for chip versions */
-
-	int	status;			/* HW or SW state */
-
-	int	spdif_counter;		/* spdif frame counter */
-};
-
-/* flags used for capability */
-#define	CAN_AC3_HW		0x00000001		/* 037 or later */
-#define	CAN_AC3_SW		0x00000002		/* 033 or later */
-#define	CAN_AC3			(CAN_AC3_HW | CAN_AC3_SW)
-#define CAN_DUAL_DAC		0x00000004		/* 033 or later */
-#define	CAN_MULTI_CH_HW		0x00000008		/* 039 or later */
-#define	CAN_MULTI_CH		(CAN_MULTI_CH_HW | CAN_DUAL_DAC)
-#define	CAN_LINE_AS_REAR	0x00000010		/* 033 or later */
-#define	CAN_LINE_AS_BASS	0x00000020		/* 039 or later */
-#define	CAN_MIC_AS_BASS		0x00000040		/* 039 or later */
-
-/* flags used for status */
-#define	DO_AC3_HW		0x00000001
-#define	DO_AC3_SW		0x00000002
-#define	DO_AC3			(DO_AC3_HW | DO_AC3_SW)
-#define	DO_DUAL_DAC		0x00000004
-#define	DO_MULTI_CH_HW		0x00000008
-#define	DO_MULTI_CH		(DO_MULTI_CH_HW | DO_DUAL_DAC)
-#define	DO_LINE_AS_REAR		0x00000010		/* 033 or later */
-#define	DO_LINE_AS_BASS		0x00000020		/* 039 or later */
-#define	DO_MIC_AS_BASS		0x00000040		/* 039 or later */
-#define	DO_SPDIF_OUT		0x00000100
-#define	DO_SPDIF_IN		0x00000200
-#define	DO_SPDIF_LOOP		0x00000400
-#define	DO_BIGENDIAN_W		0x00001000		/* used in PowerPC */
-#define	DO_BIGENDIAN_R		0x00002000		/* used in PowerPC */
-
-static LIST_HEAD(devs);
-
-static	int	mpuio;
-static	int	fmio;
-static	int	joystick;
-static	int	spdif_inverse;
-static	int	spdif_loop;
-static	int	spdif_out;
-static	int	use_line_as_rear;
-static	int	use_line_as_bass;
-static	int	use_mic_as_bass;
-static	int	mic_boost;
-static	int	hw_copy;
-module_param(mpuio, int, 0);
-module_param(fmio, int, 0);
-module_param(joystick, bool, 0);
-module_param(spdif_inverse, bool, 0);
-module_param(spdif_loop, bool, 0);
-module_param(spdif_out, bool, 0);
-module_param(use_line_as_rear, bool, 0);
-module_param(use_line_as_bass, bool, 0);
-module_param(use_mic_as_bass, bool, 0);
-module_param(mic_boost, bool, 0);
-module_param(hw_copy, bool, 0);
-MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
-MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
-MODULE_PARM_DESC(joystick, "(1/0) Enable joystick interface, still need joystick driver");
-MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal");
-MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly");
-MODULE_PARM_DESC(spdif_out, "(1/0) Send PCM to S/PDIF-out (PCM volume will not function)");
-MODULE_PARM_DESC(use_line_as_rear, "(1/0) Use line-in jack as rear-out");
-MODULE_PARM_DESC(use_line_as_bass, "(1/0) Use line-in jack as bass/center");
-MODULE_PARM_DESC(use_mic_as_bass, "(1/0) Use mic-in jack as bass/center");
-MODULE_PARM_DESC(mic_boost, "(1/0) Enable microphone boost");
-MODULE_PARM_DESC(hw_copy, "Copy front channel to surround channel");
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned exp=16,l=5,r=0;
-	static const unsigned num[]={0x2,0x4,0x10,0x100,0x10000};
-
-	/* num: 2, 4, 16, 256, 65536 */
-	/* exp: 1, 2,  4,   8,    16 */
-
-	while(l--) {
-		if( x >= num[l] ) {
-			if(num[l]>2) x >>= exp;
-			r+=exp;
-		}
-		exp>>=1;
-	}
-
-	return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void maskb(unsigned int addr, unsigned int mask, unsigned int value)
-{
-	outb((inb(addr) & mask) | value, addr);
-}
-
-static void maskw(unsigned int addr, unsigned int mask, unsigned int value)
-{
-	outw((inw(addr) & mask) | value, addr);
-}
-
-static void maskl(unsigned int addr, unsigned int mask, unsigned int value)
-{
-	outl((inl(addr) & mask) | value, addr);
-}
-
-static void set_dmadac1(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-	if (addr)
-	    outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1);
-	outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2);
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC0, 0);
-}
-
-static void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-	outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1);
-	outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2);
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, CHADC0);
-}
-
-static void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-	outl(addr, s->iobase + CODEC_CMI_DAC_FRAME1);
-	outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2);
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, 0);
-	if (s->status & DO_DUAL_DAC)
-		set_dmadac1(s, 0, count);
-}
-
-static void set_countadc(struct cm_state *s, unsigned count)
-{
-	outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2 + 2);
-}
-
-static void set_countdac(struct cm_state *s, unsigned count)
-{
-	outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2 + 2);
-	if (s->status & DO_DUAL_DAC)
-	    set_countadc(s, count);
-}
-
-static unsigned get_dmadac(struct cm_state *s)
-{
-	unsigned int curr_addr;
-
-	curr_addr = inw(s->iobase + CODEC_CMI_DAC_FRAME2) + 1;
-	curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
-	curr_addr = s->dma_dac.dmasize - curr_addr;
-
-	return curr_addr;
-}
-
-static unsigned get_dmaadc(struct cm_state *s)
-{
-	unsigned int curr_addr;
-
-	curr_addr = inw(s->iobase + CODEC_CMI_ADC_FRAME2) + 1;
-	curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK];
-	curr_addr = s->dma_adc.dmasize - curr_addr;
-
-	return curr_addr;
-}
-
-static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
-{
-	unsigned char regval, pseudo;
-
-	// pseudo register
-	if (idx == DSP_MIX_AUXVOL_L) {
-		data >>= 4;
-		data &= 0x0f;
-		regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0x0f;
-		outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL);
-		return;
-	}
-	if (idx == DSP_MIX_AUXVOL_R) {
-		data &= 0xf0;
-		regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0xf0;
-		outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL);
-		return;
-	}
-	outb(idx, s->iobase + CODEC_SB16_ADDR);
-	udelay(10);
-	// pseudo bits
-	if (idx == DSP_MIX_OUTMIXIDX) {
-		pseudo = data & ~0x1f;
-		pseudo >>= 1;
-		regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x30;
-		outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-	}
-	if (idx == DSP_MIX_ADCMIXIDX_L) {
-		pseudo = data & 0x80;
-		pseudo >>= 1;
-		regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x40;
-		outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-	}
-	if (idx == DSP_MIX_ADCMIXIDX_R) {
-		pseudo = data & 0x80;
-		regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x80;
-		outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-	}
-	outb(data, s->iobase + CODEC_SB16_DATA);
-	udelay(10);
-}
-
-static unsigned char rdmixer(struct cm_state *s, unsigned char idx)
-{
-	unsigned char v, pseudo;
-
-	// pseudo register
-	if (idx == DSP_MIX_AUXVOL_L) {
-		v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0x0f;
-		v <<= 4;
-		return v;
-	}
-	if (idx == DSP_MIX_AUXVOL_L) {
-		v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0xf0;
-		return v;
-	}
-	outb(idx, s->iobase + CODEC_SB16_ADDR);
-	udelay(10);
-	v = inb(s->iobase + CODEC_SB16_DATA);
-	udelay(10);
-	// pseudo bits
-	if (idx == DSP_MIX_OUTMIXIDX) {
-		pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x30;
-		pseudo <<= 1;
-		v |= pseudo;
-	}
-	if (idx == DSP_MIX_ADCMIXIDX_L) {
-		pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x40;
-		pseudo <<= 1;
-		v |= pseudo;
-	}
-	if (idx == DSP_MIX_ADCMIXIDX_R) {
-		pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x80;
-		v |= pseudo;
-	}
-	return v;
-}
-
-static void set_fmt_unlocked(struct cm_state *s, unsigned char mask, unsigned char data)
-{
-	if (mask && s->chip_version > 0) {	/* 8338 cannot keep this */
-		s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
-		udelay(10);
-	}
-	s->fmt = (s->fmt & mask) | data;
-	outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
-	udelay(10);
-}
-
-static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	set_fmt_unlocked(s,mask,data);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data)
-{
-	outb(idx, s->iobase + CODEC_SB16_ADDR);
-	udelay(10);
-	outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
-	udelay(10);
-}
-
-static struct {
-	unsigned	rate;
-	unsigned	lower;
-	unsigned	upper;
-	unsigned char	freq;
-} rate_lookup[] =
-{
-	{ 5512,		(0 + 5512) / 2,		(5512 + 8000) / 2,	0 },
-	{ 8000,		(5512 + 8000) / 2,	(8000 + 11025) / 2,	4 },
-	{ 11025,	(8000 + 11025) / 2,	(11025 + 16000) / 2,	1 },
-	{ 16000,	(11025 + 16000) / 2,	(16000 + 22050) / 2,	5 },
-	{ 22050,	(16000 + 22050) / 2,	(22050 + 32000) / 2,	2 },
-	{ 32000,	(22050 + 32000) / 2,	(32000 + 44100) / 2,	6 },
-	{ 44100,	(32000 + 44100) / 2,	(44100 + 48000) / 2,	3 },
-	{ 48000,	(44100 + 48000) / 2,	48000,			7 }
-};
-
-static void set_spdif_copyright(struct cm_state *s, int spdif_copyright)
-{
-	/* enable SPDIF-in Copyright */
-	maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~SPDCOPYRHT, spdif_copyright ? SPDCOPYRHT : 0);
-}
-
-static void set_spdif_loop(struct cm_state *s, int spdif_loop)
-{
-	/* enable SPDIF loop */
-	if (spdif_loop) {
-		s->status |= DO_SPDIF_LOOP;
-		/* turn on spdif-in to spdif-out */
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, SPDFLOOP);
-	} else {
-		s->status &= ~DO_SPDIF_LOOP;
-		/* turn off spdif-in to spdif-out */
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDFLOOP, 0);
-	}
-}
-
-static void set_spdif_monitor(struct cm_state *s, int channel)
-{
-	// SPDO2DAC
-	maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDO2DAC, channel == 2 ? SPDO2DAC : 0);
-	// CDPLAY
-	if (s->chip_version >= 39)
-		maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, channel ? CDPLAY : 0);
-}
-
-static void set_spdifout_level(struct cm_state *s, int level5v)
-{
-	/* SPDO5V */
-	if (s->chip_version > 0)
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~SPDO5V, level5v ? SPDO5V : 0);
-}
-
-static void set_spdifin_inverse(struct cm_state *s, int spdif_inverse)
-{
-	if (s->chip_version == 0)	/* 8338 has not this feature */
-		return;
-	if (spdif_inverse) {
-		/* turn on spdif-in inverse */
-		if (s->chip_version >= 39)
-			maskb(s->iobase + CODEC_CMI_CHFORMAT, ~0, INVSPDIFI);
-		else
-			maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1);
-	} else {
-		/* turn off spdif-ininverse */
-		if (s->chip_version >= 39)
-			maskb(s->iobase + CODEC_CMI_CHFORMAT, ~INVSPDIFI, 0);
-		else
-			maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
-	}
-}
-
-static void set_spdifin_channel2(struct cm_state *s, int channel2)
-{
-	/* SELSPDIFI2 */
-	if (s->chip_version >= 39)
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 1, ~SELSPDIFI2, channel2 ? SELSPDIFI2 : 0);
-}
-
-static void set_spdifin_valid(struct cm_state *s, int valid)
-{
-	/* SPDVALID */
-	maskb(s->iobase + CODEC_CMI_MISC, ~SPDVALID, valid ? SPDVALID : 0);
-}
-
-static void set_spdifout_unlocked(struct cm_state *s, unsigned rate)
-{
-	if (rate != 48000 && rate != 44100)
-		rate = 0;
-	if (rate == 48000 || rate == 44100) {
-		set_spdif_loop(s, 0);
-		// SPDF_1
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1);
-		// SPDIFI48K SPDF_AC97
-		maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0);
-		if (s->chip_version >= 55)
-		// SPD32KFMT
-			maskb(s->iobase + CODEC_CMI_MISC_CTRL2, ~SPD32KFMT, rate == 48000 ? SPD32KFMT : 0);
-		if (s->chip_version > 0)
-		// ENSPDOUT
-			maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, ENSPDOUT);
-		// monitor SPDIF out
-		set_spdif_monitor(s, 2);
-		s->status |= DO_SPDIF_OUT;
-	} else {
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0);
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~ENSPDOUT, 0);
-		// monitor none
-		set_spdif_monitor(s, 0);
-		s->status &= ~DO_SPDIF_OUT;
-	}
-}
-
-static void set_spdifout(struct cm_state *s, unsigned rate)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	set_spdifout_unlocked(s,rate);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_spdifin_unlocked(struct cm_state *s, unsigned rate)
-{
-	if (rate == 48000 || rate == 44100) {
-		// SPDF_1
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1);
-		// SPDIFI48K SPDF_AC97
-		maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0);
-		s->status |= DO_SPDIF_IN;
-	} else {
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0);
-		s->status &= ~DO_SPDIF_IN;
-	}
-}
-
-static void set_spdifin(struct cm_state *s, unsigned rate)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	set_spdifin_unlocked(s,rate);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* find parity for bit 4~30 */
-static unsigned parity(unsigned data)
-{
-	unsigned parity = 0;
-	int counter = 4;
-
-	data >>= 4;	// start from bit 4
-	while (counter <= 30) {
-		if (data & 1)
-			parity++;
-		data >>= 1;
-		counter++;
-	}
-	return parity & 1;
-}
-
-static void set_ac3_unlocked(struct cm_state *s, unsigned rate)
-{
-	if (!(s->capability & CAN_AC3))
-		return;
-	/* enable AC3 */
-	if (rate && rate != 44100)
-		rate = 48000;
-	if (rate == 48000 || rate == 44100) {
-		// mute DAC
-		maskb(s->iobase + CODEC_CMI_MIXER1, ~0, WSMUTE);
-		if (s->chip_version >= 39)
-			maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~0, MUTECH1);
-		// AC3EN for 039, 0x04
-		if (s->chip_version >= 39) {
-			maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, AC3_EN);
-			if (s->chip_version == 55)
-				maskb(s->iobase + CODEC_CMI_SPDIF_CTRL, ~2, 0);
-		// AC3EN for 037, 0x10
-		} else if (s->chip_version == 37)
-			maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x10);
-		if (s->capability & CAN_AC3_HW) {
-			// SPD24SEL for 039, 0x20, but cannot be set
-			if (s->chip_version == 39)
-				maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, SPD24SEL);
-			// SPD24SEL for 037, 0x02
-			else if (s->chip_version == 37)
-				maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x02);
-			if (s->chip_version >= 39)
-				maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, 0);
-
-			s->status |= DO_AC3_HW;
-		 } else {
-			// SPD32SEL for 037 & 039
-			maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, SPD32SEL);
-			// set 176K sample rate to fix 033 HW bug
-			if (s->chip_version == 33) {
-				if (rate == 48000)
-					maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0, 0x08);
-				else
-					maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
-			}
-			s->status |= DO_AC3_SW;
-		}
-	} else {
-		maskb(s->iobase + CODEC_CMI_MIXER1, ~WSMUTE, 0);
-		if (s->chip_version >= 39)
-			maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~MUTECH1, 0);
-		maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~(SPD24SEL|0x12), 0);
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~(SPD32SEL|AC3_EN), 0);
-		if (s->chip_version == 33)
-			maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
-		if (s->chip_version >= 39)
-			maskb(s->iobase + CODEC_CMI_MIXER1, ~0, CDPLAY);
-		s->status &= ~DO_AC3;
-	}
-	s->spdif_counter = 0;
-}
-
-static void set_line_as_rear(struct cm_state *s, int use_line_as_rear)
-{
-	if (!(s->capability & CAN_LINE_AS_REAR))
-		return;
-	if (use_line_as_rear) {
-		maskb(s->iobase + CODEC_CMI_MIXER1, ~0, SPK4);
-		s->status |= DO_LINE_AS_REAR;
-	} else {
-		maskb(s->iobase + CODEC_CMI_MIXER1, ~SPK4, 0);
-		s->status &= ~DO_LINE_AS_REAR;
-	}
-}
-
-static void set_line_as_bass(struct cm_state *s, int use_line_as_bass)
-{
-	if (!(s->capability & CAN_LINE_AS_BASS))
-		return;
-	if (use_line_as_bass) {
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0, CB2LIN);
-		s->status |= DO_LINE_AS_BASS;
-	} else {
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CB2LIN, 0);
-		s->status &= ~DO_LINE_AS_BASS;
-	}
-}
-
-static void set_mic_as_bass(struct cm_state *s, int use_mic_as_bass)
-{
-	if (!(s->capability & CAN_MIC_AS_BASS))
-		return;
-	if (use_mic_as_bass) {
-		maskb(s->iobase + CODEC_CMI_MISC, ~0, 0x04);
-		s->status |= DO_MIC_AS_BASS;
-	} else {
-		maskb(s->iobase + CODEC_CMI_MISC, ~0x04, 0);
-		s->status &= ~DO_MIC_AS_BASS;
-	}
-}
-
-static void set_hw_copy(struct cm_state *s, int hw_copy)
-{
-    	if (s->max_channels > 2 && hw_copy)
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0, N4SPK3D);
-    	else
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~N4SPK3D, 0);
-}
-
-static void set_ac3(struct cm_state *s, unsigned rate)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	set_spdifout_unlocked(s, rate);
-	set_ac3_unlocked(s, rate);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static int trans_ac3(struct cm_state *s, void *dest, const char __user *source, int size)
-{
-	int   i = size / 2;
-	unsigned long data;
-	unsigned short data16;
-	unsigned long *dst = (unsigned long *) dest;
-	unsigned short __user *src = (unsigned short __user *)source;
-	int err;
-
-	do {
-		if ((err = __get_user(data16, src++)))
-			return err;
-		data = (unsigned long)le16_to_cpu(data16);
-		data <<= 12;			// ok for 16-bit data
-		if (s->spdif_counter == 2 || s->spdif_counter == 3)
-			data |= 0x40000000;	// indicate AC-3 raw data
-		if (parity(data))
-			data |= 0x80000000;	// parity
-		if (s->spdif_counter == 0)
-			data |= 3;		// preamble 'M'
-		else if (s->spdif_counter & 1)
-			data |= 5;		// odd, 'W'
-		else
-			data |= 9;		// even, 'M'
-		*dst++ = cpu_to_le32(data);
-		s->spdif_counter++;
-		if (s->spdif_counter == 384)
-			s->spdif_counter = 0;
-	} while (--i);
-
-	return 0;
-}
-
-static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
-{
-	unsigned char freq = 4;
-	int	i;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 8000)
-		rate = 8000;
-	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-			rate = rate_lookup[i].rate;
-			freq = rate_lookup[i].freq;
-			break;
-	    	}
-	}
-	s->rateadc = rate;
-	freq <<= CM_FREQ_ADCSHIFT;
-
-	maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq);
-}
-
-static void set_adc_rate(struct cm_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned char freq = 4;
-	int	i;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 8000)
-		rate = 8000;
-	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-			rate = rate_lookup[i].rate;
-			freq = rate_lookup[i].freq;
-			break;
-	    	}
-	}
-	s->rateadc = rate;
-	freq <<= CM_FREQ_ADCSHIFT;
-
-	spin_lock_irqsave(&s->lock, flags);
-	maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_dac_rate(struct cm_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned char freq = 4;
-	int	i;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 8000)
-		rate = 8000;
-	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-			rate = rate_lookup[i].rate;
-			freq = rate_lookup[i].freq;
-			break;
-	    	}
-	}
-	s->ratedac = rate;
-	freq <<= CM_FREQ_DACSHIFT;
-
-	spin_lock_irqsave(&s->lock, flags);
-	maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~DSFC, freq);
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	if (s->curr_channels <= 2 && spdif_out)
-		set_spdifout(s, rate);
-	if (s->status & DO_DUAL_DAC)
-		set_dac1_rate(s, rate);
-}
-
-/* --------------------------------------------------------------------- */
-static inline void reset_adc(struct cm_state *s)
-{
-	/* reset bus master */
-	outb(s->enable | RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	udelay(10);
-	outb(s->enable & ~RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-}
-
-static inline void reset_dac(struct cm_state *s)
-{
-	/* reset bus master */
-	outb(s->enable | RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	udelay(10);
-	outb(s->enable & ~RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	if (s->status & DO_DUAL_DAC)
-		reset_adc(s);
-}
-
-static inline void pause_adc(struct cm_state *s)
-{
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEADC);
-}
-
-static inline void pause_dac(struct cm_state *s)
-{
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEDAC);
-	if (s->status & DO_DUAL_DAC)
-		pause_adc(s);
-}
-
-static inline void disable_adc(struct cm_state *s)
-{
-	/* disable channel */
-	s->enable &= ~ENADC;
-	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	reset_adc(s);
-}
-
-static inline void disable_dac(struct cm_state *s)
-{
-	/* disable channel */
-	s->enable &= ~ENDAC;
-	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	reset_dac(s);
-	if (s->status & DO_DUAL_DAC)
-		disable_adc(s);
-}
-
-static inline void enable_adc(struct cm_state *s)
-{
-	if (!(s->enable & ENADC)) {
-		/* enable channel */
-		s->enable |= ENADC;
-		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	}
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEADC, 0);
-}
-
-static inline void enable_dac_unlocked(struct cm_state *s)
-{
-	if (!(s->enable & ENDAC)) {
-		/* enable channel */
-		s->enable |= ENDAC;
-		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	}
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEDAC, 0);
-
-	if (s->status & DO_DUAL_DAC)
-		enable_adc(s);
-}
-
-static inline void stop_adc_unlocked(struct cm_state *s)
-{
-	if (s->enable & ENADC) {
-		/* disable interrupt */
-		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENADCINT, 0);
-		disable_adc(s);
-	}
-}
-
-static inline void stop_adc(struct cm_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	stop_adc_unlocked(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-
-}
-
-static inline void stop_dac_unlocked(struct cm_state *s)
-{
-	if (s->enable & ENDAC) {
-		/* disable interrupt */
-		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENDACINT, 0);
-		disable_dac(s);
-	}
-	if (s->status & DO_DUAL_DAC)
-		stop_dac1_unlocked(s);
-}
-
-static inline void stop_dac(struct cm_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	stop_dac_unlocked(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static inline void start_adc_unlocked(struct cm_state *s)
-{
-	if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-	    && s->dma_adc.ready) {
-		/* enable interrupt */
-		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT);
-		enable_adc(s);
-	}
-}
-
-static void start_adc(struct cm_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	start_adc_unlocked(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac1_unlocked(struct cm_state *s)
-{
-	if ((s->dma_adc.mapped || s->dma_adc.count > 0) && s->dma_adc.ready) {
-		/* enable interrupt */
-		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT);
- 		enable_dac_unlocked(s);
-	}
-}
-
-static void start_dac_unlocked(struct cm_state *s)
-{
-	if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-		/* enable interrupt */
-		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENDACINT);
-		enable_dac_unlocked(s);
-	}
-	if (s->status & DO_DUAL_DAC)
-		start_dac1_unlocked(s);
-}
-
-static void start_dac(struct cm_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	start_dac_unlocked(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static int prog_dmabuf(struct cm_state *s, unsigned rec);
-
-static int set_dac_channels(struct cm_state *s, int channels)
-{
-	unsigned long flags;
-	static unsigned int fmmute = 0;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	if ((channels > 2) && (channels <= s->max_channels)
-	 && (((s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK) == (CM_CFMT_STEREO | CM_CFMT_16BIT))) {
-	    set_spdifout_unlocked(s, 0);
-	    if (s->capability & CAN_MULTI_CH_HW) {
-		// NXCHG
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0, NXCHG);
-		// CHB3D or CHB3D5C
-	       	maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), channels > 4 ? CHB3D5C : CHB3D);
-		// CHB3D6C
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, channels == 6 ? CHB3D6C : 0);
-		// ENCENTER
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~ENCENTER, channels == 6 ? ENCENTER : 0);
-		s->status |= DO_MULTI_CH_HW;
-	    } else if (s->capability & CAN_DUAL_DAC) {
-		unsigned char fmtm = ~0, fmts = 0;
-		ssize_t ret;
-
-		// ENDBDAC, turn on double DAC mode
-		// XCHGDAC, CH0 -> back, CH1->front
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, ENDBDAC|XCHGDAC);
-		// mute FM
-		fmmute = inb(s->iobase + CODEC_CMI_MIXER1) & FMMUTE;
-		maskb(s->iobase + CODEC_CMI_MIXER1, ~0, FMMUTE);
-		s->status |= DO_DUAL_DAC;
-		// prepare secondary buffer
-		spin_unlock_irqrestore(&s->lock, flags);
-		ret = prog_dmabuf(s, 1);
-		if (ret) return ret;
-		spin_lock_irqsave(&s->lock, flags);
-
-		// copy the hw state
-		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
-		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
-		// the HW only support 16-bit stereo
-		fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-		fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-		fmts |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-		fmts |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-
-		set_fmt_unlocked(s, fmtm, fmts);
-		set_adc_rate_unlocked(s, s->ratedac);
-	    }
-	    // disable 4 speaker mode (analog duplicate)
-	    set_hw_copy(s, 0);
-	    s->curr_channels = channels;
-
-	    // enable jack redirect
-	    set_line_as_rear(s, use_line_as_rear);
-	    if (channels > 4) {
-		    set_line_as_bass(s, use_line_as_bass);
-		    set_mic_as_bass(s, use_mic_as_bass);
-	    }
-	} else {
-	    if (s->status & DO_MULTI_CH_HW) {
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~NXCHG, 0);
-		maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), 0);
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, 0);
-	    } else if (s->status & DO_DUAL_DAC) {
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~ENDBDAC, 0);
-		maskb(s->iobase + CODEC_CMI_MIXER1, ~FMMUTE, fmmute);
-	    }
-	    // enable 4 speaker mode (analog duplicate)
-	    set_hw_copy(s, hw_copy);
-	    s->status &= ~DO_MULTI_CH;
-	    s->curr_channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
-	    // disable jack redirect
-	    set_line_as_rear(s, hw_copy ? use_line_as_rear : 0);
-	    set_line_as_bass(s, 0);
-	    set_mic_as_bass(s, 0);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return s->curr_channels;
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static void dealloc_dmabuf(struct cm_state *s, struct dmabuf *db)
-{
-	struct page *pstart, *pend;
-
-	if (db->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
-			ClearPageReserved(pstart);
-		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-	}
-	db->rawbuf = NULL;
-	db->mapped = db->ready = 0;
-}
-
-/* Ch1 is used for playback, Ch0 is used for recording */
-
-static int prog_dmabuf(struct cm_state *s, unsigned rec)
-{
-	struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-	unsigned rate = rec ? s->rateadc : s->ratedac;
-	int order;
-	unsigned bytepersec;
-	unsigned bufs;
-	struct page *pstart, *pend;
-	unsigned char fmt;
-	unsigned long flags;
-
-	fmt = s->fmt;
-	if (rec) {
-		stop_adc(s);
-		fmt >>= CM_CFMT_ADCSHIFT;
-	} else {
-		stop_dac(s);
-		fmt >>= CM_CFMT_DACSHIFT;
-	}
-
-	fmt &= CM_CFMT_MASK;
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-				break;
-		if (!db->rawbuf || !db->dmaaddr)
-			return -ENOMEM;
-		db->buforder = order;
-		/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
-			SetPageReserved(pstart);
-	}
-	bytepersec = rate << sample_shift[fmt];
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < bytepersec)
-			db->fragshift = ld2(bytepersec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3;
-	}
-	db->numfrag = bufs >> db->fragshift;
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->numfrag = bufs >> db->fragshift;
-	}
-	db->fragsize = 1 << db->fragshift;
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
- 	/* to make fragsize >= 4096 */
-	db->fragsamples = db->fragsize >> sample_shift[fmt];
-	db->dmasize = db->numfrag << db->fragshift;
-	db->dmasamples = db->dmasize >> sample_shift[fmt];
-	memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
-	spin_lock_irqsave(&s->lock, flags);
-	if (rec) {
-		if (s->status & DO_DUAL_DAC)
-		    set_dmadac1(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-		else
-		    set_dmaadc(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-		/* program sample counts */
-		set_countdac(s, db->fragsamples);
-	} else {
-		set_dmadac(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-		/* program sample counts */
-		set_countdac(s, db->fragsamples);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	db->enabled = 1;
-	db->ready = 1;
-	return 0;
-}
-
-static inline void clear_advance(struct cm_state *s)
-{
-	unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_DACSHIFT)) ? 0 : 0x80;
-	unsigned char *buf = s->dma_dac.rawbuf;
-	unsigned char *buf1 = s->dma_adc.rawbuf;
-	unsigned bsize = s->dma_dac.dmasize;
-	unsigned bptr = s->dma_dac.swptr;
-	unsigned len = s->dma_dac.fragsize;
-
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(buf + bptr, c, x);
-		if (s->status & DO_DUAL_DAC)
-			memset(buf1 + bptr, c, x);
-		bptr = 0;
-		len -= x;
-	}
-	memset(buf + bptr, c, len);
-	if (s->status & DO_DUAL_DAC)
-		memset(buf1 + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void cm_update_ptr(struct cm_state *s)
-{
-	unsigned hwptr;
-	int diff;
-
-	/* update ADC pointer */
-	if (s->dma_adc.ready) {
-	    if (s->status & DO_DUAL_DAC) {
-		    /* the dac part will finish for this */
-	    } else {
-		hwptr = get_dmaadc(s) % s->dma_adc.dmasize;
-		diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-		s->dma_adc.hwptr = hwptr;
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-			wake_up(&s->dma_adc.wait);
-		if (!s->dma_adc.mapped) {
-			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-				pause_adc(s);
-				s->dma_adc.error++;
-			}
-		}
-	    }
-	}
-	/* update DAC pointer */
-	if (s->dma_dac.ready) {
-		hwptr = get_dmadac(s) % s->dma_dac.dmasize;
-		diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-		s->dma_dac.hwptr = hwptr;
-		s->dma_dac.total_bytes += diff;
-		if (s->status & DO_DUAL_DAC) {
-			s->dma_adc.hwptr = hwptr;
-			s->dma_adc.total_bytes += diff;
-		}
-		if (s->dma_dac.mapped) {
-			s->dma_dac.count += diff;
-			if (s->status & DO_DUAL_DAC)
-				s->dma_adc.count += diff;
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-				wake_up(&s->dma_dac.wait);
-		} else {
-			s->dma_dac.count -= diff;
-			if (s->status & DO_DUAL_DAC)
-				s->dma_adc.count -= diff;
-			if (s->dma_dac.count <= 0) {
-				pause_dac(s);
-				s->dma_dac.error++;
-			} else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-				clear_advance(s);
-				s->dma_dac.endcleared = 1;
-				if (s->status & DO_DUAL_DAC)
-					s->dma_adc.endcleared = 1;
-			}
-			if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
-				wake_up(&s->dma_dac.wait);
-		}
-	}
-}
-
-static irqreturn_t cm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct cm_state *s = (struct cm_state *)dev_id;
-	unsigned int intsrc, intstat;
-	unsigned char mask = 0;
-
-	/* fastpath out, to ease interrupt sharing */
-	intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS);
-	if (!(intsrc & 0x80000000))
-		return IRQ_NONE;
-	spin_lock(&s->lock);
-	intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	/* acknowledge interrupt */
-	if (intsrc & ADCINT)
-		mask |= ENADCINT;
-	if (intsrc & DACINT)
-		mask |= ENDACINT;
-	outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	cm_update_ptr(s);
-	spin_unlock(&s->lock);
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-	if (intsrc & 0x00010000) {	// UART interrupt
-		if (s->midi_devc && intchk_mpu401((void *)s->midi_devc))
-			mpuintr(irq, (void *)s->midi_devc, regs);
-		else
-			inb(s->iomidi);// dummy read
-	}
-#endif
-	return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-	if (!(s) || (s)->magic != CM_MAGIC) { \
-		printk(invalid_magic);            \
-		return -ENXIO;                    \
-	}                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-#define MT_4          1
-#define MT_5MUTE      2
-#define MT_4MUTEMONO  3
-#define MT_6MUTE      4
-#define MT_5MUTEMONO  5
-
-static const struct {
-	unsigned left;
-	unsigned right;
-	unsigned type;
-	unsigned rec;
-	unsigned play;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-	[SOUND_MIXER_CD]     = { DSP_MIX_CDVOLIDX_L,     DSP_MIX_CDVOLIDX_R,     MT_5MUTE,     0x04, 0x06 },
-	[SOUND_MIXER_LINE]   = { DSP_MIX_LINEVOLIDX_L,   DSP_MIX_LINEVOLIDX_R,   MT_5MUTE,     0x10, 0x18 },
-	[SOUND_MIXER_MIC]    = { DSP_MIX_MICVOLIDX,      DSP_MIX_MICVOLIDX,      MT_5MUTEMONO, 0x01, 0x01 },
-	[SOUND_MIXER_SYNTH]  = { DSP_MIX_FMVOLIDX_L,  	 DSP_MIX_FMVOLIDX_R,     MT_5MUTE,     0x40, 0x00 },
-	[SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE,     0x00, 0x00 },
-	[SOUND_MIXER_PCM]    = { DSP_MIX_VOICEVOLIDX_L,  DSP_MIX_VOICEVOLIDX_R,  MT_5MUTE,     0x00, 0x00 },
-	[SOUND_MIXER_LINE1]  = { DSP_MIX_AUXVOL_L,       DSP_MIX_AUXVOL_R,       MT_5MUTE,     0x80, 0x60 },
-	[SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX,	 DSP_MIX_SPKRVOLIDX,	 MT_5MUTEMONO, 0x00, 0x01 }
-};
-
-static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
-{
-	[SOUND_MIXER_CD]     = 1,
-	[SOUND_MIXER_LINE]   = 2,
-	[SOUND_MIXER_MIC]    = 3,
-	[SOUND_MIXER_SYNTH]  = 4,
-	[SOUND_MIXER_VOLUME] = 5,
-	[SOUND_MIXER_PCM]    = 6,
-	[SOUND_MIXER_LINE1]  = 7,
-	[SOUND_MIXER_SPEAKER]= 8
-};
-
-static unsigned mixer_outmask(struct cm_state *s)
-{
-	unsigned long flags;
-	int i, j, k;
-
-	spin_lock_irqsave(&s->lock, flags);
-	j = rdmixer(s, DSP_MIX_OUTMIXIDX);
-	spin_unlock_irqrestore(&s->lock, flags);
-	for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-		if (j & mixtable[i].play)
-			k |= 1 << i;
-	return k;
-}
-
-static unsigned mixer_recmask(struct cm_state *s)
-{
-	unsigned long flags;
-	int i, j, k;
-
-	spin_lock_irqsave(&s->lock, flags);
-	j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
-	spin_unlock_irqrestore(&s->lock, flags);
-	for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-		if (j & mixtable[i].rec)
-			k |= 1 << i;
-	return k;
-}
-
-static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
-{
-	unsigned long flags;
-	int i, val, j;
-	unsigned char l, r, rl, rr;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_STATE(s);
-        if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		memset(&info, 0, sizeof(info));
-		strlcpy(info.id, "cmpci", sizeof(info.id));
-		strlcpy(info.name, "C-Media PCI", sizeof(info.name));
-		info.modify_counter = s->mix.modcnt;
-		if (copy_to_user(argp, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == SOUND_OLD_MIXER_INFO) {
-		_old_mixer_info info;
-		memset(&info, 0, sizeof(info));
-		strlcpy(info.id, "cmpci", sizeof(info.id));
-		strlcpy(info.name, "C-Media cmpci", sizeof(info.name));
-		if (copy_to_user(argp, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, p);
-	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-			val = mixer_recmask(s);
-			return put_user(val, p);
-
-                case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-			val = mixer_outmask(s);
-			return put_user(val, p);
-
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].type)
-					val |= 1 << i;
-			return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].rec)
-					val |= 1 << i;
-			return put_user(val, p);
-
-                case SOUND_MIXER_OUTMASK: /* Arg contains a bit for each supported recording source */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].play)
-					val |= 1 << i;
-			return put_user(val, p);
-
-                 case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
-					val |= 1 << i;
-			return put_user(val, p);
-
-                case SOUND_MIXER_CAPS:
-			return put_user(0, p);
-
-		default:
-			i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                                return -EINVAL;
-			if (!volidx[i])
-				return -EINVAL;
-			return put_user(s->mix.vol[volidx[i]-1], p);
-		}
-	}
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
-		return -EINVAL;
-	s->mix.modcnt++;
-	switch (_IOC_NR(cmd)) {
-	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-		if (get_user(val, p))
-			return -EFAULT;
-		i = hweight32(val);
-		for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-			if (!(val & (1 << i)))
-				continue;
-			if (!mixtable[i].rec) {
-				val &= ~(1 << i);
-				continue;
-			}
-			j |= mixtable[i].rec;
-		}
-		spin_lock_irqsave(&s->lock, flags);
-		wrmixer(s, DSP_MIX_ADCMIXIDX_L, j);
-		wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | (j>>1) | (j & 0x80));
-		spin_unlock_irqrestore(&s->lock, flags);
-		return 0;
-
-	case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-		if (get_user(val, p))
-			return -EFAULT;
-		for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-			if (!(val & (1 << i)))
-				continue;
-			if (!mixtable[i].play) {
-				val &= ~(1 << i);
-				continue;
-			}
-			j |= mixtable[i].play;
-		}
-		spin_lock_irqsave(&s->lock, flags);
-		wrmixer(s, DSP_MIX_OUTMIXIDX, j);
-		spin_unlock_irqrestore(&s->lock, flags);
-		return 0;
-
-	default:
-		i = _IOC_NR(cmd);
-		if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-			return -EINVAL;
-		if (get_user(val, p))
-			return -EFAULT;
-		l = val & 0xff;
-		r = (val >> 8) & 0xff;
-		if (l > 100)
-			l = 100;
-		if (r > 100)
-			r = 100;
-		spin_lock_irqsave(&s->lock, flags);
-		switch (mixtable[i].type) {
-		case MT_4:
-			if (l >= 10)
-				l -= 10;
-			if (r >= 10)
-				r -= 10;
-			frobindir(s, mixtable[i].left, 0xf0, l / 6);
-			frobindir(s, mixtable[i].right, 0xf0, l / 6);
-			break;
-
-		case MT_4MUTEMONO:
-			rl = (l < 4 ? 0 : (l - 5) / 3) & 31;
-			rr = (rl >> 2) & 7;
-			wrmixer(s, mixtable[i].left, rl<<3);
-			if (i == SOUND_MIXER_MIC)
-				maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
-			break;
-
-		case MT_5MUTEMONO:
-			rl = l < 4 ? 0 : (l - 5) / 3;
- 			wrmixer(s, mixtable[i].left, rl<<3);
-			l = rdmixer(s, DSP_MIX_OUTMIXIDX) & ~mixtable[i].play;
-			r = rl ? mixtable[i].play : 0;
-			wrmixer(s, DSP_MIX_OUTMIXIDX, l | r);
-			/* for recording */
-			if (i == SOUND_MIXER_MIC) {
-				if (s->chip_version >= 37) {
-					rr = rl >> 1;
-					maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, (rr&0x07)<<1);
-					frobindir(s, DSP_MIX_EXTENSION, ~0x01, rr>>3);
-				} else {
-					rr = rl >> 2;
-					maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
-				}
-			}
-			break;
-
-		case MT_5MUTE:
-			rl = l < 4 ? 0 : (l - 5) / 3;
-			rr = r < 4 ? 0 : (r - 5) / 3;
- 			wrmixer(s, mixtable[i].left, rl<<3);
-			wrmixer(s, mixtable[i].right, rr<<3);
-			l = rdmixer(s, DSP_MIX_OUTMIXIDX);
-			l &= ~mixtable[i].play;
-			r = (rl|rr) ? mixtable[i].play : 0;
-			wrmixer(s, DSP_MIX_OUTMIXIDX, l | r);
-			break;
-
-		case MT_6MUTE:
-			if (l < 6)
-				rl = 0x00;
-			else
-				rl = l * 2 / 3;
-			if (r < 6)
-				rr = 0x00;
-			else
-				rr = r * 2 / 3;
-			wrmixer(s, mixtable[i].left, rl);
-			wrmixer(s, mixtable[i].right, rr);
-			break;
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-
-		if (!volidx[i])
-			return -EINVAL;
-		s->mix.vol[volidx[i]-1] = val;
-		return put_user(s->mix.vol[volidx[i]-1], p);
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static int cm_open_mixdev(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	struct list_head *list;
-	struct cm_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct cm_state, devs);
-		if (s->dev_mixer == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	return nonseekable_open(inode, file);
-}
-
-static int cm_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct cm_state *s = (struct cm_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	return 0;
-}
-
-static int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	return mixer_ioctl((struct cm_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations cm_mixer_fops = {
-	.owner	 = THIS_MODULE,
-	.llseek	 = no_llseek,
-	.ioctl	 = cm_ioctl_mixdev,
-	.open	 = cm_open_mixdev,
-	.release = cm_release_mixdev,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct cm_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count, tmo;
-
-	if (s->dma_dac.mapped || !s->dma_dac.ready)
-		return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-        	__set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-		tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
-		tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
-		if (!schedule_timeout(tmo + 1))
-			DBG(printk(KERN_DEBUG "cmpci: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t cm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct cm_state *s = (struct cm_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-
-        add_wait_queue(&s->dma_adc.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		swptr = s->dma_adc.swptr;
-		cnt = s->dma_adc.dmasize-swptr;
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_adc.enabled)
-				start_adc(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto out;
-			}
-			if (!schedule_timeout(HZ)) {
-				printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
-				       s->dma_adc.hwptr, s->dma_adc.swptr);
-				spin_lock_irqsave(&s->lock, flags);
-				stop_adc_unlocked(s);
-				set_dmaadc(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples);
-				/* program sample counts */
-				set_countadc(s, s->dma_adc.fragsamples);
-				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				goto out;
-			}
-			continue;
-		}
-		if (s->status & DO_BIGENDIAN_R) {
-			int	i, err;
-			unsigned char *src;
-			char __user *dst = buffer;
-			unsigned char data[2];
-
-			src = (unsigned char *) (s->dma_adc.rawbuf + swptr);
-			// copy left/right sample at one time
-			for (i = 0; i < cnt / 2; i++) {
-				data[0] = src[1];
-				data[1] = src[0];
-				if ((err = __put_user(data[0], dst++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __put_user(data[1], dst++))) {
-					ret = err;
-					goto out;
-				}
-				src += 2;
-			}
-		} else if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			goto out;
-		}
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_adc.enabled)
-			start_adc_unlocked(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	}
-out:
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-static ssize_t cm_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct cm_state *s = (struct cm_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_dac.mapped)
-		return -ENXIO;
-	if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	if (s->status & DO_DUAL_DAC) {
-		if (s->dma_adc.mapped)
-			return -ENXIO;
-		if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-			return ret;
-	}
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-
-        add_wait_queue(&s->dma_dac.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac.count < 0) {
-			s->dma_dac.count = 0;
-			s->dma_dac.swptr = s->dma_dac.hwptr;
-		}
-		if (s->status & DO_DUAL_DAC) {
-			s->dma_adc.swptr = s->dma_dac.swptr;
-			s->dma_adc.count = s->dma_dac.count;
-			s->dma_adc.endcleared = s->dma_dac.endcleared;
-		}
-		swptr = s->dma_dac.swptr;
-		cnt = s->dma_dac.dmasize-swptr;
-		if (s->status & DO_AC3_SW) {
-			if (s->dma_dac.count + 2 * cnt > s->dma_dac.dmasize)
-				cnt = (s->dma_dac.dmasize - s->dma_dac.count) / 2;
-		} else {
-			if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-				cnt = s->dma_dac.dmasize - s->dma_dac.count;
-		}
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if ((s->status & DO_DUAL_DAC) && (cnt > count / 2))
-		    cnt = count / 2;
-		if (cnt <= 0) {
-			if (s->dma_dac.enabled)
-				start_dac(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto out;
-			}
-			if (!schedule_timeout(HZ)) {
-				printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
-				       s->dma_dac.hwptr, s->dma_dac.swptr);
-				spin_lock_irqsave(&s->lock, flags);
-				stop_dac_unlocked(s);
-				set_dmadac(s, s->dma_dac.dmaaddr, s->dma_dac.dmasamples);
-				/* program sample counts */
-				set_countdac(s, s->dma_dac.fragsamples);
-				s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-				if (s->status & DO_DUAL_DAC)  {
-					set_dmadac1(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples);
-					s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-				}
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				goto out;
-			}
-			continue;
-		}
-		if (s->status & DO_AC3_SW) {
-			int err;
-
-			// clip exceeded data, caught by 033 and 037
-			if (swptr + 2 * cnt > s->dma_dac.dmasize)
-				cnt = (s->dma_dac.dmasize - swptr) / 2;
-			if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt))) {
-				ret = err;
-				goto out;
-			}
-			swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
-		} else if ((s->status & DO_DUAL_DAC) && (s->status & DO_BIGENDIAN_W)) {
-			int	i, err;
-			const char __user *src = buffer;
-			unsigned char *dst0, *dst1;
-			unsigned char data[8];
-
-			dst0 = (unsigned char *) (s->dma_dac.rawbuf + swptr);
-			dst1 = (unsigned char *) (s->dma_adc.rawbuf + swptr);
-			// copy left/right sample at one time
-			for (i = 0; i < cnt / 4; i++) {
-				if ((err = __get_user(data[0], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[1], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[2], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[3], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[4], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[5], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[6], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[7], src++))) {
-					ret = err;
-					goto out;
-				}
-				dst0[0] = data[1];
-				dst0[1] = data[0];
-				dst0[2] = data[3];
-				dst0[3] = data[2];
-				dst1[0] = data[5];
-				dst1[1] = data[4];
-				dst1[2] = data[7];
-				dst1[3] = data[6];
-				dst0 += 4;
-				dst1 += 4;
-			}
-			swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		} else if (s->status & DO_DUAL_DAC) {
-			int	i, err;
-			unsigned long __user *src = (unsigned long __user *) buffer;
-			unsigned long *dst0, *dst1;
-
-			dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr);
-			dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
-			// copy left/right sample at one time
-			for (i = 0; i < cnt / 4; i++) {
-				if ((err = __get_user(*dst0++, src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(*dst1++, src++))) {
-					ret = err;
-					goto out;
-				}
-			}
-			swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		} else if (s->status & DO_BIGENDIAN_W) {
-			int	i, err;
-			const char __user *src = buffer;
-			unsigned char *dst;
-			unsigned char data[2];
-
-			dst = (unsigned char *) (s->dma_dac.rawbuf + swptr);
-			// swap hi/lo bytes for each sample
-			for (i = 0; i < cnt / 2; i++) {
-				if ((err = __get_user(data[0], src++))) {
-					ret = err;
-					goto out;
-				}
-				if ((err = __get_user(data[1], src++))) {
-					ret = err;
-					goto out;
-				}
-				dst[0] = data[1];
-				dst[1] = data[0];
-				dst += 2;
-			}
-			swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		} else {
-			if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-				if (!ret)
-					ret = -EFAULT;
-				goto out;
-			}
-			swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		}
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac.swptr = swptr;
-		s->dma_dac.count += cnt;
-		if (s->status & DO_AC3_SW)
-			s->dma_dac.count += cnt;
-		s->dma_dac.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->status & DO_DUAL_DAC) {
-			count -= cnt;
-			buffer += cnt;
-			ret += cnt;
-		}
-		if (s->dma_dac.enabled)
-			start_dac(s);
-	}
-out:
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-static unsigned int cm_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct cm_state *s = (struct cm_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready && prog_dmabuf(s, 0))
-			return 0;
-		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready && prog_dmabuf(s, 1))
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	cm_update_ptr(s);
-	if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int cm_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct cm_state *s = (struct cm_state *)file->private_data;
-	struct dmabuf *db;
-	int ret = -EINVAL;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf(s, 0)) != 0)
-			goto out;
-		db = &s->dma_dac;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf(s, 1)) != 0)
-			goto out;
-		db = &s->dma_adc;
-	} else
-		goto out;
-	ret = -EINVAL;
-	if (vma->vm_pgoff != 0)
-		goto out;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder))
-		goto out;
-	ret = -EINVAL;
-	if (remap_pfn_range(vma, vma->vm_start,
-				virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-				size, vma->vm_page_prot))
-		goto out;
-	db->mapped = 1;
-	ret = 0;
-out:
-	unlock_kernel();
-	return ret;
-}
-
-#define SNDCTL_SPDIF_COPYRIGHT	_SIOW('S',  0, int)       // set/reset S/PDIF copy protection
-#define SNDCTL_SPDIF_LOOP	_SIOW('S',  1, int)       // set/reset S/PDIF loop
-#define SNDCTL_SPDIF_MONITOR	_SIOW('S',  2, int)       // set S/PDIF monitor
-#define SNDCTL_SPDIF_LEVEL	_SIOW('S',  3, int)       // set/reset S/PDIF out level
-#define SNDCTL_SPDIF_INV	_SIOW('S',  4, int)       // set/reset S/PDIF in inverse
-#define SNDCTL_SPDIF_SEL2	_SIOW('S',  5, int)       // set S/PDIF in #2
-#define SNDCTL_SPDIF_VALID	_SIOW('S',  6, int)       // set S/PDIF valid
-#define SNDCTL_SPDIFOUT		_SIOW('S',  7, int)       // set S/PDIF out
-#define SNDCTL_SPDIFIN		_SIOW('S',  8, int)       // set S/PDIF out
-
-static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct cm_state *s = (struct cm_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int val, mapped, ret;
-	unsigned char fmtm, fmtd;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-		return 0;
-
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, p);
-
-        case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq(s->irq);
-			s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-			if (s->status & DO_DUAL_DAC)
-				s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->irq);
-			s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			if (file->f_mode & FMODE_READ) {
-			 	spin_lock_irqsave(&s->lock, flags);
-				stop_adc_unlocked(s);
-				s->dma_adc.ready = 0;
-				set_adc_rate_unlocked(s, val);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (s->status & DO_DUAL_DAC)
-					s->dma_adc.ready = 0;
-				set_dac_rate(s, val);
-			}
-		}
-		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SNDCTL_DSP_STEREO:
-		if (get_user(val, p))
-			return -EFAULT;
-		fmtd = 0;
-		fmtm = ~0;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ready = 0;
-			if (val)
-				fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-			else
-				fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.ready = 0;
-			if (val)
-				fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-			else
-				fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
-			if (s->status & DO_DUAL_DAC) {
-				s->dma_adc.ready = 0;
-				if (val)
-					fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-				else
-					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-			}
-		}
-		set_fmt(s, fmtm, fmtd);
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			fmtd = 0;
-			fmtm = ~0;
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val >= 2)
-					fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-				else
-					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val >= 2)
-					fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-				else
-					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
-				if (s->status & DO_DUAL_DAC) {
-					s->dma_adc.ready = 0;
-					if (val >= 2)
-						fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-					else
-						fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-				}
-			}
-			set_fmt(s, fmtm, fmtd);
-			if ((s->capability & CAN_MULTI_CH)
-			     && (file->f_mode & FMODE_WRITE)) {
-				val = set_dac_channels(s, val);
-				return put_user(val, p);
-			}
-		}
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT)
-					   : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
-
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_BE|AFMT_S16_LE|AFMT_U8|
-			((s->capability & CAN_AC3) ? AFMT_AC3 : 0), p);
-
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			fmtd = 0;
-			fmtm = ~0;
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val == AFMT_S16_BE || val == AFMT_S16_LE)
-					fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-				else
-					fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT);
-				if (val == AFMT_S16_BE)
-					s->status |= DO_BIGENDIAN_R;
-				else
-					s->status &= ~DO_BIGENDIAN_R;
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val == AFMT_S16_BE || val == AFMT_S16_LE || val == AFMT_AC3)
-					fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-				else
-					fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);
-				if (val == AFMT_AC3) {
-					fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-					set_ac3(s, 48000);
-				} else
-					set_ac3(s, 0);
-				if (s->status & DO_DUAL_DAC) {
-					s->dma_adc.ready = 0;
-					if (val == AFMT_S16_BE || val == AFMT_S16_LE)
-						fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-					else
-						fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-				}
-				if (val == AFMT_S16_BE)
-					s->status |= DO_BIGENDIAN_W;
-				else
-					s->status &= ~DO_BIGENDIAN_W;
-			}
-			set_fmt(s, fmtm, fmtd);
-		}
-		if (s->status & DO_AC3) return put_user(AFMT_AC3, p);
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
-					   : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? val : AFMT_U8, p);
-
-	case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if (s->status & DO_DUAL_DAC) {
-			if (file->f_mode & FMODE_WRITE &&
-			 (s->enable & ENDAC) &&
-			 (s->enable & ENADC))
-				val |= PCM_ENABLE_OUTPUT;
-			return put_user(val, p);
-		}
-		if (file->f_mode & FMODE_READ && s->enable & ENADC)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && s->enable & ENDAC)
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, p);
-
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-					return ret;
-				s->dma_adc.enabled = 1;
-				start_adc(s);
-			} else {
-				s->dma_adc.enabled = 0;
-				stop_adc(s);
-			}
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-					return ret;
-				if (s->status & DO_DUAL_DAC) {
-					if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-						return ret;
-				}
-				s->dma_dac.enabled = 1;
-				start_dac(s);
-			} else {
-				s->dma_dac.enabled = 0;
-				stop_dac(s);
-			}
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!(s->enable & ENDAC) && (val = prog_dmabuf(s, 0)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cm_update_ptr(s);
-		abinfo.fragsize = s->dma_dac.fragsize;
-                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!(s->enable & ENADC) && (val = prog_dmabuf(s, 1)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cm_update_ptr(s);
-		abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		cm_update_ptr(s);
-                val = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return put_user(val, p);
-
-        case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		cm_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user(argp, &cinfo, sizeof(cinfo))  ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		cm_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-                cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= s->dma_dac.fragsize-1;
-		if (s->status & DO_DUAL_DAC) {
-			if (s->dma_adc.mapped)
-				s->dma_adc.count &= s->dma_adc.fragsize-1;
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf(s, 0)))
-				return val;
-			if (s->status & DO_DUAL_DAC) {
-				if ((val = prog_dmabuf(s, 1)))
-					return val;
-				return put_user(2 * s->dma_dac.fragsize, p);
-			}
-			return put_user(s->dma_dac.fragsize, p);
-		}
-		if ((val = prog_dmabuf(s, 1)))
-			return val;
-		return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			s->dma_dac.ossfragshift = val & 0xffff;
-			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac.ossfragshift < 4)
-				s->dma_dac.ossfragshift = 4;
-			if (s->dma_dac.ossfragshift > 15)
-				s->dma_dac.ossfragshift = 15;
-			if (s->dma_dac.ossmaxfrags < 4)
-				s->dma_dac.ossmaxfrags = 4;
-			if (s->status & DO_DUAL_DAC) {
-				s->dma_adc.ossfragshift = s->dma_dac.ossfragshift;
-				s->dma_adc.ossmaxfrags = s->dma_dac.ossmaxfrags;
-			}
-		}
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-			return -EINVAL;
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE) {
-			s->dma_dac.subdivision = val;
-			if (s->status & DO_DUAL_DAC)
-				s->dma_adc.subdivision = val;
-		}
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_READ_FILTER:
-		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-	case SNDCTL_DSP_GETCHANNELMASK:
-		return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, p);
-
-	case SNDCTL_DSP_BIND_CHANNEL:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val == DSP_BIND_QUERY) {
-			val = DSP_BIND_FRONT;
-			if (s->status & DO_SPDIF_OUT)
-				val |= DSP_BIND_SPDIF;
-			else {
-				if (s->curr_channels == 4)
-					val |= DSP_BIND_SURR;
-				if (s->curr_channels > 4)
-					val |= DSP_BIND_CENTER_LFE;
-			}
-		} else {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val & DSP_BIND_SPDIF) {
-					set_spdifin(s, s->rateadc);
-					if (!(s->status & DO_SPDIF_OUT))
-						val &= ~DSP_BIND_SPDIF;
-				}
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val & DSP_BIND_SPDIF) {
-					set_spdifout(s, s->ratedac);
-					set_dac_channels(s, s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1);
-					if (!(s->status & DO_SPDIF_OUT))
-						val &= ~DSP_BIND_SPDIF;
-				} else {
-					int channels;
-					int mask;
-
-					mask = val & (DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE);
-					switch (mask) {
-					    case DSP_BIND_FRONT:
-						channels = 2;
-						break;
-					    case DSP_BIND_FRONT|DSP_BIND_SURR:
-						channels = 4;
-						break;
-					    case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE:
-						channels = 6;
-						break;
-					    default:
-						channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
-						break;
-					}
-					set_dac_channels(s, channels);
-				}
-			}
-		}
-		return put_user(val, p);
-
-	case SOUND_PCM_WRITE_FILTER:
-	case SNDCTL_DSP_MAPINBUF:
-	case SNDCTL_DSP_MAPOUTBUF:
-        case SNDCTL_DSP_SETSYNCRO:
-                return -EINVAL;
-	case SNDCTL_SPDIF_COPYRIGHT:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdif_copyright(s, val);
-                return 0;
-	case SNDCTL_SPDIF_LOOP:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdif_loop(s, val);
-                return 0;
-	case SNDCTL_SPDIF_MONITOR:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdif_monitor(s, val);
-                return 0;
-	case SNDCTL_SPDIF_LEVEL:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdifout_level(s, val);
-                return 0;
-	case SNDCTL_SPDIF_INV:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdifin_inverse(s, val);
-                return 0;
-	case SNDCTL_SPDIF_SEL2:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdifin_channel2(s, val);
-                return 0;
-	case SNDCTL_SPDIF_VALID:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdifin_valid(s, val);
-                return 0;
-	case SNDCTL_SPDIFOUT:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdifout(s, val ? s->ratedac : 0);
-                return 0;
-	case SNDCTL_SPDIFIN:
-		if (get_user(val, p))
-			return -EFAULT;
-		set_spdifin(s, val ? s->rateadc : 0);
-                return 0;
-	}
-	return mixer_ioctl(s, cmd, arg);
-}
-
-static int cm_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned char fmtm = ~0, fmts = 0;
-	struct list_head *list;
-	struct cm_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct cm_state, devs);
-		if (!((s->dev_audio ^ minor) & ~0xf))
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & file->f_mode) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->status &= ~DO_BIGENDIAN_R;
-		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-		s->dma_adc.enabled = 1;
-		set_adc_rate(s, 8000);
-		// spdif-in is turnned off by default
-		set_spdifin(s, 0);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->status &= ~DO_BIGENDIAN_W;
-		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-		s->dma_dac.enabled = 1;
-		set_dac_rate(s, 8000);
-		// clear previous multichannel, spdif, ac3 state
-		set_spdifout(s, 0);
-		set_ac3(s, 0);
-		set_dac_channels(s, 1);
-	}
-	set_fmt(s, fmtm, fmts);
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int cm_release(struct inode *inode, struct file *file)
-{
-	struct cm_state *s = (struct cm_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-
-		dealloc_dmabuf(s, &s->dma_dac);
-		if (s->status & DO_DUAL_DAC)
-			dealloc_dmabuf(s, &s->dma_adc);
-
-		if (s->status & DO_MULTI_CH)
-			set_dac_channels(s, 1);
-		if (s->status & DO_AC3)
-			set_ac3(s, 0);
-		if (s->status & DO_SPDIF_OUT)
-			set_spdifout(s, 0);
-		/* enable SPDIF loop */
-		set_spdif_loop(s, spdif_loop);
-		s->status &= ~DO_BIGENDIAN_W;
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-		s->status &= ~DO_BIGENDIAN_R;
-	}
-	s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-	mutex_unlock(&s->open_mutex);
-	wake_up(&s->open_wait);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations cm_audio_fops = {
-	.owner	 = THIS_MODULE,
-	.llseek	 = no_llseek,
-	.read	 = cm_read,
-	.write	 = cm_write,
-	.poll	 = cm_poll,
-	.ioctl	 = cm_ioctl,
-	.mmap	 = cm_mmap,
-	.open	 = cm_open,
-	.release = cm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-	int mixch;
-	int vol;
-} initvol[] __devinitdata = {
-	{ SOUND_MIXER_WRITE_CD, 0x4f4f },
-	{ SOUND_MIXER_WRITE_LINE, 0x4f4f },
-	{ SOUND_MIXER_WRITE_MIC, 0x4f4f },
-	{ SOUND_MIXER_WRITE_SYNTH, 0x4f4f },
-	{ SOUND_MIXER_WRITE_VOLUME, 0x4f4f },
-	{ SOUND_MIXER_WRITE_PCM, 0x4f4f }
-};
-
-/* check chip version and capability */
-static int query_chip(struct cm_state *s)
-{
-	int ChipVersion = -1;
-	unsigned char RegValue;
-
-	// check reg 0Ch, bit 24-31
-	RegValue = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 3);
-	if (RegValue == 0) {
-	    // check reg 08h, bit 24-28
-	    RegValue = inb(s->iobase + CODEC_CMI_CHFORMAT + 3);
-	    RegValue &= 0x1f;
-	    if (RegValue == 0) {
-		ChipVersion = 33;
-		s->max_channels = 4;
-		s->capability |= CAN_AC3_SW;
-		s->capability |= CAN_DUAL_DAC;
-	    } else {
-		ChipVersion = 37;
-		s->max_channels = 4;
-		s->capability |= CAN_AC3_HW;
-		s->capability |= CAN_DUAL_DAC;
-	    }
-	} else {
-	    // check reg 0Ch, bit 26
-	    if (RegValue & (1 << (26-24))) {
-		ChipVersion = 39;
-	    	if (RegValue & (1 << (24-24)))
-		    s->max_channels = 6;
-	    	else
-		    s->max_channels = 4;
-		s->capability |= CAN_AC3_HW;
-		s->capability |= CAN_DUAL_DAC;
-		s->capability |= CAN_MULTI_CH_HW;
-		s->capability |= CAN_LINE_AS_BASS;
-		s->capability |= CAN_MIC_AS_BASS;
-	    } else {
-		ChipVersion = 55; // 4 or 6 channels
-		s->max_channels = 6;
-		s->capability |= CAN_AC3_HW;
-		s->capability |= CAN_DUAL_DAC;
-		s->capability |= CAN_MULTI_CH_HW;
-		s->capability |= CAN_LINE_AS_BASS;
-		s->capability |= CAN_MIC_AS_BASS;
-	    }
-	}
-	s->capability |= CAN_LINE_AS_REAR;
-	return ChipVersion;
-}
-
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-static int __devinit cm_create_gameport(struct cm_state *s, int io_port)
-{
-	struct gameport *gp;
-
-	if (!request_region(io_port, CM_EXTENT_GAME, "cmpci GAME")) {
-		printk(KERN_ERR "cmpci: gameport io ports 0x%#x in use\n", io_port);
-		return -EBUSY;
-	}
-
-	if (!(s->gameport = gp = gameport_allocate_port())) {
-		printk(KERN_ERR "cmpci: can not allocate memory for gameport\n");
-		release_region(io_port, CM_EXTENT_GAME);
-		return -ENOMEM;
-	}
-
-	gameport_set_name(gp, "C-Media GP");
-	gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
-	gp->dev.parent = &s->dev->dev;
-	gp->io = io_port;
-
-	/* enable joystick */
-	maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x02);
-
-	gameport_register_port(gp);
-
-	return 0;
-}
-
-static void __devexit cm_free_gameport(struct cm_state *s)
-{
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-
-		gameport_unregister_port(s->gameport);
-		s->gameport = NULL;
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0);
-		release_region(gpio, CM_EXTENT_GAME);
-	}
-}
-#else
-static inline int cm_create_gameport(struct cm_state *s, int io_port) { return -ENOSYS; }
-static inline void cm_free_gameport(struct cm_state *s) { }
-#endif
-
-#define	echo_option(x)\
-if (x) strcat(options, "" #x " ")
-
-static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-	struct cm_state *s;
-	mm_segment_t fs;
-	int i, val, ret;
-	unsigned char reg_mask;
-	int timeout;
-	struct resource *ports;
-	struct {
-		unsigned short	deviceid;
-		char		*devicename;
-	} devicetable[] = {
-		{ PCI_DEVICE_ID_CMEDIA_CM8338A, "CM8338A" },
-		{ PCI_DEVICE_ID_CMEDIA_CM8338B, "CM8338B" },
-		{ PCI_DEVICE_ID_CMEDIA_CM8738,  "CM8738" },
-		{ PCI_DEVICE_ID_CMEDIA_CM8738B, "CM8738B" },
-	};
-	char	*devicename = "unknown";
-	char	options[256];
-
-	if ((ret = pci_enable_device(pcidev)))
-		return ret;
-	if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO))
-		return -ENODEV;
-	if (pcidev->irq == 0)
-		return -ENODEV;
-	i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-	if (i) {
-		printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n");
-		return i;
-	}
-	s = kmalloc(sizeof(*s), GFP_KERNEL);
-	if (!s) {
-		printk(KERN_WARNING "cmpci: out of memory\n");
-		return -ENOMEM;
-	}
-	/* search device name */
-	for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++) {
-		if (devicetable[i].deviceid == pcidev->device) {
-			devicename = devicetable[i].devicename;
-			break;
-		}
-	}
-	memset(s, 0, sizeof(struct cm_state));
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac.wait);
-	init_waitqueue_head(&s->open_wait);
-	mutex_init(&s->open_mutex);
-	spin_lock_init(&s->lock);
-	s->magic = CM_MAGIC;
-	s->dev = pcidev;
-	s->iobase = pci_resource_start(pcidev, 0);
-	s->iosynth = fmio;
-	s->iomidi = mpuio;
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-	s->midi_devc = 0;
-#endif
-	s->status = 0;
-	if (s->iobase == 0)
-		return -ENODEV;
-	s->irq = pcidev->irq;
-
-	if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
-		printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
-		ret = -EBUSY;
-		goto err_region5;
-	}
-	/* dump parameters */
-	strcpy(options, "cmpci: ");
-	echo_option(joystick);
-	echo_option(spdif_inverse);
-	echo_option(spdif_loop);
-	echo_option(spdif_out);
-	echo_option(use_line_as_rear);
-	echo_option(use_line_as_bass);
-	echo_option(use_mic_as_bass);
-	echo_option(mic_boost);
-	echo_option(hw_copy);
-	printk(KERN_INFO "%s\n", options);
-
-	/* initialize codec registers */
-	outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
-	outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
-	/* reset mixer */
-	wrmixer(s, DSP_MIX_DATARESETIDX, 0);
-
-	/* request irq */
-	if ((ret = request_irq(s->irq, cm_interrupt, IRQF_SHARED, "cmpci", s))) {
-		printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
-		goto err_irq;
-	}
-	printk(KERN_INFO "cmpci: found %s adapter at io %#x irq %u\n",
-	       devicename, s->iobase, s->irq);
-	/* register devices */
-	if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0) {
-		ret = s->dev_audio;
-		goto err_dev1;
-	}
-	if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0) {
-		ret = s->dev_mixer;
-		goto err_dev2;
-	}
-	pci_set_master(pcidev);	/* enable bus mastering */
-	/* initialize the chips */
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	/* set mixer output */
-	frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, 0x1f);
-	/* set mixer input */
-	val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD|SOUND_MASK_MIC;
-	mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-	for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-		val = initvol[i].vol;
-		mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-	}
-	set_fs(fs);
-	/* use channel 1 for playback, channel 0 for record */
-	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, CHADC0);
-	/* turn off VMIC3 - mic boost */
-	if (mic_boost)
-		maskb(s->iobase + CODEC_CMI_MIXER2, ~1, 0);
-	else
-		maskb(s->iobase + CODEC_CMI_MIXER2, ~0, 1);
-	s->deviceid = pcidev->device;
-
-	if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738
-	 || pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738B) {
-
-		/* chip version and hw capability check */
-		s->chip_version = query_chip(s);
-		printk(KERN_INFO "cmpci: chip version = 0%d\n", s->chip_version);
-
-		/* set SPDIF-in inverse before enable SPDIF loop */
-		set_spdifin_inverse(s, spdif_inverse);
-
-		/* use SPDIF in #1 */
-		set_spdifin_channel2(s, 0);
-	} else {
-		s->chip_version = 0;
-		/* 8338 will fall here */
-		s->max_channels = 4;
-		s->capability |= CAN_DUAL_DAC;
-		s->capability |= CAN_LINE_AS_REAR;
-	}
-	/* enable SPDIF loop */
-	set_spdif_loop(s, spdif_loop);
-
-	// enable 4 speaker mode (analog duplicate)
-	set_hw_copy(s, hw_copy);
-
-	reg_mask = 0;
-#ifdef CONFIG_SOUND_CMPCI_FM
-	/* disable FM */
-	maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-	if (s->iosynth) {
-	    /* don't enable OPL3 if there is one */
-	    if (opl3_detect(s->iosynth, NULL)) {
-	    	s->iosynth = 0;
-	    } else {
-		/* set IO based at 0x388 */
-		switch (s->iosynth) {
-		    case 0x388:
-			reg_mask = 0;
-			break;
-		    case 0x3C8:
-			reg_mask = 0x01;
-			break;
-		    case 0x3E0:
-			reg_mask = 0x02;
-			break;
-		    case 0x3E8:
-			reg_mask = 0x03;
-			break;
-		    default:
-			s->iosynth = 0;
-			break;
-		}
-		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x03, reg_mask);
-		/* enable FM */
-		if (s->iosynth) {
-			maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 8);
-			if (opl3_detect(s->iosynth, NULL))
-				ret = opl3_init(s->iosynth, NULL, THIS_MODULE);
-			else {
-				maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-				s->iosynth = 0;
-			}
-		}
-	    }
-	}
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-	switch (s->iomidi) {
-	    case 0x330:
-		reg_mask = 0;
-		break;
-	    case 0x320:
-		reg_mask = 0x20;
-		break;
-	    case 0x310:
-		reg_mask = 0x40;
-		break;
-	    case 0x300:
-		reg_mask = 0x60;
-		break;
-	    default:
-		s->iomidi = 0;
-		goto skip_mpu;
-	}
-	ports = request_region(s->iomidi, 2, "mpu401");
-	if (!ports)
-		goto skip_mpu;
-	/* disable MPU-401 */
-	maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
-	s->mpu_data.name = "cmpci mpu";
-	s->mpu_data.io_base = s->iomidi;
-	s->mpu_data.irq = -s->irq;	// tell mpu401 to share irq
-	if (probe_mpu401(&s->mpu_data, ports)) {
-		release_region(s->iomidi, 2);
-		s->iomidi = 0;
-		goto skip_mpu;
-	}
-	maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x60, reg_mask);
-	/* enable MPU-401 */
-	maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
-	/* clear all previously received interrupt */
-	for (timeout = 900000; timeout > 0; timeout--) {
-		if ((inb(s->iomidi + 1) && 0x80) == 0)
-			inb(s->iomidi);
-		else
-			break;
-	}
-	if (!probe_mpu401(&s->mpu_data, ports)) {
-		release_region(s->iomidi, 2);
-		s->iomidi = 0;
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
-	} else {
-		attach_mpu401(&s->mpu_data, THIS_MODULE);
-		s->midi_devc = s->mpu_data.slots[1];
-	}
-skip_mpu:
-#endif
-	/* disable joystick port */
-	maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0);
-	if (joystick)
-		cm_create_gameport(s, 0x200);
-
-	/* store it in the driver field */
-	pci_set_drvdata(pcidev, s);
-	/* put it into driver list */
-	list_add_tail(&s->devs, &devs);
-	/* increment devindex */
-	if (devindex < NR_DEVICE-1)
-		devindex++;
-	return 0;
-
-err_dev2:
-	unregister_sound_dsp(s->dev_audio);
-err_dev1:
-	printk(KERN_ERR "cmpci: cannot register misc device\n");
-	free_irq(s->irq, s);
-err_irq:
-	release_region(s->iobase, CM_EXTENT_CODEC);
-err_region5:
-	kfree(s);
-	return ret;
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw");
-MODULE_DESCRIPTION("CM8x38 Audio Driver");
-MODULE_LICENSE("GPL");
-
-static void __devexit cm_remove(struct pci_dev *dev)
-{
-	struct cm_state *s = pci_get_drvdata(dev);
-
-	if (!s)
-		return;
-
-	cm_free_gameport(s);
-
-#ifdef CONFIG_SOUND_CMPCI_FM
-	if (s->iosynth) {
-		/* disable FM */
-		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-	}
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-	if (s->iomidi) {
-		unload_mpu401(&s->mpu_data);
-		/* disable MPU-401 */
-		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
-	}
-#endif
-	set_spdif_loop(s, 0);
-	list_del(&s->devs);
-	outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
-	synchronize_irq(s->irq);
-	outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
-	free_irq(s->irq, s);
-
-	/* reset mixer */
-	wrmixer(s, DSP_MIX_DATARESETIDX, 0);
-
-	release_region(s->iobase, CM_EXTENT_CODEC);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->dev_mixer);
-	kfree(s);
-	pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] __devinitdata = {
-	{ PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- 	{ PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver cm_driver = {
-       .name	 = "cmpci",
-       .id_table = id_table,
-       .probe	 = cm_probe,
-       .remove	 = __devexit_p(cm_remove)
-};
-
-static int __init init_cmpci(void)
-{
-	printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n");
-	return pci_register_driver(&cm_driver);
-}
-
-static void __exit cleanup_cmpci(void)
-{
-	printk(KERN_INFO "cmpci: unloading\n");
-	pci_unregister_driver(&cm_driver);
-}
-
-module_init(init_cmpci);
-module_exit(cleanup_cmpci);
diff --git a/sound/oss/cs4281/Makefile b/sound/oss/cs4281/Makefile
deleted file mode 100644
index 6d527e8..0000000
--- a/sound/oss/cs4281/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# Makefile for Cirrus Logic-Crystal CS4281 
-#
-
-obj-$(CONFIG_SOUND_CS4281) += cs4281.o
-
-cs4281-objs += cs4281m.o
diff --git a/sound/oss/cs4281/cs4281_hwdefs.h b/sound/oss/cs4281/cs4281_hwdefs.h
deleted file mode 100644
index 701d595..0000000
--- a/sound/oss/cs4281/cs4281_hwdefs.h
+++ /dev/null
@@ -1,1234 +0,0 @@
-//****************************************************************************
-//
-// HWDEFS.H - Definitions of the registers and data structures used by the
-//            CS4281
-//
-// Copyright (c) 1999,2000,2001 Crystal Semiconductor Corp.
-//
-//****************************************************************************
-
-#ifndef _H_HWDEFS
-#define _H_HWDEFS
-
-//****************************************************************************
-//
-// The following define the offsets of the registers located in the PCI
-// configuration space of the CS4281 part.
-//
-//****************************************************************************
-#define PCICONFIG_DEVID_VENID                   0x00000000L
-#define PCICONFIG_STATUS_COMMAND                0x00000004L
-#define PCICONFIG_CLASS_REVISION                0x00000008L
-#define PCICONFIG_LATENCY_TIMER                 0x0000000CL
-#define PCICONFIG_BA0                           0x00000010L
-#define PCICONFIG_BA1                           0x00000014L
-#define PCICONFIG_SUBSYSID_SUBSYSVENID          0x0000002CL
-#define PCICONFIG_INTERRUPT                     0x0000003CL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers accessed via base address
-// register zero on the CS4281 part.
-//
-//****************************************************************************
-#define BA0_HISR                                0x00000000L
-#define BA0_HICR                                0x00000008L
-#define BA0_HIMR                                0x0000000CL
-#define BA0_IIER                                0x00000010L
-#define BA0_HDSR0                               0x000000F0L
-#define BA0_HDSR1                               0x000000F4L
-#define BA0_HDSR2                               0x000000F8L
-#define BA0_HDSR3                               0x000000FCL
-#define BA0_DCA0                                0x00000110L
-#define BA0_DCC0                                0x00000114L
-#define BA0_DBA0                                0x00000118L
-#define BA0_DBC0                                0x0000011CL
-#define BA0_DCA1                                0x00000120L
-#define BA0_DCC1                                0x00000124L
-#define BA0_DBA1                                0x00000128L
-#define BA0_DBC1                                0x0000012CL
-#define BA0_DCA2                                0x00000130L
-#define BA0_DCC2                                0x00000134L
-#define BA0_DBA2                                0x00000138L
-#define BA0_DBC2                                0x0000013CL
-#define BA0_DCA3                                0x00000140L
-#define BA0_DCC3                                0x00000144L
-#define BA0_DBA3                                0x00000148L
-#define BA0_DBC3                                0x0000014CL
-#define BA0_DMR0                                0x00000150L
-#define BA0_DCR0                                0x00000154L
-#define BA0_DMR1                                0x00000158L
-#define BA0_DCR1                                0x0000015CL
-#define BA0_DMR2                                0x00000160L
-#define BA0_DCR2                                0x00000164L
-#define BA0_DMR3                                0x00000168L
-#define BA0_DCR3                                0x0000016CL
-#define BA0_DLMR                                0x00000170L
-#define BA0_DLSR                                0x00000174L
-#define BA0_FCR0                                0x00000180L
-#define BA0_FCR1                                0x00000184L
-#define BA0_FCR2                                0x00000188L
-#define BA0_FCR3                                0x0000018CL
-#define BA0_FPDR0                               0x00000190L
-#define BA0_FPDR1                               0x00000194L
-#define BA0_FPDR2                               0x00000198L
-#define BA0_FPDR3                               0x0000019CL
-#define BA0_FCHS                                0x0000020CL
-#define BA0_FSIC0                               0x00000210L
-#define BA0_FSIC1                               0x00000214L
-#define BA0_FSIC2                               0x00000218L
-#define BA0_FSIC3                               0x0000021CL
-#define BA0_PCICFG00                            0x00000300L
-#define BA0_PCICFG04                            0x00000304L
-#define BA0_PCICFG08                            0x00000308L
-#define BA0_PCICFG0C                            0x0000030CL
-#define BA0_PCICFG10                            0x00000310L
-#define BA0_PCICFG14                            0x00000314L
-#define BA0_PCICFG18                            0x00000318L
-#define BA0_PCICFG1C                            0x0000031CL
-#define BA0_PCICFG20                            0x00000320L
-#define BA0_PCICFG24                            0x00000324L
-#define BA0_PCICFG28                            0x00000328L
-#define BA0_PCICFG2C                            0x0000032CL
-#define BA0_PCICFG30                            0x00000330L
-#define BA0_PCICFG34                            0x00000334L
-#define BA0_PCICFG38                            0x00000338L
-#define BA0_PCICFG3C                            0x0000033CL
-#define BA0_PCICFG40                            0x00000340L
-#define BA0_PMCS                                0x00000344L
-#define BA0_CWPR                                0x000003E0L
-#define BA0_EPPMC                               0x000003E4L
-#define BA0_GPIOR                               0x000003E8L
-#define BA0_SPMC                                0x000003ECL
-#define BA0_CFLR                                0x000003F0L
-#define BA0_IISR                                0x000003F4L
-#define BA0_TMS                                 0x000003F8L
-#define BA0_SSVID                               0x000003FCL
-#define BA0_CLKCR1                              0x00000400L
-#define BA0_FRR                                 0x00000410L
-#define BA0_SLT12O                              0x0000041CL
-#define BA0_SERMC                               0x00000420L
-#define BA0_SERC1                               0x00000428L
-#define BA0_SERC2                               0x0000042CL
-#define BA0_SLT12M                              0x0000045CL
-#define BA0_ACCTL                               0x00000460L
-#define BA0_ACSTS                               0x00000464L
-#define BA0_ACOSV                               0x00000468L
-#define BA0_ACCAD                               0x0000046CL
-#define BA0_ACCDA                               0x00000470L
-#define BA0_ACISV                               0x00000474L
-#define BA0_ACSAD                               0x00000478L
-#define BA0_ACSDA                               0x0000047CL
-#define BA0_JSPT                                0x00000480L
-#define BA0_JSCTL                               0x00000484L
-#define BA0_MIDCR                               0x00000490L
-#define BA0_MIDCMD                              0x00000494L
-#define BA0_MIDSR                               0x00000494L
-#define BA0_MIDWP                               0x00000498L
-#define BA0_MIDRP                               0x0000049CL
-#define BA0_AODSD1                              0x000004A8L
-#define BA0_AODSD2                              0x000004ACL
-#define BA0_CFGI                                0x000004B0L
-#define BA0_SLT12M2                             0x000004DCL
-#define BA0_ACSTS2                              0x000004E4L
-#define BA0_ACISV2                              0x000004F4L
-#define BA0_ACSAD2                              0x000004F8L
-#define BA0_ACSDA2                              0x000004FCL
-#define BA0_IOTGP                               0x00000500L
-#define BA0_IOTSB                               0x00000504L
-#define BA0_IOTFM                               0x00000508L
-#define BA0_IOTDMA                              0x0000050CL
-#define BA0_IOTAC0                              0x00000500L
-#define BA0_IOTAC1                              0x00000504L
-#define BA0_IOTAC2                              0x00000508L
-#define BA0_IOTAC3                              0x0000050CL
-#define BA0_IOTPCP                              0x0000052CL
-#define BA0_IOTCC                               0x00000530L
-#define BA0_IOTCR                               0x0000058CL
-#define BA0_PCPRR                               0x00000600L
-#define BA0_PCPGR                               0x00000604L
-#define BA0_PCPCR                               0x00000608L
-#define BA0_PCPCIEN                             0x00000608L
-#define BA0_SBMAR                               0x00000700L
-#define BA0_SBMDR                               0x00000704L
-#define BA0_SBRR                                0x00000708L
-#define BA0_SBRDP                               0x0000070CL
-#define BA0_SBWDP                               0x00000710L
-#define BA0_SBWBS                               0x00000710L
-#define BA0_SBRBS                               0x00000714L
-#define BA0_FMSR                                0x00000730L
-#define BA0_B0AP                                0x00000730L
-#define BA0_FMDP                                0x00000734L
-#define BA0_B1AP                                0x00000738L
-#define BA0_B1DP                                0x0000073CL
-#define BA0_SSPM                                0x00000740L
-#define BA0_DACSR                               0x00000744L
-#define BA0_ADCSR                               0x00000748L
-#define BA0_SSCR                                0x0000074CL
-#define BA0_FMLVC                               0x00000754L
-#define BA0_FMRVC                               0x00000758L
-#define BA0_SRCSA                               0x0000075CL
-#define BA0_PPLVC                               0x00000760L
-#define BA0_PPRVC                               0x00000764L
-#define BA0_PASR                                0x00000768L
-#define BA0_CASR                                0x0000076CL
-
-//****************************************************************************
-//
-// The following define the offsets of the AC97 shadow registers, which appear
-// as a virtual extension to the base address register zero memory range.
-//
-//****************************************************************************
-#define AC97_REG_OFFSET_MASK                    0x0000007EL
-#define AC97_CODEC_NUMBER_MASK                  0x00003000L
-
-#define BA0_AC97_RESET                          0x00001000L
-#define BA0_AC97_MASTER_VOLUME                  0x00001002L
-#define BA0_AC97_HEADPHONE_VOLUME               0x00001004L
-#define BA0_AC97_MASTER_VOLUME_MONO             0x00001006L
-#define BA0_AC97_MASTER_TONE                    0x00001008L
-#define BA0_AC97_PC_BEEP_VOLUME                 0x0000100AL
-#define BA0_AC97_PHONE_VOLUME                   0x0000100CL
-#define BA0_AC97_MIC_VOLUME                     0x0000100EL
-#define BA0_AC97_LINE_IN_VOLUME                 0x00001010L
-#define BA0_AC97_CD_VOLUME                      0x00001012L
-#define BA0_AC97_VIDEO_VOLUME                   0x00001014L
-#define BA0_AC97_AUX_VOLUME                     0x00001016L
-#define BA0_AC97_PCM_OUT_VOLUME                 0x00001018L
-#define BA0_AC97_RECORD_SELECT                  0x0000101AL
-#define BA0_AC97_RECORD_GAIN                    0x0000101CL
-#define BA0_AC97_RECORD_GAIN_MIC                0x0000101EL
-#define BA0_AC97_GENERAL_PURPOSE                0x00001020L
-#define BA0_AC97_3D_CONTROL                     0x00001022L
-#define BA0_AC97_MODEM_RATE                     0x00001024L
-#define BA0_AC97_POWERDOWN                      0x00001026L
-#define BA0_AC97_EXT_AUDIO_ID                   0x00001028L
-#define BA0_AC97_EXT_AUDIO_POWER                0x0000102AL
-#define BA0_AC97_PCM_FRONT_DAC_RATE             0x0000102CL
-#define BA0_AC97_PCM_SURR_DAC_RATE              0x0000102EL
-#define BA0_AC97_PCM_LFE_DAC_RATE               0x00001030L
-#define BA0_AC97_PCM_LR_ADC_RATE                0x00001032L
-#define BA0_AC97_MIC_ADC_RATE                   0x00001034L
-#define BA0_AC97_6CH_VOL_C_LFE                  0x00001036L
-#define BA0_AC97_6CH_VOL_SURROUND               0x00001038L
-#define BA0_AC97_RESERVED_3A                    0x0000103AL
-#define BA0_AC97_EXT_MODEM_ID                   0x0000103CL
-#define BA0_AC97_EXT_MODEM_POWER                0x0000103EL
-#define BA0_AC97_LINE1_CODEC_RATE               0x00001040L
-#define BA0_AC97_LINE2_CODEC_RATE               0x00001042L
-#define BA0_AC97_HANDSET_CODEC_RATE             0x00001044L
-#define BA0_AC97_LINE1_CODEC_LEVEL              0x00001046L
-#define BA0_AC97_LINE2_CODEC_LEVEL              0x00001048L
-#define BA0_AC97_HANDSET_CODEC_LEVEL            0x0000104AL
-#define BA0_AC97_GPIO_PIN_CONFIG                0x0000104CL
-#define BA0_AC97_GPIO_PIN_TYPE                  0x0000104EL
-#define BA0_AC97_GPIO_PIN_STICKY                0x00001050L
-#define BA0_AC97_GPIO_PIN_WAKEUP                0x00001052L
-#define BA0_AC97_GPIO_PIN_STATUS                0x00001054L
-#define BA0_AC97_MISC_MODEM_AFE_STAT            0x00001056L
-#define BA0_AC97_RESERVED_58                    0x00001058L
-#define BA0_AC97_CRYSTAL_REV_N_FAB_ID           0x0000105AL
-#define BA0_AC97_TEST_AND_MISC_CTRL             0x0000105CL
-#define BA0_AC97_AC_MODE                        0x0000105EL
-#define BA0_AC97_MISC_CRYSTAL_CONTROL           0x00001060L
-#define BA0_AC97_LINE1_HYPRID_CTRL              0x00001062L
-#define BA0_AC97_VENDOR_RESERVED_64             0x00001064L
-#define BA0_AC97_VENDOR_RESERVED_66             0x00001066L
-#define BA0_AC97_SPDIF_CONTROL                  0x00001068L
-#define BA0_AC97_VENDOR_RESERVED_6A             0x0000106AL
-#define BA0_AC97_VENDOR_RESERVED_6C             0x0000106CL
-#define BA0_AC97_VENDOR_RESERVED_6E             0x0000106EL
-#define BA0_AC97_VENDOR_RESERVED_70             0x00001070L
-#define BA0_AC97_VENDOR_RESERVED_72             0x00001072L
-#define BA0_AC97_VENDOR_RESERVED_74             0x00001074L
-#define BA0_AC97_CAL_ADDRESS                    0x00001076L
-#define BA0_AC97_CAL_DATA                       0x00001078L
-#define BA0_AC97_VENDOR_RESERVED_7A             0x0000107AL
-#define BA0_AC97_VENDOR_ID1                     0x0000107CL
-#define BA0_AC97_VENDOR_ID2                     0x0000107EL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers and memories accessed via
-// base address register one on the CS4281 part.
-//
-//****************************************************************************
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI device ID/vendor ID
-// register.
-//
-//****************************************************************************
-#define PDV_VENID_MASK                          0x0000FFFFL
-#define PDV_DEVID_MASK                          0xFFFF0000L
-#define PDV_VENID_SHIFT                         0L
-#define PDV_DEVID_SHIFT                         16L
-#define VENID_CIRRUS_LOGIC                      0x1013L
-#define DEVID_CS4281                            0x6005L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI status and command
-// register.
-//
-//****************************************************************************
-#define PSC_IO_SPACE_ENABLE                     0x00000001L
-#define PSC_MEMORY_SPACE_ENABLE                 0x00000002L
-#define PSC_BUS_MASTER_ENABLE                   0x00000004L
-#define PSC_SPECIAL_CYCLES                      0x00000008L
-#define PSC_MWI_ENABLE                          0x00000010L
-#define PSC_VGA_PALETTE_SNOOP                   0x00000020L
-#define PSC_PARITY_RESPONSE                     0x00000040L
-#define PSC_WAIT_CONTROL                        0x00000080L
-#define PSC_SERR_ENABLE                         0x00000100L
-#define PSC_FAST_B2B_ENABLE                     0x00000200L
-#define PSC_UDF_MASK                            0x007F0000L
-#define PSC_FAST_B2B_CAPABLE                    0x00800000L
-#define PSC_PARITY_ERROR_DETECTED               0x01000000L
-#define PSC_DEVSEL_TIMING_MASK                  0x06000000L
-#define PSC_TARGET_ABORT_SIGNALLED              0x08000000L
-#define PSC_RECEIVED_TARGET_ABORT               0x10000000L
-#define PSC_RECEIVED_MASTER_ABORT               0x20000000L
-#define PSC_SIGNALLED_SERR                      0x40000000L
-#define PSC_DETECTED_PARITY_ERROR               0x80000000L
-#define PSC_UDF_SHIFT                           16L
-#define PSC_DEVSEL_TIMING_SHIFT                 25L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI class/revision ID
-// register.
-//
-//****************************************************************************
-#define PCR_REVID_MASK                          0x000000FFL
-#define PCR_INTERFACE_MASK                      0x0000FF00L
-#define PCR_SUBCLASS_MASK                       0x00FF0000L
-#define PCR_CLASS_MASK                          0xFF000000L
-#define PCR_REVID_SHIFT                         0L
-#define PCR_INTERFACE_SHIFT                     8L
-#define PCR_SUBCLASS_SHIFT                      16L
-#define PCR_CLASS_SHIFT                         24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI latency timer register.
-//
-//****************************************************************************
-#define PLT_CACHE_LINE_SIZE_MASK                0x000000FFL
-#define PLT_LATENCY_TIMER_MASK                  0x0000FF00L
-#define PLT_HEADER_TYPE_MASK                    0x00FF0000L
-#define PLT_BIST_MASK                           0xFF000000L
-#define PLT_CACHE_LINE_SIZE_SHIFT               0L
-#define PLT_LATENCY_TIMER_SHIFT                 8L
-#define PLT_HEADER_TYPE_SHIFT                   16L
-#define PLT_BIST_SHIFT                          24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI base address registers.
-//
-//****************************************************************************
-#define PBAR_MEMORY_SPACE_INDICATOR             0x00000001L
-#define PBAR_LOCATION_TYPE_MASK                 0x00000006L
-#define PBAR_NOT_PREFETCHABLE                   0x00000008L
-#define PBAR_ADDRESS_MASK                       0xFFFFFFF0L
-#define PBAR_LOCATION_TYPE_SHIFT                1L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI subsystem ID/subsystem
-// vendor ID register.
-//
-//****************************************************************************
-#define PSS_SUBSYSTEM_VENDOR_ID_MASK            0x0000FFFFL
-#define PSS_SUBSYSTEM_ID_MASK                   0xFFFF0000L
-#define PSS_SUBSYSTEM_VENDOR_ID_SHIFT           0L
-#define PSS_SUBSYSTEM_ID_SHIFT                  16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI interrupt register.
-//
-//****************************************************************************
-#define PI_LINE_MASK                            0x000000FFL
-#define PI_PIN_MASK                             0x0000FF00L
-#define PI_MIN_GRANT_MASK                       0x00FF0000L
-#define PI_MAX_LATENCY_MASK                     0xFF000000L
-#define PI_LINE_SHIFT                           0L
-#define PI_PIN_SHIFT                            8L
-#define PI_MIN_GRANT_SHIFT                      16L
-#define PI_MAX_LATENCY_SHIFT                    24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt status
-// register.
-//
-//****************************************************************************
-#define HISR_HVOLMASK                            0x00000003L
-#define HISR_VDNI                                0x00000001L
-#define HISR_VUPI                                0x00000002L
-#define HISR_GP1I                                0x00000004L
-#define HISR_GP3I                                0x00000008L
-#define HISR_GPSI                                0x00000010L
-#define HISR_GPPI                                0x00000020L
-#define HISR_DMAI                                0x00040000L
-#define HISR_FIFOI                               0x00100000L
-#define HISR_HVOL                                0x00200000L
-#define HISR_MIDI                                0x00400000L
-#define HISR_SBINT                               0x00800000L
-#define HISR_INTENA                              0x80000000L
-#define HISR_DMA_MASK                            0x00000F00L
-#define HISR_FIFO_MASK                           0x0000F000L
-#define HISR_DMA_SHIFT                           8L
-#define HISR_FIFO_SHIFT                          12L
-#define HISR_FIFO0                               0x00001000L
-#define HISR_FIFO1                               0x00002000L
-#define HISR_FIFO2                               0x00004000L
-#define HISR_FIFO3                               0x00008000L
-#define HISR_DMA0                                0x00000100L
-#define HISR_DMA1                                0x00000200L
-#define HISR_DMA2                                0x00000400L
-#define HISR_DMA3                                0x00000800L
-#define HISR_RESERVED                            0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt control
-// register.
-//
-//****************************************************************************
-#define HICR_IEV                                 0x00000001L
-#define HICR_CHGM                                0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Mode Register n
-// (DMRn)
-//
-//****************************************************************************
-#define DMRn_TR_MASK                             0x0000000CL
-#define DMRn_TR_SHIFT                            2L
-#define DMRn_AUTO                                0x00000010L
-#define DMRn_TR_READ                             0x00000008L
-#define DMRn_TR_WRITE                            0x00000004L
-#define DMRn_TYPE_MASK                           0x000000C0L
-#define DMRn_TYPE_SHIFT                          6L
-#define DMRn_SIZE8                               0x00010000L
-#define DMRn_MONO                                0x00020000L
-#define DMRn_BEND                                0x00040000L
-#define DMRn_USIGN                               0x00080000L
-#define DMRn_SIZE20                              0x00100000L
-#define DMRn_SWAPC                               0x00400000L
-#define DMRn_CBC                                 0x01000000L
-#define DMRn_TBC                                 0x02000000L
-#define DMRn_POLL                                0x10000000L
-#define DMRn_DMA                                 0x20000000L
-#define DMRn_FSEL_MASK                           0xC0000000L
-#define DMRn_FSEL_SHIFT                          30L
-#define DMRn_FSEL0                               0x00000000L
-#define DMRn_FSEL1                               0x40000000L
-#define DMRn_FSEL2                               0x80000000L
-#define DMRn_FSEL3                               0xC0000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Command Register n
-// (DCRn)
-//
-//****************************************************************************
-#define DCRn_HTCIE                               0x00020000L
-#define DCRn_TCIE                                0x00010000L
-#define DCRn_MSK                                 0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the FIFO Control 
-// register n.(FCRn)
-//
-//****************************************************************************
-#define FCRn_OF_MASK                            0x0000007FL
-#define FCRn_OF_SHIFT                           0L
-#define FCRn_SZ_MASK                            0x00007F00L
-#define FCRn_SZ_SHIFT                           8L
-#define FCRn_LS_MASK                            0x001F0000L
-#define FCRn_LS_SHIFT                           16L
-#define FCRn_RS_MASK                            0x1F000000L
-#define FCRn_RS_SHIFT                           24L
-#define FCRn_FEN                                0x80000000L
-#define FCRn_PSH                                0x20000000L
-#define FCRn_DACZ                               0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port Power Management
-// control register.(SPMC)
-//
-//****************************************************************************
-#define SPMC_RSTN                               0x00000001L
-#define SPMC_ASYN                               0x00000002L
-#define SPMC_WUP1                               0x00000004L
-#define SPMC_WUP2                               0x00000008L
-#define SPMC_ASDI2E                             0x00000100L
-#define SPMC_ESSPD                              0x00000200L
-#define SPMC_GISPEN                             0x00004000L
-#define SPMC_GIPPEN                             0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Configuration Load register.
-// (CFLR)
-//
-//****************************************************************************
-#define CFLR_CLOCK_SOURCE_MASK                  0x00000003L
-#define CFLR_CLOCK_SOURCE_AC97                  0x00000001L
-
-#define CFLR_CB0_MASK                            0x000000FFL
-#define CFLR_CB1_MASK                            0x0000FF00L
-#define CFLR_CB2_MASK                            0x00FF0000L
-#define CFLR_CB3_MASK                            0xFF000000L
-#define CFLR_CB0_SHIFT                           0L
-#define CFLR_CB1_SHIFT                           8L
-#define CFLR_CB2_SHIFT                           16L
-#define CFLR_CB3_SHIFT                           24L
-
-#define IOTCR_DMA0                              0x00000000L
-#define IOTCR_DMA1                              0x00000400L
-#define IOTCR_DMA2                              0x00000800L
-#define IOTCR_DMA3                              0x00000C00L
-#define IOTCR_CCLS                              0x00000100L
-#define IOTCR_PCPCI                             0x00000200L
-#define IOTCR_DDMA                              0x00000300L
-
-#define SBWBS_WBB                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the SRC Slot Assignment Register
-// (SRCSA)
-//
-//****************************************************************************
-#define SRCSA_PLSS_MASK                         0x0000001FL
-#define SRCSA_PLSS_SHIFT                        0L
-#define SRCSA_PRSS_MASK                         0x00001F00L
-#define SRCSA_PRSS_SHIFT                        8L
-#define SRCSA_CLSS_MASK                         0x001F0000L
-#define SRCSA_CLSS_SHIFT                        16L
-#define SRCSA_CRSS_MASK                         0x1F000000L
-#define SRCSA_CRSS_SHIFT                        24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Power Management
-// register.(SSPM)
-//
-//****************************************************************************
-#define SSPM_FPDN                               0x00000080L
-#define SSPM_MIXEN                              0x00000040L
-#define SSPM_CSRCEN                             0x00000020L
-#define SSPM_PSRCEN                             0x00000010L
-#define SSPM_JSEN                               0x00000008L
-#define SSPM_ACLEN                              0x00000004L
-#define SSPM_FMEN                               0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Control
-// Register. (SSCR)
-//
-//****************************************************************************
-#define SSCR_SB                                 0x00000004L
-#define SSCR_HVC                                0x00000008L
-#define SSCR_LPFIFO                             0x00000040L
-#define SSCR_LPSRC                              0x00000080L
-#define SSCR_XLPSRC                             0x00000100L
-#define SSCR_MVMD                               0x00010000L
-#define SSCR_MVAD                               0x00020000L
-#define SSCR_MVLD                               0x00040000L
-#define SSCR_MVCS                               0x00080000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Clock Control Register 1. 
-// (CLKCR1)
-//
-//****************************************************************************
-#define CLKCR1_DLLSS_MASK                       0x0000000CL
-#define CLKCR1_DLLSS_SHIFT                      2L
-#define CLKCR1_DLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_DLLOS                            0x00000040L
-#define CLKCR1_CKRA                             0x00010000L
-#define CLKCR1_CKRN                             0x00020000L
-#define CLKCR1_DLLRDY                           0x01000000L
-#define CLKCR1_CLKON                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound Blaster Read Buffer
-// Status.(SBRBS)
-//
-//****************************************************************************
-#define SBRBS_RD_MASK                           0x0000007FL
-#define SBRBS_RD_SHIFT                          0L
-#define SBRBS_RBF                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port master control
-// register.(SERMC)
-//
-//****************************************************************************
-#define SERMC_MSPE                              0x00000001L
-#define SERMC_PTC_MASK                          0x0000000EL
-#define SERMC_PTC_SHIFT                         1L
-#define SERMC_PTC_AC97                          0x00000002L
-#define SERMC_PLB                               0x00000010L
-#define SERMC_PXLB                              0x00000020L
-#define SERMC_LOFV                              0x00080000L
-#define SERMC_SLB                               0x00100000L
-#define SERMC_SXLB                              0x00200000L
-#define SERMC_ODSEN1                            0x01000000L
-#define SERMC_ODSEN2                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the General Purpose I/O Register. 
-// (GPIOR)
-//
-//****************************************************************************
-#define GPIOR_VDNS                              0x00000001L
-#define GPIOR_VUPS                              0x00000002L
-#define GPIOR_GP1S                              0x00000004L
-#define GPIOR_GP3S                              0x00000008L
-#define GPIOR_GPSS                              0x00000010L
-#define GPIOR_GPPS                              0x00000020L
-#define GPIOR_GP1D                              0x00000400L
-#define GPIOR_GP3D                              0x00000800L
-#define GPIOR_VDNLT                             0x00010000L
-#define GPIOR_VDNPO                             0x00020000L
-#define GPIOR_VDNST                             0x00040000L
-#define GPIOR_VDNW                              0x00080000L
-#define GPIOR_VUPLT                             0x00100000L
-#define GPIOR_VUPPO                             0x00200000L
-#define GPIOR_VUPST                             0x00400000L
-#define GPIOR_VUPW                              0x00800000L
-#define GPIOR_GP1OE                             0x01000000L
-#define GPIOR_GP1PT                             0x02000000L
-#define GPIOR_GP1ST                             0x04000000L
-#define GPIOR_GP1W                              0x08000000L
-#define GPIOR_GP3OE                             0x10000000L
-#define GPIOR_GP3PT                             0x20000000L
-#define GPIOR_GP3ST                             0x40000000L
-#define GPIOR_GP3W                              0x80000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the clock control register 1.
-//
-//****************************************************************************
-#define CLKCR1_PLLSS_MASK                       0x0000000CL
-#define CLKCR1_PLLSS_SERIAL                     0x00000000L
-#define CLKCR1_PLLSS_CRYSTAL                    0x00000004L
-#define CLKCR1_PLLSS_PCI                        0x00000008L
-#define CLKCR1_PLLSS_RESERVED                   0x0000000CL
-#define CLKCR1_PLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_PLLOS                            0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the feature reporting register.
-//
-//****************************************************************************
-#define FRR_FAB_MASK                            0x00000003L
-#define FRR_MASK_MASK                           0x0000001CL
-#define FRR_ID_MASK                             0x00003000L
-#define FRR_FAB_SHIFT                           0L
-#define FRR_MASK_SHIFT                          2L
-#define FRR_ID_SHIFT                            12L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 1 configuration
-// register.
-//
-//****************************************************************************
-#define SERC1_VALUE                             0x00000003L
-#define SERC1_SO1EN                             0x00000001L
-#define SERC1_SO1F_MASK                         0x0000000EL
-#define SERC1_SO1F_CS423X                       0x00000000L
-#define SERC1_SO1F_AC97                         0x00000002L
-#define SERC1_SO1F_DAC                          0x00000004L
-#define SERC1_SO1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 2 configuration
-// register.
-//
-//****************************************************************************
-#define SERC2_VALUE                             0x00000003L
-#define SERC2_SI1EN                             0x00000001L
-#define SERC2_SI1F_MASK                         0x0000000EL
-#define SERC2_SI1F_CS423X                       0x00000000L
-#define SERC2_SI1F_AC97                         0x00000002L
-#define SERC2_SI1F_ADC                          0x00000004L
-#define SERC2_SI1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 control register.
-//
-//****************************************************************************
-#define ACCTL_ESYN                              0x00000002L
-#define ACCTL_VFRM                              0x00000004L
-#define ACCTL_DCV                               0x00000008L
-#define ACCTL_CRW                               0x00000010L
-#define ACCTL_TC                                0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register.
-//
-//****************************************************************************
-#define ACSTS_CRDY                              0x00000001L
-#define ACSTS_VSTS                              0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 output slot valid
-// register.
-//
-//****************************************************************************
-#define ACOSV_SLV3                              0x00000001L
-#define ACOSV_SLV4                              0x00000002L
-#define ACOSV_SLV5                              0x00000004L
-#define ACOSV_SLV6                              0x00000008L
-#define ACOSV_SLV7                              0x00000010L
-#define ACOSV_SLV8                              0x00000020L
-#define ACOSV_SLV9                              0x00000040L
-#define ACOSV_SLV10                             0x00000080L
-#define ACOSV_SLV11                             0x00000100L
-#define ACOSV_SLV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command address
-// register.
-//
-//****************************************************************************
-#define ACCAD_CI_MASK                           0x0000007FL
-#define ACCAD_CI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command data register.
-//
-//****************************************************************************
-#define ACCDA_CD_MASK                           0x0000FFFFL
-#define ACCDA_CD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register.
-//
-//****************************************************************************
-#define ACISV_ISV3                              0x00000001L
-#define ACISV_ISV4                              0x00000002L
-#define ACISV_ISV5                              0x00000004L
-#define ACISV_ISV6                              0x00000008L
-#define ACISV_ISV7                              0x00000010L
-#define ACISV_ISV8                              0x00000020L
-#define ACISV_ISV9                              0x00000040L
-#define ACISV_ISV10                             0x00000080L
-#define ACISV_ISV11                             0x00000100L
-#define ACISV_ISV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register.
-//
-//****************************************************************************
-#define ACSAD_SI_MASK                           0x0000007FL
-#define ACSAD_SI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register.
-//
-//****************************************************************************
-#define ACSDA_SD_MASK                           0x0000FFFFL
-#define ACSDA_SD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers (all 12).
-//
-//****************************************************************************
-#define IOTAC_SA_MASK                           0x0000FFFFL
-#define IOTAC_MSK_MASK                          0x000F0000L
-#define IOTAC_IODC_MASK                         0x06000000L
-#define IOTAC_IODC_16_BIT                       0x00000000L
-#define IOTAC_IODC_10_BIT                       0x02000000L
-#define IOTAC_IODC_12_BIT                       0x04000000L
-#define IOTAC_WSPI                              0x08000000L
-#define IOTAC_RSPI                              0x10000000L
-#define IOTAC_WSE                               0x20000000L
-#define IOTAC_WE                                0x40000000L
-#define IOTAC_RE                                0x80000000L
-#define IOTAC_SA_SHIFT                          0L
-#define IOTAC_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI master enable
-// register.
-//
-//****************************************************************************
-#define PCPCIEN_EN                              0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick poll/trigger
-// register.
-//
-//****************************************************************************
-#define JSPT_CAX                                0x00000001L
-#define JSPT_CAY                                0x00000002L
-#define JSPT_CBX                                0x00000004L
-#define JSPT_CBY                                0x00000008L
-#define JSPT_BA1                                0x00000010L
-#define JSPT_BA2                                0x00000020L
-#define JSPT_BB1                                0x00000040L
-#define JSPT_BB2                                0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick control register.
-// The TBF bit has been moved from MIDSR register to JSCTL register bit 8.
-//
-//****************************************************************************
-#define JSCTL_SP_MASK                           0x00000003L
-#define JSCTL_SP_SLOW                           0x00000000L
-#define JSCTL_SP_MEDIUM_SLOW                    0x00000001L
-#define JSCTL_SP_MEDIUM_FAST                    0x00000002L
-#define JSCTL_SP_FAST                           0x00000003L
-#define JSCTL_ARE                               0x00000004L
-#define JSCTL_TBF                               0x00000100L
-
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI control register.
-//
-//****************************************************************************
-#define MIDCR_TXE                               0x00000001L
-#define MIDCR_RXE                               0x00000002L
-#define MIDCR_RIE                               0x00000004L
-#define MIDCR_TIE                               0x00000008L
-#define MIDCR_MLB                               0x00000010L
-#define MIDCR_MRST                              0x00000020L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI status register.
-//
-//****************************************************************************
-#define MIDSR_RBE                               0x00000080L
-#define MIDSR_RDA                               0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI write port register.
-//
-//****************************************************************************
-#define MIDWP_MWD_MASK                          0x000000FFL
-#define MIDWP_MWD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI read port register.
-//
-//****************************************************************************
-#define MIDRP_MRD_MASK                          0x000000FFL
-#define MIDRP_MRD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the configuration interface
-// register.
-//
-//****************************************************************************
-#define CFGI_CLK                                0x00000001L
-#define CFGI_DOUT                               0x00000002L
-#define CFGI_DIN_EEN                            0x00000004L
-#define CFGI_EELD                               0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the subsystem ID and vendor ID
-// register.
-//
-//****************************************************************************
-#define SSVID_VID_MASK                          0x0000FFFFL
-#define SSVID_SID_MASK                          0xFFFF0000L
-#define SSVID_VID_SHIFT                         0L
-#define SSVID_SID_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the GPIO pin interface register.
-//
-//****************************************************************************
-#define GPIOR_VOLDN                             0x00000001L
-#define GPIOR_VOLUP                             0x00000002L
-#define GPIOR_SI2D                              0x00000004L
-#define GPIOR_SI2OE                             0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register 2.
-//
-//****************************************************************************
-#define ACSTS2_CRDY                             0x00000001L
-#define ACSTS2_VSTS                             0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register 2.
-//
-//****************************************************************************
-#define ACISV2_ISV3                             0x00000001L
-#define ACISV2_ISV4                             0x00000002L
-#define ACISV2_ISV5                             0x00000004L
-#define ACISV2_ISV6                             0x00000008L
-#define ACISV2_ISV7                             0x00000010L
-#define ACISV2_ISV8                             0x00000020L
-#define ACISV2_ISV9                             0x00000040L
-#define ACISV2_ISV10                            0x00000080L
-#define ACISV2_ISV11                            0x00000100L
-#define ACISV2_ISV12                            0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register 2.
-//
-//****************************************************************************
-#define ACSAD2_SI_MASK                          0x0000007FL
-#define ACSAD2_SI_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register 2.
-//
-//****************************************************************************
-#define ACSDA2_SD_MASK                          0x0000FFFFL
-#define ACSDA2_SD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap control register.
-//
-//****************************************************************************
-#define IOTCR_ITD                               0x00000001L
-#define IOTCR_HRV                               0x00000002L
-#define IOTCR_SRV                               0x00000004L
-#define IOTCR_DTI                               0x00000008L
-#define IOTCR_DFI                               0x00000010L
-#define IOTCR_DDP                               0x00000020L
-#define IOTCR_JTE                               0x00000040L
-#define IOTCR_PPE                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Hardware Master Volume.  
-//
-//****************************************************************************
-#define IOTGP_SA_MASK                           0x0000FFFFL
-#define IOTGP_MSK_MASK                          0x000F0000L
-#define IOTGP_IODC_MASK                         0x06000000L
-#define IOTGP_IODC_16_BIT                       0x00000000L
-#define IOTGP_IODC_10_BIT                       0x02000000L
-#define IOTGP_IODC_12_BIT                       0x04000000L
-#define IOTGP_WSPI                              0x08000000L
-#define IOTGP_RSPI                              0x10000000L
-#define IOTGP_WSE                               0x20000000L
-#define IOTGP_WE                                0x40000000L
-#define IOTGP_RE                                0x80000000L
-#define IOTGP_SA_SHIFT                          0L
-#define IOTGP_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Sound Blaster
-//
-//****************************************************************************
-#define IOTSB_SA_MASK                           0x0000FFFFL
-#define IOTSB_MSK_MASK                          0x000F0000L
-#define IOTSB_IODC_MASK                         0x06000000L
-#define IOTSB_IODC_16_BIT                       0x00000000L
-#define IOTSB_IODC_10_BIT                       0x02000000L
-#define IOTSB_IODC_12_BIT                       0x04000000L
-#define IOTSB_WSPI                              0x08000000L
-#define IOTSB_RSPI                              0x10000000L
-#define IOTSB_WSE                               0x20000000L
-#define IOTSB_WE                                0x40000000L
-#define IOTSB_RE                                0x80000000L
-#define IOTSB_SA_SHIFT                          0L
-#define IOTSB_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for FM.
-//
-//****************************************************************************
-#define IOTFM_SA_MASK                           0x0000FFFFL
-#define IOTFM_MSK_MASK                          0x000F0000L
-#define IOTFM_IODC_MASK                         0x06000000L
-#define IOTFM_IODC_16_BIT                       0x00000000L
-#define IOTFM_IODC_10_BIT                       0x02000000L
-#define IOTFM_IODC_12_BIT                       0x04000000L
-#define IOTFM_WSPI                              0x08000000L
-#define IOTFM_RSPI                              0x10000000L
-#define IOTFM_WSE                               0x20000000L
-#define IOTFM_WE                                0x40000000L
-#define IOTFM_RE                                0x80000000L
-#define IOTFM_SA_SHIFT                          0L
-#define IOTFM_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI request register.
-//
-//****************************************************************************
-#define PCPRR_RDC_MASK                         0x00000007L
-#define PCPRR_REQ                              0x00008000L
-#define PCPRR_RDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI grant register.
-//
-//****************************************************************************
-#define PCPGR_GDC_MASK                         0x00000007L
-#define PCPGR_VL                               0x00008000L
-#define PCPGR_GDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI Control Register.
-//
-//****************************************************************************
-#define PCPCR_EN                               0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the debug index register.
-//
-//****************************************************************************
-#define DREG_REGID_MASK                         0x0000007FL
-#define DREG_DEBUG                              0x00000080L
-#define DREG_RGBK_MASK                          0x00000700L
-#define DREG_TRAP                               0x00000800L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_TRAPX                              0x00001000L
-#endif
-#endif
-#define DREG_REGID_SHIFT                        0L
-#define DREG_RGBK_SHIFT                         8L
-#define DREG_RGBK_REGID_MASK                    0x0000077FL
-#define DREG_REGID_R0                           0x00000010L
-#define DREG_REGID_R1                           0x00000011L
-#define DREG_REGID_R2                           0x00000012L
-#define DREG_REGID_R3                           0x00000013L
-#define DREG_REGID_R4                           0x00000014L
-#define DREG_REGID_R5                           0x00000015L
-#define DREG_REGID_R6                           0x00000016L
-#define DREG_REGID_R7                           0x00000017L
-#define DREG_REGID_R8                           0x00000018L
-#define DREG_REGID_R9                           0x00000019L
-#define DREG_REGID_RA                           0x0000001AL
-#define DREG_REGID_RB                           0x0000001BL
-#define DREG_REGID_RC                           0x0000001CL
-#define DREG_REGID_RD                           0x0000001DL
-#define DREG_REGID_RE                           0x0000001EL
-#define DREG_REGID_RF                           0x0000001FL
-#define DREG_REGID_RA_BUS_LOW                   0x00000020L
-#define DREG_REGID_RA_BUS_HIGH                  0x00000038L
-#define DREG_REGID_YBUS_LOW                     0x00000050L
-#define DREG_REGID_YBUS_HIGH                    0x00000058L
-#define DREG_REGID_TRAP_0                       0x00000100L
-#define DREG_REGID_TRAP_1                       0x00000101L
-#define DREG_REGID_TRAP_2                       0x00000102L
-#define DREG_REGID_TRAP_3                       0x00000103L
-#define DREG_REGID_TRAP_4                       0x00000104L
-#define DREG_REGID_TRAP_5                       0x00000105L
-#define DREG_REGID_TRAP_6                       0x00000106L
-#define DREG_REGID_TRAP_7                       0x00000107L
-#define DREG_REGID_INDIRECT_ADDRESS             0x0000010EL
-#define DREG_REGID_TOP_OF_STACK                 0x0000010FL
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_8                       0x00000110L
-#define DREG_REGID_TRAP_9                       0x00000111L
-#define DREG_REGID_TRAP_10                      0x00000112L
-#define DREG_REGID_TRAP_11                      0x00000113L
-#define DREG_REGID_TRAP_12                      0x00000114L
-#define DREG_REGID_TRAP_13                      0x00000115L
-#define DREG_REGID_TRAP_14                      0x00000116L
-#define DREG_REGID_TRAP_15                      0x00000117L
-#define DREG_REGID_TRAP_16                      0x00000118L
-#define DREG_REGID_TRAP_17                      0x00000119L
-#define DREG_REGID_TRAP_18                      0x0000011AL
-#define DREG_REGID_TRAP_19                      0x0000011BL
-#define DREG_REGID_TRAP_20                      0x0000011CL
-#define DREG_REGID_TRAP_21                      0x0000011DL
-#define DREG_REGID_TRAP_22                      0x0000011EL
-#define DREG_REGID_TRAP_23                      0x0000011FL
-#endif
-#endif
-#define DREG_REGID_RSA0_LOW                     0x00000200L
-#define DREG_REGID_RSA0_HIGH                    0x00000201L
-#define DREG_REGID_RSA1_LOW                     0x00000202L
-#define DREG_REGID_RSA1_HIGH                    0x00000203L
-#define DREG_REGID_RSA2                         0x00000204L
-#define DREG_REGID_RSA3                         0x00000205L
-#define DREG_REGID_RSI0_LOW                     0x00000206L
-#define DREG_REGID_RSI0_HIGH                    0x00000207L
-#define DREG_REGID_RSI1                         0x00000208L
-#define DREG_REGID_RSI2                         0x00000209L
-#define DREG_REGID_SAGUSTATUS                   0x0000020AL
-#define DREG_REGID_RSCONFIG01_LOW               0x0000020BL
-#define DREG_REGID_RSCONFIG01_HIGH              0x0000020CL
-#define DREG_REGID_RSCONFIG23_LOW               0x0000020DL
-#define DREG_REGID_RSCONFIG23_HIGH              0x0000020EL
-#define DREG_REGID_RSDMA01E                     0x0000020FL
-#define DREG_REGID_RSDMA23E                     0x00000210L
-#define DREG_REGID_RSD0_LOW                     0x00000211L
-#define DREG_REGID_RSD0_HIGH                    0x00000212L
-#define DREG_REGID_RSD1_LOW                     0x00000213L
-#define DREG_REGID_RSD1_HIGH                    0x00000214L
-#define DREG_REGID_RSD2_LOW                     0x00000215L
-#define DREG_REGID_RSD2_HIGH                    0x00000216L
-#define DREG_REGID_RSD3_LOW                     0x00000217L
-#define DREG_REGID_RSD3_HIGH                    0x00000218L
-#define DREG_REGID_SRAR_HIGH                    0x0000021AL
-#define DREG_REGID_SRAR_LOW                     0x0000021BL
-#define DREG_REGID_DMA_STATE                    0x0000021CL
-#define DREG_REGID_CURRENT_DMA_STREAM           0x0000021DL
-#define DREG_REGID_NEXT_DMA_STREAM              0x0000021EL
-#define DREG_REGID_CPU_STATUS                   0x00000300L
-#define DREG_REGID_MAC_MODE                     0x00000301L
-#define DREG_REGID_STACK_AND_REPEAT             0x00000302L
-#define DREG_REGID_INDEX0                       0x00000304L
-#define DREG_REGID_INDEX1                       0x00000305L
-#define DREG_REGID_DMA_STATE_0_3                0x00000400L
-#define DREG_REGID_DMA_STATE_4_7                0x00000404L
-#define DREG_REGID_DMA_STATE_8_11               0x00000408L
-#define DREG_REGID_DMA_STATE_12_15              0x0000040CL
-#define DREG_REGID_DMA_STATE_16_19              0x00000410L
-#define DREG_REGID_DMA_STATE_20_23              0x00000414L
-#define DREG_REGID_DMA_STATE_24_27              0x00000418L
-#define DREG_REGID_DMA_STATE_28_31              0x0000041CL
-#define DREG_REGID_DMA_STATE_32_35              0x00000420L
-#define DREG_REGID_DMA_STATE_36_39              0x00000424L
-#define DREG_REGID_DMA_STATE_40_43              0x00000428L
-#define DREG_REGID_DMA_STATE_44_47              0x0000042CL
-#define DREG_REGID_DMA_STATE_48_51              0x00000430L
-#define DREG_REGID_DMA_STATE_52_55              0x00000434L
-#define DREG_REGID_DMA_STATE_56_59              0x00000438L
-#define DREG_REGID_DMA_STATE_60_63              0x0000043CL
-#define DREG_REGID_DMA_STATE_64_67              0x00000440L
-#define DREG_REGID_DMA_STATE_68_71              0x00000444L
-#define DREG_REGID_DMA_STATE_72_75              0x00000448L
-#define DREG_REGID_DMA_STATE_76_79              0x0000044CL
-#define DREG_REGID_DMA_STATE_80_83              0x00000450L
-#define DREG_REGID_DMA_STATE_84_87              0x00000454L
-#define DREG_REGID_DMA_STATE_88_91              0x00000458L
-#define DREG_REGID_DMA_STATE_92_95              0x0000045CL
-#define DREG_REGID_TRAP_SELECT                  0x00000500L
-#define DREG_REGID_TRAP_WRITE_0                 0x00000500L
-#define DREG_REGID_TRAP_WRITE_1                 0x00000501L
-#define DREG_REGID_TRAP_WRITE_2                 0x00000502L
-#define DREG_REGID_TRAP_WRITE_3                 0x00000503L
-#define DREG_REGID_TRAP_WRITE_4                 0x00000504L
-#define DREG_REGID_TRAP_WRITE_5                 0x00000505L
-#define DREG_REGID_TRAP_WRITE_6                 0x00000506L
-#define DREG_REGID_TRAP_WRITE_7                 0x00000507L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_WRITE_8                 0x00000510L
-#define DREG_REGID_TRAP_WRITE_9                 0x00000511L
-#define DREG_REGID_TRAP_WRITE_10                0x00000512L
-#define DREG_REGID_TRAP_WRITE_11                0x00000513L
-#define DREG_REGID_TRAP_WRITE_12                0x00000514L
-#define DREG_REGID_TRAP_WRITE_13                0x00000515L
-#define DREG_REGID_TRAP_WRITE_14                0x00000516L
-#define DREG_REGID_TRAP_WRITE_15                0x00000517L
-#define DREG_REGID_TRAP_WRITE_16                0x00000518L
-#define DREG_REGID_TRAP_WRITE_17                0x00000519L
-#define DREG_REGID_TRAP_WRITE_18                0x0000051AL
-#define DREG_REGID_TRAP_WRITE_19                0x0000051BL
-#define DREG_REGID_TRAP_WRITE_20                0x0000051CL
-#define DREG_REGID_TRAP_WRITE_21                0x0000051DL
-#define DREG_REGID_TRAP_WRITE_22                0x0000051EL
-#define DREG_REGID_TRAP_WRITE_23                0x0000051FL
-#endif
-#endif
-#define DREG_REGID_MAC0_ACC0_LOW                0x00000600L
-#define DREG_REGID_MAC0_ACC1_LOW                0x00000601L
-#define DREG_REGID_MAC0_ACC2_LOW                0x00000602L
-#define DREG_REGID_MAC0_ACC3_LOW                0x00000603L
-#define DREG_REGID_MAC1_ACC0_LOW                0x00000604L
-#define DREG_REGID_MAC1_ACC1_LOW                0x00000605L
-#define DREG_REGID_MAC1_ACC2_LOW                0x00000606L
-#define DREG_REGID_MAC1_ACC3_LOW                0x00000607L
-#define DREG_REGID_MAC0_ACC0_MID                0x00000608L
-#define DREG_REGID_MAC0_ACC1_MID                0x00000609L
-#define DREG_REGID_MAC0_ACC2_MID                0x0000060AL
-#define DREG_REGID_MAC0_ACC3_MID                0x0000060BL
-#define DREG_REGID_MAC1_ACC0_MID                0x0000060CL
-#define DREG_REGID_MAC1_ACC1_MID                0x0000060DL
-#define DREG_REGID_MAC1_ACC2_MID                0x0000060EL
-#define DREG_REGID_MAC1_ACC3_MID                0x0000060FL
-#define DREG_REGID_MAC0_ACC0_HIGH               0x00000610L
-#define DREG_REGID_MAC0_ACC1_HIGH               0x00000611L
-#define DREG_REGID_MAC0_ACC2_HIGH               0x00000612L
-#define DREG_REGID_MAC0_ACC3_HIGH               0x00000613L
-#define DREG_REGID_MAC1_ACC0_HIGH               0x00000614L
-#define DREG_REGID_MAC1_ACC1_HIGH               0x00000615L
-#define DREG_REGID_MAC1_ACC2_HIGH               0x00000616L
-#define DREG_REGID_MAC1_ACC3_HIGH               0x00000617L
-#define DREG_REGID_RSHOUT_LOW                   0x00000620L
-#define DREG_REGID_RSHOUT_MID                   0x00000628L
-#define DREG_REGID_RSHOUT_HIGH                  0x00000630L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 S/PDIF Control register.
-//
-//****************************************************************************
-#define SPDIF_CONTROL_SPDIF_EN                 0x00008000L
-#define SPDIF_CONTROL_VAL                      0x00004000L
-#define SPDIF_CONTROL_COPY                     0x00000004L
-#define SPDIF_CONTROL_CC0                      0x00000010L
-#define SPDIF_CONTROL_CC1                      0x00000020L
-#define SPDIF_CONTROL_CC2                      0x00000040L
-#define SPDIF_CONTROL_CC3                      0x00000080L
-#define SPDIF_CONTROL_CC4                      0x00000100L
-#define SPDIF_CONTROL_CC5                      0x00000200L
-#define SPDIF_CONTROL_CC6                      0x00000400L
-#define SPDIF_CONTROL_L                        0x00000800L
-
-#endif // _H_HWDEFS
diff --git a/sound/oss/cs4281/cs4281_wrapper-24.c b/sound/oss/cs4281/cs4281_wrapper-24.c
deleted file mode 100644
index 4559f02..0000000
--- a/sound/oss/cs4281/cs4281_wrapper-24.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281_wrapper.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/20/00 trw - new file. 
-*
-*******************************************************************************/
-
-#include <linux/spinlock.h>
-
-static int cs4281_resume_null(struct pci_dev *pcidev) { return 0; }
-static int cs4281_suspend_null(struct pci_dev *pcidev, pm_message_t state) { return 0; }
-
-#define free_dmabuf(state, dmabuf) \
-	pci_free_consistent(state->pcidev, \
-			    PAGE_SIZE << (dmabuf)->buforder, \
-			    (dmabuf)->rawbuf, (dmabuf)->dmaaddr);
-#define free_dmabuf2(state, dmabuf) \
-	pci_free_consistent((state)->pcidev, \
-				    PAGE_SIZE << (state)->buforder_tmpbuff, \
-				    (state)->tmpbuff, (state)->dmaaddr_tmpbuff);
-#define cs4x_pgoff(vma) ((vma)->vm_pgoff)
-
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
deleted file mode 100644
index 0400a41..0000000
--- a/sound/oss/cs4281/cs4281m.c
+++ /dev/null
@@ -1,4487 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- adapted from drivers by Thomas Sailer, 
-*            -- but don't bug him; Problems should go to:
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Module command line parameters:
-*   none
-*
-*  Supported devices:
-*  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
-*  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
-*  /dev/midi   simple MIDI UART interface, no ioctl
-*
-* Modification History
-* 08/20/00 trw - silence and no stopping DAC until release
-* 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop.
-* 09/18/00 trw - added 16bit only record with conversion 
-* 09/24/00 trw - added Enhanced Full duplex (separate simultaneous 
-*                capture/playback rates)
-* 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin  
-*                libOSSm.so)
-* 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal)
-* 11/03/00 trw - fixed interrupt loss/stutter, added debug.
-* 11/10/00 bkz - added __devinit to cs4281_hw_init()
-* 11/10/00 trw - fixed SMP and capture spinlock hang.
-* 12/04/00 trw - cleaned up CSDEBUG flags and added "defaultorder" moduleparm.
-* 12/05/00 trw - fixed polling (myth2), and added underrun swptr fix.
-* 12/08/00 trw - added PM support. 
-* 12/14/00 trw - added wrapper code, builds under 2.4.0, 2.2.17-20, 2.2.17-8 
-*		 (RH/Dell base), 2.2.18, 2.2.12.  cleaned up code mods by ident.
-* 12/19/00 trw - added PM support for 2.2 base (apm_callback). other PM cleanup.
-* 12/21/00 trw - added fractional "defaultorder" inputs. if >100 then use 
-*		 defaultorder-100 as power of 2 for the buffer size. example:
-*		 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
-*
-*******************************************************************************/
-
-/* uncomment the following line to disable building PM support into the driver */
-//#define NOT_CS4281_PM 1 
-
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/fs.h>
-#include <linux/wait.h>
-
-#include <asm/current.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-//#include "cs_dm.h"
-#include "cs4281_hwdefs.h"
-#include "cs4281pm.h"
-
-struct cs4281_state;
-
-static void stop_dac(struct cs4281_state *s);
-static void stop_adc(struct cs4281_state *s);
-static void start_dac(struct cs4281_state *s);
-static void start_adc(struct cs4281_state *s);
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-// --------------------------------------------------------------------- 
-
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS          0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CRYSTAL_CS4281
-#define PCI_DEVICE_ID_CRYSTAL_CS4281  0x6005
-#endif
-
-#define CS4281_MAGIC  ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS)
-#define	CS4281_CFLR_DEFAULT	0x00000001  /* CFLR must be in AC97 link mode */
-
-// buffer order determines the size of the dma buffer for the driver.
-// under Linux, a smaller buffer allows more responsiveness from many of the 
-// applications (e.g. games).  A larger buffer allows some of the apps (esound) 
-// to not underrun the dma buffer as easily.  As default, use 32k (order=3)
-// rather than 64k as some of the games work more responsively.
-// log base 2( buff sz = 32k).
-static unsigned long defaultorder = 3;
-module_param(defaultorder, ulong, 0);
-
-//
-// Turn on/off debugging compilation by commenting out "#define CSDEBUG"
-//
-#define CSDEBUG 1
-#if CSDEBUG
-#define CSDEBUG_INTERFACE 1
-#else
-#undef CSDEBUG_INTERFACE
-#endif
-//
-// cs_debugmask areas
-//
-#define CS_INIT	 	0x00000001	// initialization and probe functions
-#define CS_ERROR 	0x00000002	// tmp debugging bit placeholder
-#define CS_INTERRUPT	0x00000004	// interrupt handler (separate from all other)
-#define CS_FUNCTION 	0x00000008	// enter/leave functions
-#define CS_WAVE_WRITE 	0x00000010	// write information for wave
-#define CS_WAVE_READ 	0x00000020	// read information for wave
-#define CS_MIDI_WRITE 	0x00000040	// write information for midi
-#define CS_MIDI_READ 	0x00000080	// read information for midi
-#define CS_MPU401_WRITE 0x00000100	// write information for mpu401
-#define CS_MPU401_READ 	0x00000200	// read information for mpu401
-#define CS_OPEN		0x00000400	// all open functions in the driver
-#define CS_RELEASE	0x00000800	// all release functions in the driver
-#define CS_PARMS	0x00001000	// functional and operational parameters
-#define CS_IOCTL	0x00002000	// ioctl (non-mixer)
-#define CS_PM		0x00004000	// power management 
-#define CS_TMP		0x10000000	// tmp debug mask bit
-
-#define CS_IOCTL_CMD_SUSPEND	0x1	// suspend
-#define CS_IOCTL_CMD_RESUME	0x2	// resume
-//
-// CSDEBUG is usual mode is set to 1, then use the
-// cs_debuglevel and cs_debugmask to turn on or off debugging.
-// Debug level of 1 has been defined to be kernel errors and info
-// that should be printed on any released driver.
-//
-#if CSDEBUG
-#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;}
-#else
-#define CS_DBGOUT(mask,level,x)
-#endif
-
-#if CSDEBUG
-static unsigned long cs_debuglevel = 1;	// levels range from 1-9
-static unsigned long cs_debugmask = CS_INIT | CS_ERROR;	// use CS_DBGOUT with various mask values
-module_param(cs_debuglevel, ulong, 0);
-module_param(cs_debugmask, ulong, 0);
-#endif
-#define CS_TRUE 	1
-#define CS_FALSE 	0
-
-// MIDI buffer sizes 
-#define MIDIINBUF  500
-#define MIDIOUTBUF 500
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define CS4281_MAJOR_VERSION 	1
-#define CS4281_MINOR_VERSION 	13
-#ifdef __ia64__
-#define CS4281_ARCH	     	64	//architecture key
-#else
-#define CS4281_ARCH	     	32	//architecture key
-#endif
-
-#define CS_TYPE_ADC 0
-#define CS_TYPE_DAC 1
-
-
-static const char invalid_magic[] =
-    KERN_CRIT "cs4281: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-        if (!(s) || (s)->magic != CS4281_MAGIC) { \
-                printk(invalid_magic);            \
-                return -ENXIO;                    \
-        }                                         \
-})
-
-//LIST_HEAD(cs4281_devs);
-static struct list_head cs4281_devs = { &cs4281_devs, &cs4281_devs };
-
-struct cs4281_state; 
-
-#include "cs4281_wrapper-24.c"
-
-struct cs4281_state {
-	// magic 
-	unsigned int magic;
-
-	// we keep the cards in a linked list 
-	struct cs4281_state *next;
-
-	// pcidev is needed to turn off the DDMA controller at driver shutdown 
-	struct pci_dev *pcidev;
-	struct list_head list;
-
-	// soundcore stuff 
-	int dev_audio;
-	int dev_mixer;
-	int dev_midi;
-
-	// hardware resources 
-	unsigned int pBA0phys, pBA1phys;
-	char __iomem *pBA0;
-	char __iomem *pBA1;
-	unsigned int irq;
-
-	// mixer registers 
-	struct {
-		unsigned short vol[10];
-		unsigned int recsrc;
-		unsigned int modcnt;
-		unsigned short micpreamp;
-	} mix;
-
-	// wave stuff   
-	struct properties {
-		unsigned fmt;
-		unsigned fmt_original;	// original requested format
-		unsigned channels;
-		unsigned rate;
-		unsigned char clkdiv;
-	} prop_dac, prop_adc;
-	unsigned conversion:1;	// conversion from 16 to 8 bit in progress
-	void *tmpbuff;		// tmp buffer for sample conversions
-	unsigned ena;
-	spinlock_t lock;
-	struct mutex open_sem;
-	struct mutex open_sem_adc;
-	struct mutex open_sem_dac;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-	wait_queue_head_t open_wait_adc;
-	wait_queue_head_t open_wait_dac;
-
-	dma_addr_t dmaaddr_tmpbuff;
-	unsigned buforder_tmpbuff;	// Log base 2 of 'rawbuf' size in bytes..
-	struct dmabuf {
-		void *rawbuf;	// Physical address of  
-		dma_addr_t dmaaddr;
-		unsigned buforder;	// Log base 2 of 'rawbuf' size in bytes..
-		unsigned numfrag;	// # of 'fragments' in the buffer.
-		unsigned fragshift;	// Log base 2 of fragment size.
-		unsigned hwptr, swptr;
-		unsigned total_bytes;	// # bytes process since open.
-		unsigned blocks;	// last returned blocks value GETOPTR
-		unsigned wakeup;	// interrupt occurred on block 
-		int count;
-		unsigned underrun;	// underrun flag
-		unsigned error;	// over/underrun 
-		wait_queue_head_t wait;
-		// redundant, but makes calculations easier 
-		unsigned fragsize;	// 2**fragshift..
-		unsigned dmasize;	// 2**buforder.
-		unsigned fragsamples;
-		// OSS stuff 
-		unsigned mapped:1;	// Buffer mapped in cs4281_mmap()?
-		unsigned ready:1;	// prog_dmabuf_dac()/adc() successful?
-		unsigned endcleared:1;
-		unsigned type:1;	// adc or dac buffer (CS_TYPE_XXX)
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac, dma_adc;
-
-	// midi stuff 
-	struct {
-		unsigned ird, iwr, icnt;
-		unsigned ord, owr, ocnt;
-		wait_queue_head_t iwait;
-		wait_queue_head_t owait;
-		struct timer_list timer;
-		unsigned char ibuf[MIDIINBUF];
-		unsigned char obuf[MIDIOUTBUF];
-	} midi;
-
-	struct cs4281_pm pm;
-	struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];
-};
-
-#include "cs4281pm-24.c"
-
-#if CSDEBUG
-
-// DEBUG ROUTINES
-
-#define SOUND_MIXER_CS_GETDBGLEVEL 	_SIOWR('M',120, int)
-#define SOUND_MIXER_CS_SETDBGLEVEL 	_SIOWR('M',121, int)
-#define SOUND_MIXER_CS_GETDBGMASK 	_SIOWR('M',122, int)
-#define SOUND_MIXER_CS_SETDBGMASK 	_SIOWR('M',123, int)
-
-#define SOUND_MIXER_CS_APM	 	_SIOWR('M',124, int)
-
-
-static void cs_printioctl(unsigned int x)
-{
-	unsigned int i;
-	unsigned char vidx;
-	// Index of mixtable1[] member is Device ID 
-	// and must be <= SOUND_MIXER_NRDEVICES.
-	// Value of array member is index into s->mix.vol[]
-	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-		[SOUND_MIXER_PCM] = 1,	// voice 
-		[SOUND_MIXER_LINE1] = 2,	// AUX
-		[SOUND_MIXER_CD] = 3,	// CD 
-		[SOUND_MIXER_LINE] = 4,	// Line 
-		[SOUND_MIXER_SYNTH] = 5,	// FM
-		[SOUND_MIXER_MIC] = 6,	// Mic 
-		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
-		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
-		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
-	};
-
-	switch (x) {
-	case SOUND_MIXER_CS_GETDBGMASK:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_GETDBGMASK:\n"));
-		break;
-	case SOUND_MIXER_CS_GETDBGLEVEL:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_GETDBGLEVEL:\n"));
-		break;
-	case SOUND_MIXER_CS_SETDBGMASK:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_SETDBGMASK:\n"));
-		break;
-	case SOUND_MIXER_CS_SETDBGLEVEL:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_SETDBGLEVEL:\n"));
-		break;
-	case OSS_GETVERSION:
-		CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n"));
-		break;
-	case SNDCTL_DSP_SYNC:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n"));
-		break;
-	case SNDCTL_DSP_SETDUPLEX:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n"));
-		break;
-	case SNDCTL_DSP_GETCAPS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n"));
-		break;
-	case SNDCTL_DSP_RESET:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n"));
-		break;
-	case SNDCTL_DSP_SPEED:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n"));
-		break;
-	case SNDCTL_DSP_STEREO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n"));
-		break;
-	case SNDCTL_DSP_CHANNELS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n"));
-		break;
-	case SNDCTL_DSP_GETFMTS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n"));
-		break;
-	case SNDCTL_DSP_SETFMT:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n"));
-		break;
-	case SNDCTL_DSP_POST:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n"));
-		break;
-	case SNDCTL_DSP_GETTRIGGER:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n"));
-		break;
-	case SNDCTL_DSP_SETTRIGGER:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n"));
-		break;
-	case SNDCTL_DSP_GETOSPACE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n"));
-		break;
-	case SNDCTL_DSP_GETISPACE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n"));
-		break;
-	case SNDCTL_DSP_NONBLOCK:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n"));
-		break;
-	case SNDCTL_DSP_GETODELAY:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n"));
-		break;
-	case SNDCTL_DSP_GETIPTR:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n"));
-		break;
-	case SNDCTL_DSP_GETOPTR:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n"));
-		break;
-	case SNDCTL_DSP_GETBLKSIZE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n"));
-		break;
-	case SNDCTL_DSP_SETFRAGMENT:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SNDCTL_DSP_SETFRAGMENT:\n"));
-		break;
-	case SNDCTL_DSP_SUBDIVIDE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n"));
-		break;
-	case SOUND_PCM_READ_RATE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n"));
-		break;
-	case SOUND_PCM_READ_CHANNELS:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_PCM_READ_CHANNELS:\n"));
-		break;
-	case SOUND_PCM_READ_BITS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n"));
-		break;
-	case SOUND_PCM_WRITE_FILTER:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_PCM_WRITE_FILTER:\n"));
-		break;
-	case SNDCTL_DSP_SETSYNCRO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n"));
-		break;
-	case SOUND_PCM_READ_FILTER:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE1:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE2:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE3:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE4:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE5:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n"));
-		break;
-	case SOUND_MIXER_INFO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n"));
-		break;
-	case SOUND_OLD_MIXER_INFO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n"));
-		break;
-
-	default:
-		switch (_IOC_NR(x)) {
-		case SOUND_MIXER_VOLUME:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_VOLUME:\n"));
-			break;
-		case SOUND_MIXER_SPEAKER:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_SPEAKER:\n"));
-			break;
-		case SOUND_MIXER_RECLEV:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_RECLEV:\n"));
-			break;
-		case SOUND_MIXER_MIC:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_MIC:\n"));
-			break;
-		case SOUND_MIXER_SYNTH:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_SYNTH:\n"));
-			break;
-		case SOUND_MIXER_RECSRC:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_RECSRC:\n"));
-			break;
-		case SOUND_MIXER_DEVMASK:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_DEVMASK:\n"));
-			break;
-		case SOUND_MIXER_RECMASK:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_RECMASK:\n"));
-			break;
-		case SOUND_MIXER_STEREODEVS:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_STEREODEVS:\n"));
-			break;
-		case SOUND_MIXER_CAPS:
-			CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_CAPS:\n"));
-			break;
-		default:
-			i = _IOC_NR(x);
-			if (i >= SOUND_MIXER_NRDEVICES
-			    || !(vidx = mixtable1[i])) {
-				CS_DBGOUT(CS_IOCTL, 4, printk
-					("UNKNOWN IOCTL: 0x%.8x NR=%d\n",
-						x, i));
-			} else {
-				CS_DBGOUT(CS_IOCTL, 4, printk
-					("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n",
-						x, i));
-			}
-			break;
-		}
-	}
-}
-#endif
-static int prog_dmabuf_adc(struct cs4281_state *s);
-static void prog_codec(struct cs4281_state *s, unsigned type);
-
-// --------------------------------------------------------------------- 
-//
-//              Hardware Interfaces For the CS4281
-//
-
-
-//******************************************************************************
-// "delayus()-- Delay for the specified # of microseconds.
-//******************************************************************************
-static void delayus(struct cs4281_state *s, u32 delay)
-{
-	u32 j;
-	if ((delay > 9999) && (s->pm.flags & CS4281_PM_IDLE)) {
-		j = (delay * HZ) / 1000000;	/* calculate delay in jiffies  */
-		if (j < 1)
-			j = 1;	/* minimum one jiffy. */
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(j);
-	} else
-		udelay(delay);
-	return;
-}
-
-
-//******************************************************************************
-// "cs4281_read_ac97" -- Reads a word from the specified location in the
-//               CS4281's address space(based on the BA0 register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register,
-//                                            0h for reads.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
-// 5. if DCV not cleared, break and return error
-// 6. Read ACSTS = Status Register = 464h, check VSTS bit
-//****************************************************************************
-static int cs4281_read_ac97(struct cs4281_state *card, u32 offset,
-			    u32 * value)
-{
-	u32 count, status;
-
-	// Make sure that there is not data sitting
-	// around from a previous uncompleted access.
-	// ACSDA = Status Data Register = 47Ch
-	status = readl(card->pBA0 + BA0_ACSDA);
-
-	// Setup the AC97 control registers on the CS4281 to send the
-	// appropriate command to the AC97 to perform the read.
-	// ACCAD = Command Address Register = 46Ch
-	// ACCDA = Command Data Register = 470h
-	// ACCTL = Control Register = 460h
-	// bit DCV - will clear when process completed
-	// bit CRW - Read command
-	// bit VFRM - valid frame enabled
-	// bit ESYN - ASYNC generation enabled
-
-	// Get the actual AC97 register from the offset
-	writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-	writel(0, card->pBA0 + BA0_ACCDA);
-	writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN,
-	       card->pBA0 + BA0_ACCTL);
-
-	// Wait for the read to occur.
-	for (count = 0; count < 10; count++) {
-		// First, we want to wait for a short time.
-		udelay(25);
-
-		// Now, check to see if the read has completed.
-		// ACCTL = 460h, DCV should be reset by now and 460h = 17h
-		if (!(readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV))
-			break;
-	}
-
-	// Make sure the read completed.
-	if (readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV)
-		return 1;
-
-	// Wait for the valid status bit to go active.
-	for (count = 0; count < 10; count++) {
-		// Read the AC97 status register.
-		// ACSTS = Status Register = 464h
-		status = readl(card->pBA0 + BA0_ACSTS);
-
-		// See if we have valid status.
-		// VSTS - Valid Status
-		if (status & ACSTS_VSTS)
-			break;
-		// Wait for a short while.
-		udelay(25);
-	}
-
-	// Make sure we got valid status.
-	if (!(status & ACSTS_VSTS))
-		return 1;
-
-	// Read the data returned from the AC97 register.
-	// ACSDA = Status Data Register = 474h
-	*value = readl(card->pBA0 + BA0_ACSDA);
-
-	// Success.
-	return (0);
-}
-
-
-//****************************************************************************
-//
-// "cs4281_write_ac97()"-- writes a word to the specified location in the
-// CS461x's address space (based on the part's base address zero register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
-// 5. if DCV not cleared, break and return error
-//
-//****************************************************************************
-static int cs4281_write_ac97(struct cs4281_state *card, u32 offset,
-			     u32 value)
-{
-	u32 count, status=0;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs_4281_write_ac97()+ \n"));
-
-	// Setup the AC97 control registers on the CS4281 to send the
-	// appropriate command to the AC97 to perform the read.
-	// ACCAD = Command Address Register = 46Ch
-	// ACCDA = Command Data Register = 470h
-	// ACCTL = Control Register = 460h
-	// set DCV - will clear when process completed
-	// reset CRW - Write command
-	// set VFRM - valid frame enabled
-	// set ESYN - ASYNC generation enabled
-	// set RSTN - ARST# inactive, AC97 codec not reset
-
-	// Get the actual AC97 register from the offset
-
-	writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-	writel(value, card->pBA0 + BA0_ACCDA);
-	writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN,
-	       card->pBA0 + BA0_ACCTL);
-
-	// Wait for the write to occur.
-	for (count = 0; count < 100; count++) {
-		// First, we want to wait for a short time.
-		udelay(25);
-		// Now, check to see if the write has completed.
-		// ACCTL = 460h, DCV should be reset by now and 460h = 07h
-		status = readl(card->pBA0 + BA0_ACCTL);
-		if (!(status & ACCTL_DCV))
-			break;
-	}
-
-	// Make sure the write completed.
-	if (status & ACCTL_DCV) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-	      		"cs4281: cs_4281_write_ac97()- unable to write. ACCTL_DCV active\n"));
-		return 1;
-	}
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs_4281_write_ac97()- 0\n"));
-	// Success.
-	return 0;
-}
-
-
-//******************************************************************************
-// "Init4281()" -- Bring up the part.
-//******************************************************************************
-static __devinit int cs4281_hw_init(struct cs4281_state *card)
-{
-	u32 ac97_slotid;
-	u32 temp1, temp2;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs4281_hw_init()+ \n"));
-#ifndef NOT_CS4281_PM
-	if(!card)
-		return 1;
-#endif
-	temp2 = readl(card->pBA0 + BA0_CFLR);
-	CS_DBGOUT(CS_INIT | CS_ERROR | CS_PARMS, 4, printk(KERN_INFO 
-		"cs4281: cs4281_hw_init() CFLR 0x%x\n", temp2));
-	if(temp2 != CS4281_CFLR_DEFAULT)
-	{
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
-			"cs4281: cs4281_hw_init() CFLR invalid - resetting from 0x%x to 0x%x\n",
-				temp2,CS4281_CFLR_DEFAULT));
-		writel(CS4281_CFLR_DEFAULT, card->pBA0 + BA0_CFLR);
-		temp2 = readl(card->pBA0 + BA0_CFLR);
-		if(temp2 != CS4281_CFLR_DEFAULT)
-		{
-			CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
-				"cs4281: cs4281_hw_init() Invalid hardware - unable to configure CFLR\n"));
-			return 1;
-		}
-	}
-
-	//***************************************7
-	//  Set up the Sound System Configuration
-	//***************************************
-
-	// Set the 'Configuration Write Protect' register
-	// to 4281h.  Allows vendor-defined configuration
-	// space between 0e4h and 0ffh to be written.
-
-	writel(0x4281, card->pBA0 + BA0_CWPR);	// (3e0h)
-
-	// (0), Blast the clock control register to zero so that the
-	// PLL starts out in a known state, and blast the master serial
-	// port control register to zero so that the serial ports also
-	// start out in a known state.
-
-	writel(0, card->pBA0 + BA0_CLKCR1);	// (400h)
-	writel(0, card->pBA0 + BA0_SERMC);	// (420h)
-
-
-	// (1), Make ESYN go to zero to turn off
-	// the Sync pulse on the AC97 link.
-
-	writel(0, card->pBA0 + BA0_ACCTL);
-	udelay(50);
-
-
-	// (2) Drive the ARST# pin low for a minimum of 1uS (as defined in
-	// the AC97 spec) and then drive it high.  This is done for non
-	// AC97 modes since there might be logic external to the CS461x
-	// that uses the ARST# line for a reset.
-
-	writel(0, card->pBA0 + BA0_SPMC);	// (3ech)
-	udelay(100);
-	writel(SPMC_RSTN, card->pBA0 + BA0_SPMC);
-	delayus(card,50000);		// Wait 50 ms for ABITCLK to become stable.
-
-	// (3) Turn on the Sound System Clocks.
-	writel(CLKCR1_PLLP, card->pBA0 + BA0_CLKCR1);	// (400h)
-	delayus(card,50000);		// Wait for the PLL to stabilize.
-	// Turn on clocking of the core (CLKCR1(400h) = 0x00000030)
-	writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0 + BA0_CLKCR1);
-
-	// (4) Power on everything for now..
-	writel(0x7E, card->pBA0 + BA0_SSPM);	// (740h)
-
-	// (5) Wait for clock stabilization.
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		udelay(1000);
-		if (readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)
-			break;
-	}
-	if (!(readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR 
-			"cs4281: DLLRDY failed!\n"));
-		return -EIO;
-	}
-	// (6) Enable ASYNC generation.
-	writel(ACCTL_ESYN, card->pBA0 + BA0_ACCTL);	// (460h)
-
-	// Now wait 'for a short while' to allow the  AC97
-	// part to start generating bit clock. (so we don't
-	// Try to start the PLL without an input clock.)
-	delayus(card,50000);
-
-	// Set the serial port timing configuration, so that the
-	// clock control circuit gets its clock from the right place.
-	writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC);	// (420h)=2.
-
-	// (7) Wait for the codec ready signal from the AC97 codec.
-
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		// Delay a mil to let things settle out and
-		// to prevent retrying the read too quickly.
-		udelay(1000);
-		if (readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY)	// If ready,  (464h)
-			break;	//   exit the 'for' loop.
-	}
-	if (!(readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY))	// If never came ready,
-	{
-		CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
-			 "cs4281: ACSTS never came ready!\n"));
-		return -EIO;	//   exit initialization.
-	}
-	// (8) Assert the 'valid frame' signal so we can
-	// begin sending commands to the AC97 codec.
-	writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0 + BA0_ACCTL);	// (460h)
-
-	// (9), Wait until CODEC calibration is finished.
-	// Print an error message if it doesn't.
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		delayus(card,10000);
-		// Read the AC97 Powerdown Control/Status Register.
-		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2);
-		if ((temp2 & 0x0000000F) == 0x0000000F)
-			break;
-	}
-	if ((temp2 & 0x0000000F) != 0x0000000F) {
-		CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
-			"cs4281: Codec failed to calibrate.  Status = %.8x.\n",
-				temp2));
-		return -EIO;
-	}
-	// (10), Set the serial port timing configuration, so that the
-	// clock control circuit gets its clock from the right place.
-	writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC);	// (420h)=2.
-
-
-	// (11) Wait until we've sampled input slots 3 & 4 as valid, meaning
-	// that the codec is pumping ADC data across the AC link.
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		// Delay a mil to let things settle out and
-		// to prevent retrying the read too quickly.
-		delayus(card,1000);	//(test)
-
-		// Read the input slot valid register;  See
-		// if input slots 3 and 4 are valid yet.
-		if (
-		    (readl(card->pBA0 + BA0_ACISV) &
-		     (ACISV_ISV3 | ACISV_ISV4)) ==
-		    (ACISV_ISV3 | ACISV_ISV4)) break;	// Exit the 'for' if slots are valid.
-	}
-	// If we never got valid data, exit initialization.
-	if ((readl(card->pBA0 + BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4))
-	    != (ACISV_ISV3 | ACISV_ISV4)) {
-		CS_DBGOUT(CS_FUNCTION, 2,
-			  printk(KERN_ERR
-				 "cs4281: Never got valid data!\n"));
-		return -EIO;	// If no valid data, exit initialization.
-	}
-	// (12), Start digital data transfer of audio data to the codec.
-	writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0 + BA0_ACOSV);	// (468h)
-
-
-	//**************************************
-	// Unmute the Master and Alternate
-	// (headphone) volumes.  Set to max.
-	//**************************************
-	cs4281_write_ac97(card, BA0_AC97_HEADPHONE_VOLUME, 0);
-	cs4281_write_ac97(card, BA0_AC97_MASTER_VOLUME, 0);
-
-	//******************************************
-	// Power on the DAC(AddDACUser()from main())
-	//******************************************
-	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-	cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfdff);
-
-	// Wait until we sample a DAC ready state.
-	for (temp2 = 0; temp2 < 32; temp2++) {
-		// Let's wait a mil to let things settle.
-		delayus(card,1000);
-		// Read the current state of the power control reg.
-		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-		// If the DAC ready state bit is set, stop waiting.
-		if (temp1 & 0x2)
-			break;
-	}
-
-	//******************************************
-	// Power on the ADC(AddADCUser()from main())
-	//******************************************
-	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-	cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff);
-
-	// Wait until we sample ADC ready state.
-	for (temp2 = 0; temp2 < 32; temp2++) {
-		// Let's wait a mil to let things settle.
-		delayus(card,1000);
-		// Read the current state of the power control reg.
-		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-		// If the ADC ready state bit is set, stop waiting.
-		if (temp1 & 0x1)
-			break;
-	}
-	// Set up 4281 Register contents that
-	// don't change for boot duration.
-
-	// For playback, we map AC97 slot 3 and 4(Left
-	// & Right PCM playback) to DMA Channel 0.
-	// Set the fifo to be 15 bytes at offset zero.
-
-	ac97_slotid = 0x01000f00;	// FCR0.RS[4:0]=1(=>slot4, right PCM playback).
-	// FCR0.LS[4:0]=0(=>slot3, left PCM playback).
-	// FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0.
-	writel(ac97_slotid, card->pBA0 + BA0_FCR0);	// (180h)
-	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0);	// Turn on FIFO Enable.
-
-	// For capture, we map AC97 slot 10 and 11(Left
-	// and Right PCM Record) to DMA Channel 1.
-	// Set the fifo to be 15 bytes at offset sixteen.
-	ac97_slotid = 0x0B0A0f10;	// FCR1.RS[4:0]=11(=>slot11, right PCM record).
-	// FCR1.LS[4:0]=10(=>slot10, left PCM record).
-	// FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16.
-	writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1);	// (184h)
-	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1);	// Turn on FIFO Enable.
-
-	// Map the Playback SRC to the same AC97 slots(3 & 4--
-	// --Playback left & right)as DMA channel 0.
-	// Map the record SRC to the same AC97 slots(10 & 11--
-	// -- Record left & right) as DMA channel 1.
-
-	ac97_slotid = 0x0b0a0100;	// SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback).
-	// SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback).
-	// SCRSA.CRSS[4:0]=11(=>slot11, right PCM record)
-	// SCRSA.CLSS[4:0]=10(=>slot10, left PCM record).
-	writel(ac97_slotid, card->pBA0 + BA0_SRCSA);	// (75ch)
-
-	// Set 'Half Terminal Count Interrupt Enable' and 'Terminal
-	// Count Interrupt Enable' in DMA Control Registers 0 & 1.
-	// Set 'MSK' flag to 1 to keep the DMA engines paused.
-	temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);	// (00030001h)
-	writel(temp1, card->pBA0 + BA0_DCR0);	// (154h
-	writel(temp1, card->pBA0 + BA0_DCR1);	// (15ch)
-
-	// Set 'Auto-Initialize Control' to 'enabled'; For playback,
-	// set 'Transfer Type Control'(TR[1:0]) to 'read transfer',
-	// for record, set Transfer Type Control to 'write transfer'.
-	// All other bits set to zero;  Some will be changed @ transfer start.
-	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);	// (20000018h)
-	writel(temp1, card->pBA0 + BA0_DMR0);	// (150h)
-	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE);	// (20000014h)
-	writel(temp1, card->pBA0 + BA0_DMR1);	// (158h)
-
-	// Enable DMA interrupts generally, and
-	// DMA0 & DMA1 interrupts specifically.
-	temp1 = readl(card->pBA0 + BA0_HIMR) & 0xfffbfcff;
-	writel(temp1, card->pBA0 + BA0_HIMR);
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs4281_hw_init()- 0\n"));
-	return 0;
-}
-
-#ifndef NOT_CS4281_PM
-static void printpm(struct cs4281_state *s)
-{
-	CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
-	CS_DBGOUT(CS_PM, 9, printk("flags:0x%x u32CLKCR1_SAVE: 0%x u32SSPMValue: 0x%x\n",
-		(unsigned)s->pm.flags,s->pm.u32CLKCR1_SAVE,s->pm.u32SSPMValue));
-	CS_DBGOUT(CS_PM, 9, printk("u32PPLVCvalue: 0x%x u32PPRVCvalue: 0x%x\n",
-		s->pm.u32PPLVCvalue,s->pm.u32PPRVCvalue));
-	CS_DBGOUT(CS_PM, 9, printk("u32FMLVCvalue: 0x%x u32FMRVCvalue: 0x%x\n",
-		s->pm.u32FMLVCvalue,s->pm.u32FMRVCvalue));
-	CS_DBGOUT(CS_PM, 9, printk("u32GPIORvalue: 0x%x u32JSCTLvalue: 0x%x\n",
-		s->pm.u32GPIORvalue,s->pm.u32JSCTLvalue));
-	CS_DBGOUT(CS_PM, 9, printk("u32SSCR: 0x%x u32SRCSA: 0x%x\n",
-		s->pm.u32SSCR,s->pm.u32SRCSA));
-	CS_DBGOUT(CS_PM, 9, printk("u32DacASR: 0x%x u32AdcASR: 0x%x\n",
-		s->pm.u32DacASR,s->pm.u32AdcASR));
-	CS_DBGOUT(CS_PM, 9, printk("u32DacSR: 0x%x u32AdcSR: 0x%x\n",
-		s->pm.u32DacSR,s->pm.u32AdcSR));
-	CS_DBGOUT(CS_PM, 9, printk("u32MIDCR_Save: 0x%x\n",
-		s->pm.u32MIDCR_Save));
-
-}
-static void printpipe(struct cs4281_pipeline *pl)
-{
-
-	CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
-	CS_DBGOUT(CS_PM, 9, printk("flags:0x%x number: 0%x\n",
-		(unsigned)pl->flags,pl->number));
-	CS_DBGOUT(CS_PM, 9, printk("u32DBAnValue: 0%x u32DBCnValue: 0x%x\n",
-		pl->u32DBAnValue,pl->u32DBCnValue));
-	CS_DBGOUT(CS_PM, 9, printk("u32DMRnValue: 0x%x u32DCRnValue: 0x%x\n",
-		pl->u32DMRnValue,pl->u32DCRnValue));
-	CS_DBGOUT(CS_PM, 9, printk("u32DBAnAddress: 0x%x u32DBCnAddress: 0x%x\n",
-		pl->u32DBAnAddress,pl->u32DBCnAddress));
-	CS_DBGOUT(CS_PM, 9, printk("u32DCAnAddress: 0x%x u32DCCnAddress: 0x%x\n",
-		pl->u32DCCnAddress,pl->u32DCCnAddress));
-	CS_DBGOUT(CS_PM, 9, printk("u32DMRnAddress: 0x%x u32DCRnAddress: 0x%x\n",
-		pl->u32DMRnAddress,pl->u32DCRnAddress));
-	CS_DBGOUT(CS_PM, 9, printk("u32HDSRnAddress: 0x%x u32DBAn_Save: 0x%x\n",
-		pl->u32HDSRnAddress,pl->u32DBAn_Save));
-	CS_DBGOUT(CS_PM, 9, printk("u32DBCn_Save: 0x%x u32DMRn_Save: 0x%x\n",
-		pl->u32DBCn_Save,pl->u32DMRn_Save));
-	CS_DBGOUT(CS_PM, 9, printk("u32DCRn_Save: 0x%x u32DCCn_Save: 0x%x\n",
-		pl->u32DCRn_Save,pl->u32DCCn_Save));
-	CS_DBGOUT(CS_PM, 9, printk("u32DCAn_Save: 0x%x\n",
-		pl->u32DCAn_Save));
-	CS_DBGOUT(CS_PM, 9, printk("u32FCRn_Save: 0x%x u32FSICn_Save: 0x%x\n",
-		pl->u32FCRn_Save,pl->u32FSICn_Save));
-	CS_DBGOUT(CS_PM, 9, printk("u32FCRnValue: 0x%x u32FSICnValue: 0x%x\n",
-		pl->u32FCRnValue,pl->u32FSICnValue));
-	CS_DBGOUT(CS_PM, 9, printk("u32FCRnAddress: 0x%x u32FSICnAddress: 0x%x\n",
-		pl->u32FCRnAddress,pl->u32FSICnAddress));
-	CS_DBGOUT(CS_PM, 9, printk("u32FPDRnValue: 0x%x u32FPDRnAddress: 0x%x\n",
-		pl->u32FPDRnValue,pl->u32FPDRnAddress));
-}
-static void printpipelines(struct cs4281_state *s)
-{
-	int i;
-	for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
-	{
-		if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-		{
-			printpipe(&s->pl[i]);
-		}
-	}
-}
-/****************************************************************************
-*
-*  Suspend - save the ac97 regs, mute the outputs and power down the part.  
-*
-****************************************************************************/
-static void cs4281_ac97_suspend(struct cs4281_state *s)
-{
-	int Count,i;
-
-	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()+\n"));
-/*
-* change the state, save the current hwptr, then stop the dac/adc
-*/
-	s->pm.flags &= ~CS4281_PM_IDLE;
-	s->pm.flags |= CS4281_PM_SUSPENDING;
-	s->pm.u32hwptr_playback = readl(s->pBA0 + BA0_DCA0);
-	s->pm.u32hwptr_capture = readl(s->pBA0 + BA0_DCA1);
-	stop_dac(s);
-	stop_adc(s);
-
-	for(Count = 0x2, i=0; (Count <= CS4281_AC97_HIGHESTREGTORESTORE)
-			&& (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
-		Count += 2, i++)
-	{
-		cs4281_read_ac97(s, BA0_AC97_RESET + Count, &s->pm.ac97[i]);
-	}
-/*
-* Save the ac97 volume registers as well as the current powerdown state.
-* Now, mute the all the outputs (master, headphone, and mono), as well
-* as the PCM volume, in preparation for powering down the entire part.
-*/ 
-	cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME, &s->pm.u32AC97_master_volume);
-	cs4281_read_ac97(s, BA0_AC97_HEADPHONE_VOLUME, &s->pm.u32AC97_headphone_volume);
-	cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, &s->pm.u32AC97_master_volume_mono);
-	cs4281_read_ac97(s, BA0_AC97_PCM_OUT_VOLUME, &s->pm.u32AC97_pcm_out_volume);
-		
-	cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, 0x8000);
-	cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, 0x8000);
-	cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, 0x8000);
-	cs4281_write_ac97(s, BA0_AC97_PCM_OUT_VOLUME, 0x8000);
-
-	cs4281_read_ac97(s, BA0_AC97_POWERDOWN, &s->pm.u32AC97_powerdown);
-	cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, &s->pm.u32AC97_general_purpose);
-
-/*
-* And power down everything on the AC97 codec.
-*/
-	cs4281_write_ac97(s, BA0_AC97_POWERDOWN, 0xff00);
-	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()-\n"));
-}
-
-/****************************************************************************
-*
-*  Resume - power up the part and restore its registers..  
-*
-****************************************************************************/
-static void cs4281_ac97_resume(struct cs4281_state *s)
-{
-	int Count,i;
-
-	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()+\n"));
-
-/* do not save the power state registers at this time
-    //
-    // If we saved away the power control registers, write them into the
-    // shadows so those saved values get restored instead of the current
-    // shadowed value.
-    //
-    if( bPowerStateSaved )
-    {
-        PokeShadow( 0x26, ulSaveReg0x26 );
-        bPowerStateSaved = FALSE;
-    }
-*/
-
-//
-// First, we restore the state of the general purpose register.  This
-// contains the mic select (mic1 or mic2) and if we restore this after
-// we restore the mic volume/boost state and mic2 was selected at
-// suspend time, we will end up with a brief period of time where mic1
-// is selected with the volume/boost settings for mic2, causing
-// acoustic feedback.  So we restore the general purpose register
-// first, thereby getting the correct mic selected before we restore
-// the mic volume/boost.
-//
-	cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE, s->pm.u32AC97_general_purpose);
-
-//
-// Now, while the outputs are still muted, restore the state of power
-// on the AC97 part.
-//
-	cs4281_write_ac97(s, BA0_AC97_POWERDOWN, s->pm.u32AC97_powerdown);
-
-/*
-* Restore just the first set of registers, from register number
-* 0x02 to the register number that ulHighestRegToRestore specifies.
-*/
-	for(	Count = 0x2, i=0; 
-		(Count <= CS4281_AC97_HIGHESTREGTORESTORE)
-			&& (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
-		Count += 2, i++)
-	{
-		cs4281_write_ac97(s, BA0_AC97_RESET + Count, s->pm.ac97[i]);
-	}
-	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()-\n"));
-}
-
-/* do not save the power state registers at this time
-****************************************************************************
-*
-*  SavePowerState - Save the power registers away. 
-*
-****************************************************************************
-void 
-HWAC97codec::SavePowerState(void)
-{
-    ENTRY(TM_OBJECTCALLS, "HWAC97codec::SavePowerState()\r\n");
-
-    ulSaveReg0x26 = PeekShadow(0x26);
-
-    //
-    // Note that we have saved registers that need to be restored during a
-    // resume instead of ulAC97Regs[].
-    //
-    bPowerStateSaved = TRUE;
-
-} // SavePowerState
-*/
-
-static void cs4281_SuspendFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
- /*
- * We need to save the contents of the BASIC FIFO Registers.
- */
-	pl->u32FCRn_Save = readl(s->pBA0 + pl->u32FCRnAddress);
-	pl->u32FSICn_Save = readl(s->pBA0 + pl->u32FSICnAddress);
-}
-static void cs4281_ResumeFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
- /*
- * We need to restore the contents of the BASIC FIFO Registers.
- */
-	writel(pl->u32FCRn_Save,s->pBA0 + pl->u32FCRnAddress);
-	writel(pl->u32FSICn_Save,s->pBA0 + pl->u32FSICnAddress);
-}
-static void cs4281_SuspendDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
-	//
-	// We need to save the contents of the BASIC DMA Registers.
-	//
-	pl->u32DBAn_Save = readl(s->pBA0 + pl->u32DBAnAddress);
-	pl->u32DBCn_Save = readl(s->pBA0 + pl->u32DBCnAddress);
-	pl->u32DMRn_Save = readl(s->pBA0 + pl->u32DMRnAddress);
-	pl->u32DCRn_Save = readl(s->pBA0 + pl->u32DCRnAddress);
-	pl->u32DCCn_Save = readl(s->pBA0 + pl->u32DCCnAddress);
-	pl->u32DCAn_Save = readl(s->pBA0 + pl->u32DCAnAddress);
-}
-static void cs4281_ResumeDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
-	//
-	// We need to save the contents of the BASIC DMA Registers.
-	//
-	writel( pl->u32DBAn_Save, s->pBA0 + pl->u32DBAnAddress);
-	writel( pl->u32DBCn_Save, s->pBA0 + pl->u32DBCnAddress);
-	writel( pl->u32DMRn_Save, s->pBA0 + pl->u32DMRnAddress);
-	writel( pl->u32DCRn_Save, s->pBA0 + pl->u32DCRnAddress);
-	writel( pl->u32DCCn_Save, s->pBA0 + pl->u32DCCnAddress);
-	writel( pl->u32DCAn_Save, s->pBA0 + pl->u32DCAnAddress);
-}
-
-static int cs4281_suspend(struct cs4281_state *s)
-{
-	int i;
-	u32 u32CLKCR1;
-	struct cs4281_pm *pm = &s->pm;
-	CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
-		printk("cs4281: cs4281_suspend()+ flags=%d\n",
-			(unsigned)s->pm.flags));
-/*
-* check the current state, only suspend if IDLE
-*/
-	if(!(s->pm.flags & CS4281_PM_IDLE))
-	{
-		CS_DBGOUT(CS_PM | CS_ERROR, 2, 
-			printk("cs4281: cs4281_suspend() unable to suspend, not IDLE\n"));
-		return 1;
-	}
-	s->pm.flags &= ~CS4281_PM_IDLE;
-	s->pm.flags |= CS4281_PM_SUSPENDING;
-
-//
-// Gershwin CLKRUN - Set CKRA
-//
-	u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-
-	pm->u32CLKCR1_SAVE = u32CLKCR1;
-	if(!(u32CLKCR1 & 0x00010000 ) )
-		writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
-
-//
-// First, turn on the clocks (yikes) to the devices, so that they will
-// respond when we try to save their state.
-//
-	if(!(u32CLKCR1 & CLKCR1_SWCE))
-	{
-		writel(u32CLKCR1 | CLKCR1_SWCE , s->pBA0 + BA0_CLKCR1);
-	}
-    
-	//
-	// Save the power state
-	//
-	pm->u32SSPMValue = readl(s->pBA0 + BA0_SSPM);
-
-	//
-	// Disable interrupts.
-	//
-	writel(HICR_CHGM, s->pBA0 + BA0_HICR);
-
-	//
-	// Save the PCM Playback Left and Right Volume Control.
-	//
-	pm->u32PPLVCvalue = readl(s->pBA0 + BA0_PPLVC);
-	pm->u32PPRVCvalue = readl(s->pBA0 + BA0_PPRVC);
-
-	//
-	// Save the FM Synthesis Left and Right Volume Control.
-	//
-	pm->u32FMLVCvalue = readl(s->pBA0 + BA0_FMLVC);
-	pm->u32FMRVCvalue = readl(s->pBA0 + BA0_FMRVC);
-
-	//
-	// Save the GPIOR value.
-	//
-	pm->u32GPIORvalue = readl(s->pBA0 + BA0_GPIOR);
-
-	//
-	// Save the JSCTL value.
-	//
-	pm->u32JSCTLvalue = readl(s->pBA0 + BA0_GPIOR);
-
-	//
-	// Save Sound System Control Register
-	//
-	pm->u32SSCR = readl(s->pBA0 + BA0_SSCR);
-
-	//
-	// Save SRC Slot Assinment register
-	//
-	pm->u32SRCSA = readl(s->pBA0 + BA0_SRCSA);
-
-	//
-	// Save sample rate
-	//
-	pm->u32DacASR = readl(s->pBA0 + BA0_PASR);
-	pm->u32AdcASR = readl(s->pBA0 + BA0_CASR);
-	pm->u32DacSR = readl(s->pBA0 + BA0_DACSR);
-	pm->u32AdcSR = readl(s->pBA0 + BA0_ADCSR);
-
-	//
-	// Loop through all of the PipeLines 
-	//
-	for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
-        {
-		if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-		{
-		//
-		// Ask the DMAengines and FIFOs to Suspend.
-		//
-			cs4281_SuspendDMAengine(s,&s->pl[i]);
-			cs4281_SuspendFIFO(s,&s->pl[i]);
-		}
-	}
-	//
-	// We need to save the contents of the Midi Control Register.
-	//
-	pm->u32MIDCR_Save = readl(s->pBA0 + BA0_MIDCR);
-/*
-* save off the AC97 part information
-*/
-	cs4281_ac97_suspend(s);
-    
-	//
-	// Turn off the serial ports.
-	//
-	writel(0, s->pBA0 + BA0_SERMC);
-
-	//
-	// Power off FM, Joystick, AC link, 
-	//
-	writel(0, s->pBA0 + BA0_SSPM);
-
-	//
-	// DLL off.
-	//
-	writel(0, s->pBA0 + BA0_CLKCR1);
-
-	//
-	// AC link off.
-	//
-	writel(0, s->pBA0 + BA0_SPMC);
-
-	//
-	// Put the chip into D3(hot) state.
-	//
-	// PokeBA0(BA0_PMCS, 0x00000003);
-
-	//
-	// Gershwin CLKRUN - Clear CKRA
-	//
-	u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-	writel(u32CLKCR1 & 0xFFFEFFFF, s->pBA0 + BA0_CLKCR1);
-
-#ifdef CSDEBUG
-	printpm(s);
-	printpipelines(s);
-#endif
-
-	s->pm.flags &= ~CS4281_PM_SUSPENDING;
-	s->pm.flags |= CS4281_PM_SUSPENDED;
-
-	CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
-		printk("cs4281: cs4281_suspend()- flags=%d\n",
-			(unsigned)s->pm.flags));
-	return 0;
-}
-
-static int cs4281_resume(struct cs4281_state *s)
-{
-	int i;
-	unsigned temp1;
-	u32 u32CLKCR1;
-	struct cs4281_pm *pm = &s->pm;
-	CS_DBGOUT(CS_PM | CS_FUNCTION, 4, 
-		printk( "cs4281: cs4281_resume()+ flags=%d\n",
-			(unsigned)s->pm.flags));
-	if(!(s->pm.flags & CS4281_PM_SUSPENDED))
-	{
-		CS_DBGOUT(CS_PM | CS_ERROR, 2, 
-			printk("cs4281: cs4281_resume() unable to resume, not SUSPENDED\n"));
-		return 1;
-	}
-	s->pm.flags &= ~CS4281_PM_SUSPENDED;
-	s->pm.flags |= CS4281_PM_RESUMING;
-
-//
-// Gershwin CLKRUN - Set CKRA
-//
-	u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-	writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
-
-	//
-	// set the power state.
-	//
-	//old PokeBA0(BA0_PMCS, 0);
-
-	//
-	// Program the clock circuit and serial ports.
-	//
-	temp1 = cs4281_hw_init(s);
-	if (temp1) {
-		CS_DBGOUT(CS_ERROR | CS_INIT, 1,
-		    printk(KERN_ERR
-			"cs4281: resume cs4281_hw_init() error.\n"));
-		return -1;
-	}
-
-	//
-	// restore the Power state
-	//
-	writel(pm->u32SSPMValue, s->pBA0 + BA0_SSPM);
-
-	//
-	// Set post SRC mix setting (FM or ALT48K)
-	//
-	writel(pm->u32SSPM_BITS, s->pBA0 + BA0_SSPM);
-
-	//
-	// Loop through all of the PipeLines 
-	//
-	for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
-        {
-		if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-		{
-		//
-		// Ask the DMAengines and FIFOs to Resume.
-		//
-			cs4281_ResumeDMAengine(s,&s->pl[i]);
-			cs4281_ResumeFIFO(s,&s->pl[i]);
-		}
-	}
-	//
-	// We need to restore the contents of the Midi Control Register.
-	//
-	writel(pm->u32MIDCR_Save, s->pBA0 + BA0_MIDCR);
-
-	cs4281_ac97_resume(s);
-	//
-	// Restore the PCM Playback Left and Right Volume Control.
-	//
-	writel(pm->u32PPLVCvalue, s->pBA0 + BA0_PPLVC);
-	writel(pm->u32PPRVCvalue, s->pBA0 + BA0_PPRVC);
-
-	//
-	// Restore the FM Synthesis Left and Right Volume Control.
-	//
-	writel(pm->u32FMLVCvalue, s->pBA0 + BA0_FMLVC);
-	writel(pm->u32FMRVCvalue, s->pBA0 + BA0_FMRVC);
-
-	//
-	// Restore the JSCTL value.
-	//
-	writel(pm->u32JSCTLvalue, s->pBA0 + BA0_JSCTL);
-
-	//
-	// Restore the GPIOR register value.
-	//
-	writel(pm->u32GPIORvalue, s->pBA0 + BA0_GPIOR);
-
-	//
-	// Restore Sound System Control Register
-	//
-	writel(pm->u32SSCR, s->pBA0 + BA0_SSCR);
-
-	//
-	// Restore SRC Slot Assignment register
-	//
-	writel(pm->u32SRCSA, s->pBA0 + BA0_SRCSA);
-
-	//
-	// Restore sample rate
-	//
-	writel(pm->u32DacASR, s->pBA0 + BA0_PASR);
-	writel(pm->u32AdcASR, s->pBA0 + BA0_CASR);
-	writel(pm->u32DacSR, s->pBA0 + BA0_DACSR);
-	writel(pm->u32AdcSR, s->pBA0 + BA0_ADCSR);
-
-	// 
-	// Restore CFL1/2 registers we saved to compensate for OEM bugs.
-	//
-	//	PokeBA0(BA0_CFLR, ulConfig);
-
-	//
-	// Gershwin CLKRUN - Clear CKRA
-	//
-	writel(pm->u32CLKCR1_SAVE, s->pBA0 + BA0_CLKCR1);
-
-	//
-	// Enable interrupts on the part.
-	//
-	writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
-
-#ifdef CSDEBUG
-	printpm(s);
-	printpipelines(s);
-#endif
-/*
-* change the state, restore the current hwptrs, then stop the dac/adc
-*/
-	s->pm.flags |= CS4281_PM_IDLE;
-	s->pm.flags &= ~(CS4281_PM_SUSPENDING | CS4281_PM_SUSPENDED 
-			| CS4281_PM_RESUMING | CS4281_PM_RESUMED);
-
-	writel(s->pm.u32hwptr_playback, s->pBA0 + BA0_DCA0);
-	writel(s->pm.u32hwptr_capture, s->pBA0 + BA0_DCA1);
-	start_dac(s);
-	start_adc(s);
-
-	CS_DBGOUT(CS_PM | CS_FUNCTION, 9, printk("cs4281: cs4281_resume()- flags=%d\n",
-		(unsigned)s->pm.flags));
-	return 0;
-}
-
-#endif
-
-//******************************************************************************
-// "cs4281_play_rate()" --
-//******************************************************************************
-static void cs4281_play_rate(struct cs4281_state *card, u32 playrate)
-{
-	u32 DACSRvalue = 1;
-
-	// Based on the sample rate, program the DACSR register.
-	if (playrate == 8000)
-		DACSRvalue = 5;
-	if (playrate == 11025)
-		DACSRvalue = 4;
-	else if (playrate == 22050)
-		DACSRvalue = 2;
-	else if (playrate == 44100)
-		DACSRvalue = 1;
-	else if ((playrate <= 48000) && (playrate >= 6023))
-		DACSRvalue = 24576000 / (playrate * 16);
-	else if (playrate < 6023)
-		// Not allowed by open.
-		return;
-	else if (playrate > 48000)
-		// Not allowed by open.
-		return;
-	CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO
-		"cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n",
-			DACSRvalue, playrate));
-	//  Write the 'sample rate select code'
-	//  to the 'DAC Sample Rate' register.
-	writel(DACSRvalue, card->pBA0 + BA0_DACSR);	// (744h)
-}
-
-//******************************************************************************
-// "cs4281_record_rate()" -- Initialize the record sample rate converter.
-//******************************************************************************
-static void cs4281_record_rate(struct cs4281_state *card, u32 outrate)
-{
-	u32 ADCSRvalue = 1;
-
-	//
-	// Based on the sample rate, program the ADCSR register
-	//
-	if (outrate == 8000)
-		ADCSRvalue = 5;
-	if (outrate == 11025)
-		ADCSRvalue = 4;
-	else if (outrate == 22050)
-		ADCSRvalue = 2;
-	else if (outrate == 44100)
-		ADCSRvalue = 1;
-	else if ((outrate <= 48000) && (outrate >= 6023))
-		ADCSRvalue = 24576000 / (outrate * 16);
-	else if (outrate < 6023) {
-		// Not allowed by open.
-		return;
-	} else if (outrate > 48000) {
-		// Not allowed by open.
-		return;
-	}
-	CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO
-		"cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n",
-			ADCSRvalue, outrate));
-	//  Write the 'sample rate select code
-	//  to the 'ADC Sample Rate' register.
-	writel(ADCSRvalue, card->pBA0 + BA0_ADCSR);	// (748h)
-}
-
-
-
-static void stop_dac(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: stop_dac():\n"));
-	spin_lock_irqsave(&s->lock, flags);
-	s->ena &= ~FMODE_WRITE;
-	temp1 = readl(s->pBA0 + BA0_DCR0) | DCRn_MSK;
-	writel(temp1, s->pBA0 + BA0_DCR0);
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void start_dac(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: start_dac()+\n"));
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
-					(s->dma_dac.count > 0
-	    				&& s->dma_dac.ready))
-#ifndef NOT_CS4281_PM
-	&& (s->pm.flags & CS4281_PM_IDLE))
-#else
-)
-#endif
- {
-		s->ena |= FMODE_WRITE;
-		temp1 = readl(s->pBA0 + BA0_DCR0) & ~DCRn_MSK;	// Clear DMA0 channel mask.
-		writel(temp1, s->pBA0 + BA0_DCR0);	// Start DMA'ing.
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts.              
-
-		writel(7, s->pBA0 + BA0_PPRVC);
-		writel(7, s->pBA0 + BA0_PPLVC);
-		CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO
-			"cs4281: start_dac(): writel 0x%x start dma\n", temp1));
-
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION, 3,
-		  printk(KERN_INFO "cs4281: start_dac()-\n"));
-}
-
-
-static void stop_adc(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_FUNCTION, 3,
-		  printk(KERN_INFO "cs4281: stop_adc()+\n"));
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ena &= ~FMODE_READ;
-
-	if (s->conversion == 1) {
-		s->conversion = 0;
-		s->prop_adc.fmt = s->prop_adc.fmt_original;
-	}
-	temp1 = readl(s->pBA0 + BA0_DCR1) | DCRn_MSK;
-	writel(temp1, s->pBA0 + BA0_DCR1);
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION, 3,
-		  printk(KERN_INFO "cs4281: stop_adc()-\n"));
-}
-
-
-static void start_adc(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: start_adc()+\n"));
-
-	if (!(s->ena & FMODE_READ) &&
-	    (s->dma_adc.mapped || s->dma_adc.count <=
-	     (signed) (s->dma_adc.dmasize - 2 * s->dma_adc.fragsize))
-	    && s->dma_adc.ready
-#ifndef NOT_CS4281_PM
-	&& (s->pm.flags & CS4281_PM_IDLE))
-#else
-) 
-#endif
-	{
-		if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) {
-			// 
-			// now only use 16 bit capture, due to truncation issue
-			// in the chip, noticable distortion occurs.
-			// allocate buffer and then convert from 16 bit to 
-			// 8 bit for the user buffer.
-			//
-			s->prop_adc.fmt_original = s->prop_adc.fmt;
-			if (s->prop_adc.fmt & AFMT_S8) {
-				s->prop_adc.fmt &= ~AFMT_S8;
-				s->prop_adc.fmt |= AFMT_S16_LE;
-			}
-			if (s->prop_adc.fmt & AFMT_U8) {
-				s->prop_adc.fmt &= ~AFMT_U8;
-				s->prop_adc.fmt |= AFMT_U16_LE;
-			}
-			//
-			// prog_dmabuf_adc performs a stop_adc() but that is
-			// ok since we really haven't started the DMA yet.
-			//
-			prog_codec(s, CS_TYPE_ADC);
-
-			if (prog_dmabuf_adc(s) != 0) {
-				CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
-					 "cs4281: start_adc(): error in prog_dmabuf_adc\n"));
-			}
-			s->conversion = 1;
-		}
-		spin_lock_irqsave(&s->lock, flags);
-		s->ena |= FMODE_READ;
-		temp1 = readl(s->pBA0 + BA0_DCR1) & ~DCRn_MSK;	// Clear DMA1 channel mask bit.
-		writel(temp1, s->pBA0 + BA0_DCR1);	// Start recording
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts.
-		spin_unlock_irqrestore(&s->lock, flags);
-
-		CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO
-			 "cs4281: start_adc(): writel 0x%x \n", temp1));
-	}
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: start_adc()-\n"));
-
-}
-
-
-// --------------------------------------------------------------------- 
-
-#define DMABUF_MINORDER 1	// ==> min buffer size = 8K.
-
-
-static void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-	struct page *map, *mapend;
-
-	if (db->rawbuf) {
-		// Undo prog_dmabuf()'s marking the pages as reserved 
-		mapend =
-		    virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) -
-				 1);
-		for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-			ClearPageReserved(map);
-		free_dmabuf(s, db);
-	}
-	if (s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-		// Undo prog_dmabuf()'s marking the pages as reserved 
-		mapend =
-		    virt_to_page(s->tmpbuff +
-				 (PAGE_SIZE << s->buforder_tmpbuff) - 1);
-		for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-			ClearPageReserved(map);
-		free_dmabuf2(s, db);
-	}
-	s->tmpbuff = NULL;
-	db->rawbuf = NULL;
-	db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-	int order;
-	unsigned bytespersec, temp1;
-	unsigned bufs, sample_shift = 0;
-	struct page *map, *mapend;
-	unsigned long df;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_dmabuf()+\n"));
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error =
-	    db->endcleared = db->blocks = db->wakeup = db->underrun = 0;
-/*
-* check for order within limits, but do not overwrite value, check
-* later for a fractional defaultorder (i.e. 100+).
-*/
-	if((defaultorder > 0) && (defaultorder < 12))
-		df = defaultorder;
-	else
-		df = 1;	
-
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = df; order >= DMABUF_MINORDER; order--)
-			if ( (db->rawbuf = (void *) pci_alloc_consistent(
-				s->pcidev, PAGE_SIZE << order, &db-> dmaaddr)))
-				    break;
-		if (!db->rawbuf) {
-			CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-				"cs4281: prog_dmabuf(): unable to allocate rawbuf\n"));
-			return -ENOMEM;
-		}
-		db->buforder = order;
-		// Now mark the pages as reserved; otherwise the 
-		// remap_pfn_range() in cs4281_mmap doesn't work.
-		// 1. get index to last page in mem_map array for rawbuf.
-		mapend = virt_to_page(db->rawbuf + 
-			(PAGE_SIZE << db->buforder) - 1);
-
-		// 2. mark each physical page in range as 'reserved'.
-		for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-			SetPageReserved(map);
-	}
-	if (!s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-		for (order = df; order >= DMABUF_MINORDER;
-		     order--)
-			if ( (s->tmpbuff = (void *) pci_alloc_consistent(
-					s->pcidev, PAGE_SIZE << order, 
-					&s->dmaaddr_tmpbuff)))
-				    break;
-		if (!s->tmpbuff) {
-			CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-				"cs4281: prog_dmabuf(): unable to allocate tmpbuff\n"));
-			return -ENOMEM;
-		}
-		s->buforder_tmpbuff = order;
-		// Now mark the pages as reserved; otherwise the 
-		// remap_pfn_range() in cs4281_mmap doesn't work.
-		// 1. get index to last page in mem_map array for rawbuf.
-		mapend = virt_to_page(s->tmpbuff + 
-				(PAGE_SIZE << s->buforder_tmpbuff) - 1);
-
-		// 2. mark each physical page in range as 'reserved'.
-		for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-			SetPageReserved(map);
-	}
-	if (db->type == CS_TYPE_DAC) {
-		if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			sample_shift++;
-		if (s->prop_dac.channels > 1)
-			sample_shift++;
-		bytespersec = s->prop_dac.rate << sample_shift;
-	} else			// CS_TYPE_ADC
-	{
-		if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			sample_shift++;
-		if (s->prop_adc.channels > 1)
-			sample_shift++;
-		bytespersec = s->prop_adc.rate << sample_shift;
-	}
-	bufs = PAGE_SIZE << db->buforder;
-
-/*
-* added fractional "defaultorder" inputs. if >100 then use 
-* defaultorder-100 as power of 2 for the buffer size. example:
-* 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
-*/
-	if(defaultorder >= 100)
-	{
-		bufs = 1 << (defaultorder-100);
-	}
-
-#define INTERRUPT_RATE_MS       100	// Interrupt rate in milliseconds.
-	db->numfrag = 2;
-/* 
-* Nominal frag size(bytes/interrupt)
-*/
-	temp1 = bytespersec / (1000 / INTERRUPT_RATE_MS);
-	db->fragshift = 8;	// Min 256 bytes.
-	while (1 << db->fragshift < temp1)	// Calc power of 2 frag size.
-		db->fragshift += 1;
-	db->fragsize = 1 << db->fragshift;
-	db->dmasize = db->fragsize * 2;
-	db->fragsamples = db->fragsize >> sample_shift;	// # samples/fragment.
-
-// If the calculated size is larger than the allocated
-//  buffer, divide the allocated buffer into 2 fragments.
-	if (db->dmasize > bufs) {
-
-		db->numfrag = 2;	// Two fragments.
-		db->fragsize = bufs >> 1;	// Each 1/2 the alloc'ed buffer.
-		db->fragsamples = db->fragsize >> sample_shift;	// # samples/fragment.
-		db->dmasize = bufs;	// Use all the alloc'ed buffer.
-
-		db->fragshift = 0;	// Calculate 'fragshift'.
-		temp1 = db->fragsize;	// update_ptr() uses it 
-		while ((temp1 >>= 1) > 1)	// to calc 'total-bytes'
-			db->fragshift += 1;	// returned in DSP_GETI/OPTR. 
-	}
-	CS_DBGOUT(CS_PARMS, 3, printk(KERN_INFO
-		"cs4281: prog_dmabuf(): numfrag=%d fragsize=%d fragsamples=%d fragshift=%d bufs=%d fmt=0x%x ch=%d\n",
-			db->numfrag, db->fragsize, db->fragsamples, 
-			db->fragshift, bufs, 
-			(db->type == CS_TYPE_DAC) ? s->prop_dac.fmt : 
-				s->prop_adc.fmt, 
-			(db->type == CS_TYPE_DAC) ? s->prop_dac.channels : 
-				s->prop_adc.channels));
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_dmabuf()-\n"));
-	return 0;
-}
-
-
-static int prog_dmabuf_adc(struct cs4281_state *s)
-{
-	unsigned long va;
-	unsigned count;
-	int c;
-	stop_adc(s);
-	s->dma_adc.type = CS_TYPE_ADC;
-	if ((c = prog_dmabuf(s, &s->dma_adc)))
-		return c;
-
-	if (s->dma_adc.rawbuf) {
-		memset(s->dma_adc.rawbuf,
-		       (s->prop_adc.
-			fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-		       s->dma_adc.dmasize);
-	}
-	if (s->tmpbuff) {
-		memset(s->tmpbuff,
-		       (s->prop_adc.
-			fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-		       PAGE_SIZE << s->buforder_tmpbuff);
-	}
-
-	va = virt_to_bus(s->dma_adc.rawbuf);
-
-	count = s->dma_adc.dmasize;
-
-	if (s->prop_adc.
-	    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-		    count /= 2;	// 16-bit.
-
-	if (s->prop_adc.channels > 1)
-		count /= 2;	// Assume stereo.
-
-	CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO
-		"cs4281: prog_dmabuf_adc(): count=%d va=0x%.8x\n",
-			count, (unsigned) va));
-
-	writel(va, s->pBA0 + BA0_DBA1);	// Set buffer start address.
-	writel(count - 1, s->pBA0 + BA0_DBC1);	// Set count. 
-	s->dma_adc.ready = 1;
-	return 0;
-}
-
-
-static int prog_dmabuf_dac(struct cs4281_state *s)
-{
-	unsigned long va;
-	unsigned count;
-	int c;
-	stop_dac(s);
-	s->dma_dac.type = CS_TYPE_DAC;
-	if ((c = prog_dmabuf(s, &s->dma_dac)))
-		return c;
-	memset(s->dma_dac.rawbuf,
-	       (s->prop_dac.fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-	       s->dma_dac.dmasize);
-
-	va = virt_to_bus(s->dma_dac.rawbuf);
-
-	count = s->dma_dac.dmasize;
-	if (s->prop_dac.
-	    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-		    count /= 2;	// 16-bit.
-
-	if (s->prop_dac.channels > 1)
-		count /= 2;	// Assume stereo.
-
-	writel(va, s->pBA0 + BA0_DBA0);	// Set buffer start address.
-	writel(count - 1, s->pBA0 + BA0_DBC0);	// Set count.             
-
-	CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO
-		"cs4281: prog_dmabuf_dac(): count=%d va=0x%.8x\n",
-			count, (unsigned) va));
-
-	s->dma_dac.ready = 1;
-	return 0;
-}
-
-
-static void clear_advance(void *buf, unsigned bsize, unsigned bptr,
-			  unsigned len, unsigned char c)
-{
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(((char *) buf) + bptr, c, x);
-		bptr = 0;
-		len -= x;
-	}
-	CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
-		"cs4281: clear_advance(): memset %d at %p for %d size \n",
-			(unsigned)c, ((char *) buf) + bptr, len));
-	memset(((char *) buf) + bptr, c, len);
-}
-
-
-
-// call with spinlock held! 
-static void cs4281_update_ptr(struct cs4281_state *s, int intflag)
-{
-	int diff;
-	unsigned hwptr, va;
-
-	// update ADC pointer 
-	if (s->ena & FMODE_READ) {
-		hwptr = readl(s->pBA0 + BA0_DCA1);	// Read capture DMA address.
-		va = virt_to_bus(s->dma_adc.rawbuf);
-		hwptr -= (unsigned) va;
-		diff =
-		    (s->dma_adc.dmasize + hwptr -
-		     s->dma_adc.hwptr) % s->dma_adc.dmasize;
-		s->dma_adc.hwptr = hwptr;
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-		if (s->dma_adc.count > s->dma_adc.dmasize)
-			s->dma_adc.count = s->dma_adc.dmasize;
-		if (s->dma_adc.mapped) {
-			if (s->dma_adc.count >=
-			    (signed) s->dma_adc.fragsize) wake_up(&s->
-								  dma_adc.
-								  wait);
-		} else {
-			if (s->dma_adc.count > 0)
-				wake_up(&s->dma_adc.wait);
-		}
-		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-			"cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n",
-				s, s->dma_adc.hwptr, s->dma_adc.total_bytes, s->dma_adc.count));
-	}
-	// update DAC pointer 
-	//
-	// check for end of buffer, means that we are going to wait for another interrupt
-	// to allow silence to fill the fifos on the part, to keep pops down to a minimum.
-	//
-	if (s->ena & FMODE_WRITE) {
-		hwptr = readl(s->pBA0 + BA0_DCA0);	// Read play DMA address.
-		va = virt_to_bus(s->dma_dac.rawbuf);
-		hwptr -= (unsigned) va;
-		diff = (s->dma_dac.dmasize + hwptr -
-		     s->dma_dac.hwptr) % s->dma_dac.dmasize;
-		s->dma_dac.hwptr = hwptr;
-		s->dma_dac.total_bytes += diff;
-		if (s->dma_dac.mapped) {
-			s->dma_dac.count += diff;
-			if (s->dma_dac.count >= s->dma_dac.fragsize) {
-				s->dma_dac.wakeup = 1;
-				wake_up(&s->dma_dac.wait);
-				if (s->dma_dac.count > s->dma_dac.dmasize)
-					s->dma_dac.count &=
-					    s->dma_dac.dmasize - 1;
-			}
-		} else {
-			s->dma_dac.count -= diff;
-			if (s->dma_dac.count <= 0) {
-				//
-				// fill with silence, and do not shut down the DAC.
-				// Continue to play silence until the _release.
-				//
-				CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO
-					"cs4281: cs4281_update_ptr(): memset %d at %p for %d size \n",
-						(unsigned)(s->prop_dac.fmt & 
-						(AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, 
-						s->dma_dac.rawbuf, s->dma_dac.dmasize));
-				memset(s->dma_dac.rawbuf,
-				       (s->prop_dac.
-					fmt & (AFMT_U8 | AFMT_U16_LE)) ?
-				       0x80 : 0, s->dma_dac.dmasize);
-				if (s->dma_dac.count < 0) {
-					s->dma_dac.underrun = 1;
-					s->dma_dac.count = 0;
-					CS_DBGOUT(CS_ERROR, 9, printk(KERN_INFO
-					 "cs4281: cs4281_update_ptr(): underrun\n"));
-				}
-			} else if (s->dma_dac.count <=
-				   (signed) s->dma_dac.fragsize
-				   && !s->dma_dac.endcleared) {
-				clear_advance(s->dma_dac.rawbuf,
-					      s->dma_dac.dmasize,
-					      s->dma_dac.swptr,
-					      s->dma_dac.fragsize,
-					      (s->prop_dac.
-					       fmt & (AFMT_U8 |
-						      AFMT_U16_LE)) ? 0x80
-					      : 0);
-				s->dma_dac.endcleared = 1;
-			}
-			if ( (s->dma_dac.count <= (signed) s->dma_dac.dmasize/2) ||
-				intflag)
-			{
-				wake_up(&s->dma_dac.wait);
-			}
-		}
-		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-			"cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n",
-				s, s->dma_dac.hwptr, s->dma_dac.total_bytes, s->dma_dac.count));
-	}
-}
-
-
-// --------------------------------------------------------------------- 
-
-static void prog_codec(struct cs4281_state *s, unsigned type)
-{
-	unsigned long flags;
-	unsigned temp1, format;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_codec()+ \n"));
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (type == CS_TYPE_ADC) {
-		temp1 = readl(s->pBA0 + BA0_DCR1);
-		writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR1);	// Stop capture DMA, if active.
-
-		// program sampling rates  
-		// Note, for CS4281, capture & play rates can be set independently.
-		cs4281_record_rate(s, s->prop_adc.rate);
-
-		// program ADC parameters 
-		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
-		if (s->prop_adc.
-		    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {	// 16-bit
-			if (s->prop_adc.fmt & (AFMT_S16_BE | AFMT_U16_BE))	// Big-endian?
-				format |= DMRn_BEND;
-			if (s->prop_adc.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-				format |= DMRn_USIGN;	// Unsigned.      
-		} else
-			format |= DMRn_SIZE8 | DMRn_USIGN;	// 8-bit, unsigned
-		if (s->prop_adc.channels < 2)
-			format |= DMRn_MONO;
-
-		writel(format, s->pBA0 + BA0_DMR1);
-
-		CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-			"cs4281: prog_codec(): adc %s %s %s rate=%d DMR0 format=0x%.8x\n",
-				(format & DMRn_SIZE8) ? "8" : "16",
-				(format & DMRn_USIGN) ?  "Unsigned" : "Signed", 
-				(format & DMRn_MONO) ? "Mono" : "Stereo", 
-				s->prop_adc.rate, format));
-
-		s->ena &= ~FMODE_READ;	// not capturing data yet
-	}
-
-
-	if (type == CS_TYPE_DAC) {
-		temp1 = readl(s->pBA0 + BA0_DCR0);
-		writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR0);	// Stop play DMA, if active.
-
-		// program sampling rates  
-		// Note, for CS4281, capture & play rates can be set independently.
-		cs4281_play_rate(s, s->prop_dac.rate);
-
-		// program DAC parameters 
-		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ;
-		if (s->prop_dac.
-		    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {	// 16-bit
-			if (s->prop_dac.fmt & (AFMT_S16_BE | AFMT_U16_BE))
-				format |= DMRn_BEND;	// Big Endian.
-			if (s->prop_dac.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-				format |= DMRn_USIGN;	// Unsigned.      
-		} else
-			format |= DMRn_SIZE8 | DMRn_USIGN;	// 8-bit, unsigned
-
-		if (s->prop_dac.channels < 2)
-			format |= DMRn_MONO;
-
-		writel(format, s->pBA0 + BA0_DMR0);
-
-
-		CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-			"cs4281: prog_codec(): dac %s %s %s rate=%d DMR0 format=0x%.8x\n",
-				(format & DMRn_SIZE8) ? "8" : "16",
-				(format & DMRn_USIGN) ?  "Unsigned" : "Signed",
-				(format & DMRn_MONO) ? "Mono" : "Stereo", 
-				s->prop_dac.rate, format));
-
-		s->ena &= ~FMODE_WRITE;	// not capturing data yet
-
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_codec()- \n"));
-}
-
-
-static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
-		       unsigned long arg)
-{
-	// Index to mixer_src[] is value of AC97 Input Mux Select Reg.
-	// Value of array member is recording source Device ID Mask.
-	static const unsigned int mixer_src[8] = {
-		SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
-		SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
-	};
-	void __user *argp = (void __user *)arg;
-
-	// Index of mixtable1[] member is Device ID 
-	// and must be <= SOUND_MIXER_NRDEVICES.
-	// Value of array member is index into s->mix.vol[]
-	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-		[SOUND_MIXER_PCM] = 1,	// voice 
-		[SOUND_MIXER_LINE1] = 2,	// AUX
-		[SOUND_MIXER_CD] = 3,	// CD 
-		[SOUND_MIXER_LINE] = 4,	// Line 
-		[SOUND_MIXER_SYNTH] = 5,	// FM
-		[SOUND_MIXER_MIC] = 6,	// Mic 
-		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
-		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
-		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
-	};
-
-
-	static const unsigned mixreg[] = {
-		BA0_AC97_PCM_OUT_VOLUME,
-		BA0_AC97_AUX_VOLUME,
-		BA0_AC97_CD_VOLUME,
-		BA0_AC97_LINE_IN_VOLUME
-	};
-	unsigned char l, r, rl, rr, vidx;
-	unsigned char attentbl[11] =
-	    { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 };
-	unsigned temp1;
-	int i, val;
-
-	VALIDATE_STATE(s);
-	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
-		 "cs4281: mixer_ioctl(): s=%p cmd=0x%.8x\n", s, cmd));
-#if CSDEBUG
-	cs_printioctl(cmd);
-#endif
-#if CSDEBUG_INTERFACE
-
-	if ((cmd == SOUND_MIXER_CS_GETDBGMASK) ||
-	    (cmd == SOUND_MIXER_CS_SETDBGMASK) ||
-	    (cmd == SOUND_MIXER_CS_GETDBGLEVEL) ||
-	    (cmd == SOUND_MIXER_CS_SETDBGLEVEL) ||
-	    (cmd == SOUND_MIXER_CS_APM))
-	{
-		switch (cmd) {
-
-		case SOUND_MIXER_CS_GETDBGMASK:
-			return put_user(cs_debugmask,
-					(unsigned long __user *) argp);
-
-		case SOUND_MIXER_CS_GETDBGLEVEL:
-			return put_user(cs_debuglevel,
-					(unsigned long __user *) argp);
-
-		case SOUND_MIXER_CS_SETDBGMASK:
-			if (get_user(val, (unsigned long __user *) argp))
-				return -EFAULT;
-			cs_debugmask = val;
-			return 0;
-
-		case SOUND_MIXER_CS_SETDBGLEVEL:
-			if (get_user(val, (unsigned long __user *) argp))
-				return -EFAULT;
-			cs_debuglevel = val;
-			return 0;
-#ifndef NOT_CS4281_PM
-		case SOUND_MIXER_CS_APM:
-			if (get_user(val, (unsigned long __user *) argp))
-				return -EFAULT;
-			if(val == CS_IOCTL_CMD_SUSPEND)
-				cs4281_suspend(s);
-			else if(val == CS_IOCTL_CMD_RESUME)
-				cs4281_resume(s);
-			else
-			{
-				CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-				    "cs4281: mixer_ioctl(): invalid APM cmd (%d)\n",
-					val));
-			}
-			return 0;
-#endif
-		default:
-			CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-				"cs4281: mixer_ioctl(): ERROR unknown debug cmd\n"));
-			return 0;
-		}
-	}
-#endif
-
-	if (cmd == SOUND_MIXER_PRIVATE1) {
-		// enable/disable/query mixer preamp 
-		if (get_user(val, (int __user *) argp))
-			return -EFAULT;
-		if (val != -1) {
-			cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-			temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf);
-			cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-		}
-		cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-		val = (temp1 & 0x40) ? 1 : 0;
-		return put_user(val, (int __user *) argp);
-	}
-	if (cmd == SOUND_MIXER_PRIVATE2) {
-		// enable/disable/query spatializer 
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		if (val != -1) {
-			temp1 = (val & 0x3f) >> 2;
-			cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1);
-			cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-					 &temp1);
-			cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-					  temp1 | 0x2000);
-		}
-		cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
-		return put_user((temp1 << 2) | 3, (int __user *)argp);
-	}
-	if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		strlcpy(info.id, "CS4281", sizeof(info.id));
-		strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
-		info.modify_counter = s->mix.modcnt;
-		if (copy_to_user(argp, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == SOUND_OLD_MIXER_INFO) {
-		_old_mixer_info info;
-		strlcpy(info.id, "CS4281", sizeof(info.id));
-		strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
-		if (copy_to_user(argp, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, (int __user *) argp);
-
-	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-		return -EINVAL;
-
-	// If ioctl has only the SIOC_READ bit(bit 31)
-	// on, process the only-read commands. 
-	if (_SIOC_DIR(cmd) == _SIOC_READ) {
-		switch (_IOC_NR(cmd)) {
-		case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
-			cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT, &temp1);
-			return put_user(mixer_src[temp1&7], (int __user *)argp);
-
-		case SOUND_MIXER_DEVMASK:	// Arg contains a bit for each supported device 
-			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-					SOUND_MASK_CD | SOUND_MASK_LINE |
-					SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-					SOUND_MASK_VOLUME |
-					SOUND_MASK_RECLEV |
-					SOUND_MASK_SPEAKER, (int __user *)argp);
-
-		case SOUND_MIXER_RECMASK:	// Arg contains a bit for each supported recording source 
-			return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC |
-					SOUND_MASK_CD | SOUND_MASK_VOLUME |
-					SOUND_MASK_LINE1, (int __user *) argp);
-
-		case SOUND_MIXER_STEREODEVS:	// Mixer channels supporting stereo 
-			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-					SOUND_MASK_CD | SOUND_MASK_LINE |
-					SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-					SOUND_MASK_VOLUME |
-					SOUND_MASK_RECLEV, (int __user *)argp);
-
-		case SOUND_MIXER_CAPS:
-			return put_user(SOUND_CAP_EXCL_INPUT, (int __user *)argp);
-
-		default:
-			i = _IOC_NR(cmd);
-			if (i >= SOUND_MIXER_NRDEVICES
-			    || !(vidx = mixtable1[i]))
-				return -EINVAL;
-			return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
-		}
-	}
-	// If ioctl doesn't have both the SIOC_READ and 
-	// the SIOC_WRITE bit set, return invalid.
-	if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE))
-		return -EINVAL;
-
-	// Increment the count of volume writes.
-	s->mix.modcnt++;
-
-	// Isolate the command; it must be a write.
-	switch (_IOC_NR(cmd)) {
-
-	case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		i = hweight32(val);	// i = # bits on in val.
-		if (i != 1)	// One & only 1 bit must be on.
-			return 0;
-		for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) {
-			if (val == mixer_src[i]) {
-				temp1 = (i << 8) | i;
-				cs4281_write_ac97(s,
-						  BA0_AC97_RECORD_SELECT,
-						  temp1);
-				return 0;
-			}
-		}
-		return 0;
-
-	case SOUND_MIXER_VOLUME:
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;	// Max soundcard.h vol is 100.
-		if (l < 6) {
-			rl = 63;
-			l = 0;
-		} else
-			rl = attentbl[(10 * l) / 100];	// Convert 0-100 vol to 63-0 atten.
-
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;	// Max right volume is 100, too
-		if (r < 6) {
-			rr = 63;
-			r = 0;
-		} else
-			rr = attentbl[(10 * r) / 100];	// Convert volume to attenuation.
-
-		if ((rl > 60) && (rr > 60))	// If both l & r are 'low',          
-			temp1 = 0x8000;	//  turn on the mute bit.
-		else
-			temp1 = 0;
-
-		temp1 |= (rl << 8) | rr;
-
-		cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1);
-		cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[8] = ((unsigned int) r << 8) | l;
-#else
-		s->mix.vol[8] = val;
-#endif
-		return put_user(s->mix.vol[8], (int __user *)argp);
-
-	case SOUND_MIXER_SPEAKER:
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (l < 3) {
-			rl = 0;
-			l = 0;
-		} else {
-			rl = (l * 2 - 5) / 13;	// Convert 0-100 range to 0-15.
-			l = (rl * 13 + 5) / 2;
-		}
-
-		if (rl < 3) {
-			temp1 = 0x8000;
-			rl = 0;
-		} else
-			temp1 = 0;
-		rl = 15 - rl;	// Convert volume to attenuation.
-		temp1 |= rl << 1;
-		cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[6] = l << 8;
-#else
-		s->mix.vol[6] = val;
-#endif
-		return put_user(s->mix.vol[6], (int __user *)argp);
-
-	case SOUND_MIXER_RECLEV:
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;
-		rl = (l * 2 - 5) / 13;	// Convert 0-100 scale to 0-15.
-		rr = (r * 2 - 5) / 13;
-		if (rl < 3 && rr < 3)
-			temp1 = 0x8000;
-		else
-			temp1 = 0;
-
-		temp1 = temp1 | (rl << 8) | rr;
-		cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[7] = ((unsigned int) r << 8) | l;
-#else
-		s->mix.vol[7] = val;
-#endif
-		return put_user(s->mix.vol[7], (int __user *)argp);
-
-	case SOUND_MIXER_MIC:
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (l < 1) {
-			l = 0;
-			rl = 0;
-		} else {
-			rl = ((unsigned) l * 5 - 4) / 16;	// Convert 0-100 range to 0-31.
-			l = (rl * 16 + 4) / 5;
-		}
-		cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-		temp1 &= 0x40;	// Isolate 20db gain bit.
-		if (rl < 3) {
-			temp1 |= 0x8000;
-			rl = 0;
-		}
-		rl = 31 - rl;	// Convert volume to attenuation.
-		temp1 |= rl;
-		cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[5] = val << 8;
-#else
-		s->mix.vol[5] = val;
-#endif
-		return put_user(s->mix.vol[5], (int __user *)argp);
-
-
-	case SOUND_MIXER_SYNTH:
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;
-		rl = (l * 2 - 11) / 3;	// Convert 0-100 range to 0-63.
-		rr = (r * 2 - 11) / 3;
-		if (rl < 3)	// If l is low, turn on
-			temp1 = 0x0080;	//  the mute bit.
-		else
-			temp1 = 0;
-
-		rl = 63 - rl;	// Convert vol to attenuation.
-		writel(temp1 | rl, s->pBA0 + BA0_FMLVC);
-		if (rr < 3)	//  If rr is low, turn on
-			temp1 = 0x0080;	//   the mute bit.
-		else
-			temp1 = 0;
-		rr = 63 - rr;	// Convert vol to attenuation.
-		writel(temp1 | rr, s->pBA0 + BA0_FMRVC);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[4] = (r << 8) | l;
-#else
-		s->mix.vol[4] = val;
-#endif
-		return put_user(s->mix.vol[4], (int __user *)argp);
-
-
-	default:
-		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-			"cs4281: mixer_ioctl(): default\n"));
-
-		i = _IOC_NR(cmd);
-		if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-			return -EINVAL;
-		if (get_user(val, (int __user *)argp))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (l < 1) {
-			l = 0;
-			rl = 31;
-		} else
-			rl = (attentbl[(l * 10) / 100]) >> 1;
-
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;
-		if (r < 1) {
-			r = 0;
-			rr = 31;
-		} else
-			rr = (attentbl[(r * 10) / 100]) >> 1;
-		if ((rl > 30) && (rr > 30))
-			temp1 = 0x8000;
-		else
-			temp1 = 0;
-		temp1 = temp1 | (rl << 8) | rr;
-		cs4281_write_ac97(s, mixreg[vidx - 1], temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l;
-#else
-		s->mix.vol[vidx - 1] = val;
-#endif
-#ifndef NOT_CS4281_PM
-		CS_DBGOUT(CS_PM, 9, printk(KERN_INFO 
-			"write ac97 mixreg[%d]=0x%x mix.vol[]=0x%x\n", 
-				vidx-1,temp1,s->mix.vol[vidx-1]));
-#endif
-		return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
-	}
-}
-
-
-// --------------------------------------------------------------------- 
-
-static int cs4281_open_mixdev(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	struct cs4281_state *s=NULL;
-	struct list_head *entry;
-
-	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
-		  printk(KERN_INFO "cs4281: cs4281_open_mixdev()+\n"));
-
-	list_for_each(entry, &cs4281_devs)
-	{
-		s = list_entry(entry, struct cs4281_state, list);
-		if(s->dev_mixer == minor)
-			break;
-	}
-	if (!s)
-	{
-		CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
-			printk(KERN_INFO "cs4281: cs4281_open_mixdev()- -ENODEV\n"));
-		return -ENODEV;
-	}
-	VALIDATE_STATE(s);
-	file->private_data = s;
-
-	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
-		  printk(KERN_INFO "cs4281: cs4281_open_mixdev()- 0\n"));
-
-	return nonseekable_open(inode, file);
-}
-
-
-static int cs4281_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-
-	VALIDATE_STATE(s);
-	return 0;
-}
-
-
-static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file,
-			       unsigned int cmd, unsigned long arg)
-{
-	return mixer_ioctl((struct cs4281_state *) file->private_data, cmd,
-			   arg);
-}
-
-
-// ******************************************************************************************
-//   Mixer file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_mixer_fops = {
-	.owner	 = THIS_MODULE,
-	.llseek	 = no_llseek,
-	.ioctl	 = cs4281_ioctl_mixdev,
-	.open	 = cs4281_open_mixdev,
-	.release = cs4281_release_mixdev,
-};
-
-// --------------------------------------------------------------------- 
-
-
-static int drain_adc(struct cs4281_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count;
-	unsigned tmo;
-
-	if (s->dma_adc.mapped)
-		return 0;
-	add_wait_queue(&s->dma_adc.wait, &wait);
-	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_adc.count;
-		CS_DBGOUT(CS_FUNCTION, 2,
-			  printk(KERN_INFO "cs4281: drain_adc() %d\n", count));
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0) {
-			CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
-				 "cs4281: drain_adc() count<0\n"));
-			break;
-		}
-		if (signal_pending(current))
-			break;
-		if (nonblock) {
-			remove_wait_queue(&s->dma_adc.wait, &wait);
-			current->state = TASK_RUNNING;
-			return -EBUSY;
-		}
-		tmo =
-		    3 * HZ * (count +
-			      s->dma_adc.fragsize) / 2 / s->prop_adc.rate;
-		if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			tmo >>= 1;
-		if (s->prop_adc.channels > 1)
-			tmo >>= 1;
-		if (!schedule_timeout(tmo + 1))
-			printk(KERN_DEBUG "cs4281: dma timed out??\n");
-	}
-	remove_wait_queue(&s->dma_adc.wait, &wait);
-	current->state = TASK_RUNNING;
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-static int drain_dac(struct cs4281_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count;
-	unsigned tmo;
-
-	if (s->dma_dac.mapped)
-		return 0;
-	add_wait_queue(&s->dma_dac.wait, &wait);
-	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-			break;
-		if (nonblock) {
-			remove_wait_queue(&s->dma_dac.wait, &wait);
-			current->state = TASK_RUNNING;
-			return -EBUSY;
-		}
-		tmo =
-		    3 * HZ * (count +
-			      s->dma_dac.fragsize) / 2 / s->prop_dac.rate;
-		if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			tmo >>= 1;
-		if (s->prop_dac.channels > 1)
-			tmo >>= 1;
-		if (!schedule_timeout(tmo + 1))
-			printk(KERN_DEBUG "cs4281: dma timed out??\n");
-	}
-	remove_wait_queue(&s->dma_dac.wait, &wait);
-	current->state = TASK_RUNNING;
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-//****************************************************************************
-//
-// CopySamples copies 16-bit stereo samples from the source to the
-// destination, possibly converting down to either 8-bit or mono or both.
-// count specifies the number of output bytes to write.
-//
-//  Arguments:
-//
-//  dst             - Pointer to a destination buffer.
-//  src             - Pointer to a source buffer
-//  count           - The number of bytes to copy into the destination buffer.
-//  iChannels       - Stereo - 2
-//                    Mono   - 1
-//  fmt             - AFMT_xxx (soundcard.h formats)
-//
-// NOTES: only call this routine for conversion to 8bit from 16bit
-//
-//****************************************************************************
-static void CopySamples(char *dst, char *src, int count, int iChannels,
-			unsigned fmt)
-{
-
-	unsigned short *psSrc;
-	long lAudioSample;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: CopySamples()+ "));
-	CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-		 " dst=%p src=%p count=%d iChannels=%d fmt=0x%x\n",
-			 dst, src, (unsigned) count, (unsigned) iChannels, (unsigned) fmt));
-
-	// Gershwin does format conversion in hardware so normally
-	// we don't do any host based coversion. The data formatter
-	// truncates 16 bit data to 8 bit and that causes some hiss.
-	// We have already forced the HW to do 16 bit sampling and 
-	// 2 channel so that we can use software to round instead 
-	// of truncate
-
-	//
-	// See if the data should be output as 8-bit unsigned stereo.
-	// or if the data should be output at 8-bit unsigned mono.
-	//
-	if ( ((iChannels == 2) && (fmt & AFMT_U8)) ||
-		((iChannels == 1) && (fmt & AFMT_U8)) ) {
-		//
-		// Convert each 16-bit unsigned stereo sample to 8-bit unsigned 
-		// stereo using rounding.
-		//
-		psSrc = (unsigned short *) src;
-		count = count / 2;
-		while (count--) {
-			lAudioSample = (long) psSrc[count] + (long) 0x80;
-			if (lAudioSample > 0xffff) {
-				lAudioSample = 0xffff;
-			}
-			dst[count] = (char) (lAudioSample >> 8);
-		}
-	}
-	//
-	// check for 8-bit signed stereo.
-	//
-	else if ((iChannels == 2) && (fmt & AFMT_S8)) {
-		//
-		// Convert each 16-bit stereo sample to 8-bit stereo using rounding.
-		//
-		psSrc = (short *) src;
-		while (count--) {
-			lAudioSample =
-			    (((long) psSrc[0] + (long) psSrc[1]) / 2);
-			psSrc += 2;
-			*dst++ = (char) ((short) lAudioSample >> 8);
-		}
-	}
-	//
-	// Otherwise, the data should be output as 8-bit signed mono.
-	//
-	else if ((iChannels == 1) && (fmt & AFMT_S8)) {
-		//
-		// Convert each 16-bit signed mono sample to 8-bit signed mono 
-		// using rounding.
-		//
-		psSrc = (short *) src;
-		count = count / 2;
-		while (count--) {
-			lAudioSample =
-			    (((long) psSrc[0] + (long) psSrc[1]) / 2);
-			if (lAudioSample > 0x7fff) {
-				lAudioSample = 0x7fff;
-			}
-			psSrc += 2;
-			*dst++ = (char) ((short) lAudioSample >> 8);
-		}
-	}
-}
-
-//
-// cs_copy_to_user()
-// replacement for the standard copy_to_user, to allow for a conversion from
-// 16 bit to 8 bit if the record conversion is active.  the cs4281 has some
-// issues with 8 bit capture, so the driver always captures data in 16 bit
-// and then if the user requested 8 bit, converts from 16 to 8 bit.
-//
-static unsigned cs_copy_to_user(struct cs4281_state *s, void __user *dest,
-				unsigned *hwsrc, unsigned cnt,
-				unsigned *copied)
-{
-	void *src = hwsrc;	//default to the standard destination buffer addr
-
-	CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO
-		"cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=%p\n",
-			s->prop_adc.fmt, s->prop_adc.fmt_original,
-			(unsigned) cnt, dest));
-
-	if (cnt > s->dma_adc.dmasize) {
-		cnt = s->dma_adc.dmasize;
-	}
-	if (!cnt) {
-		*copied = 0;
-		return 0;
-	}
-	if (s->conversion) {
-		if (!s->tmpbuff) {
-			*copied = cnt / 2;
-			return 0;
-		}
-		CopySamples(s->tmpbuff, (void *) hwsrc, cnt,
-			    (unsigned) s->prop_adc.channels,
-			    s->prop_adc.fmt_original);
-		src = s->tmpbuff;
-		cnt = cnt / 2;
-	}
-
-	if (copy_to_user(dest, src, cnt)) {
-		*copied = 0;
-		return -EFAULT;
-	}
-	*copied = cnt;
-	CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
-		"cs4281: cs_copy_to_user()- copied bytes is %d \n", cnt));
-	return 0;
-}
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_read(struct file *file, char __user *buffer, size_t count,
-			   loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-	unsigned copied = 0;
-
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-		  printk(KERN_INFO "cs4281: cs4281_read()+ %Zu \n", count));
-
-	VALIDATE_STATE(s);
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-//
-// "count" is the amount of bytes to read (from app), is decremented each loop
-//      by the amount of bytes that have been returned to the user buffer.
-// "cnt" is the running total of each read from the buffer (changes each loop)
-// "buffer" points to the app's buffer
-// "ret" keeps a running total of the amount of bytes that have been copied
-//      to the user buffer.
-// "copied" is the total bytes copied into the user buffer for each loop.
-//
-	while (count > 0) {
-		CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-			"_read() count>0 count=%Zu .count=%d .swptr=%d .hwptr=%d \n",
-				count, s->dma_adc.count,
-				s->dma_adc.swptr, s->dma_adc.hwptr));
-		spin_lock_irqsave(&s->lock, flags);
-
-		// get the current copy point of the sw buffer
-		swptr = s->dma_adc.swptr;
-
-		// cnt is the amount of unread bytes from the end of the 
-		// hw buffer to the current sw pointer
-		cnt = s->dma_adc.dmasize - swptr;
-
-		// dma_adc.count is the current total bytes that have not been read.
-		// if the amount of unread bytes from the current sw pointer to the
-		// end of the buffer is greater than the current total bytes that
-		// have not been read, then set the "cnt" (unread bytes) to the
-		// amount of unread bytes.  
-
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		//
-		// if we are converting from 8/16 then we need to copy
-		// twice the number of 16 bit bytes then 8 bit bytes.
-		// 
-		if (s->conversion) {
-			if (cnt > (count * 2))
-				cnt = (count * 2);
-		} else {
-			if (cnt > count)
-				cnt = count;
-		}
-		//
-		// "cnt" NOW is the smaller of the amount that will be read,
-		// and the amount that is requested in this read (or partial).
-		// if there are no bytes in the buffer to read, then start the
-		// ADC and wait for the interrupt handler to wake us up.
-		//
-		if (cnt <= 0) {
-
-			// start up the dma engine and then continue back to the top of
-			// the loop when wake up occurs.
-			start_adc(s);
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->dma_adc.wait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		// there are bytes in the buffer to read.
-		// copy from the hw buffer over to the user buffer.
-		// user buffer is designated by "buffer"
-		// virtual address to copy from is rawbuf+swptr
-		// the "cnt" is the number of bytes to read.
-
-		CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
-			"_read() copy_to cnt=%d count=%Zu ", cnt, count));
-		CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-			 " .dmasize=%d .count=%d buffer=%p ret=%Zd\n",
-				 s->dma_adc.dmasize, s->dma_adc.count, buffer, ret));
-
-		if (cs_copy_to_user
-		    (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied))
-			return ret ? ret : -EFAULT;
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= copied;
-		buffer += copied;
-		ret += copied;
-		start_adc(s);
-	}
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-		  printk(KERN_INFO "cs4281: cs4281_read()- %Zd\n", ret));
-	return ret;
-}
-
-
-static ssize_t cs4281_write(struct file *file, const char __user *buffer,
-			    size_t count, loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr, hwptr, busaddr;
-	int cnt;
-
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-		  printk(KERN_INFO "cs4281: cs4281_write()+ count=%Zu\n",
-			 count));
-	VALIDATE_STATE(s);
-
-	if (s->dma_dac.mapped)
-		return -ENXIO;
-	if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac.count < 0) {
-			s->dma_dac.count = 0;
-			s->dma_dac.swptr = s->dma_dac.hwptr;
-		}
-		if (s->dma_dac.underrun) {
-			s->dma_dac.underrun = 0;
-			hwptr = readl(s->pBA0 + BA0_DCA0);
-			busaddr = virt_to_bus(s->dma_dac.rawbuf);
-			hwptr -= (unsigned) busaddr;
-			s->dma_dac.swptr = s->dma_dac.hwptr = hwptr;
-		}
-		swptr = s->dma_dac.swptr;
-		cnt = s->dma_dac.dmasize - swptr;
-		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-			cnt = s->dma_dac.dmasize - s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			start_dac(s);
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->dma_dac.wait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
-			return ret ? ret : -EFAULT;
-		swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac.swptr = swptr;
-		s->dma_dac.count += cnt;
-		s->dma_dac.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		start_dac(s);
-	}
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-		  printk(KERN_INFO "cs4281: cs4281_write()- %Zd\n", ret));
-	return ret;
-}
-
-
-static unsigned int cs4281_poll(struct file *file,
-				struct poll_table_struct *wait)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-		  printk(KERN_INFO "cs4281: cs4281_poll()+\n"));
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_poll() wait on FMODE_WRITE\n"));
-		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-			return 0;
-		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_poll() wait on FMODE_READ\n"));
-		if(!s->dma_dac.ready && prog_dmabuf_adc(s))
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	cs4281_update_ptr(s,CS_FALSE);
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >=
-			    (signed) s->dma_dac.fragsize) {
-				if (s->dma_dac.wakeup)
-					mask |= POLLOUT | POLLWRNORM;
-				else
-					mask = 0;
-				s->dma_dac.wakeup = 0;
-			}
-		} else {
-			if ((signed) (s->dma_dac.dmasize/2) >= s->dma_dac.count)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	} else if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.mapped) {
-			if (s->dma_adc.count >= (signed) s->dma_adc.fragsize) 
-				mask |= POLLIN | POLLRDNORM;
-		} else {
-			if (s->dma_adc.count > 0)
-				mask |= POLLIN | POLLRDNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-		  printk(KERN_INFO "cs4281: cs4281_poll()- 0x%.8x\n",
-			 mask));
-	return mask;
-}
-
-
-static int cs4281_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	struct dmabuf *db;
-	int ret;
-	unsigned long size;
-
-	CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-		  printk(KERN_INFO "cs4281: cs4281_mmap()+\n"));
-
-	VALIDATE_STATE(s);
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf_dac(s)) != 0)
-			return ret;
-		db = &s->dma_dac;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf_adc(s)) != 0)
-			return ret;
-		db = &s->dma_adc;
-	} else
-		return -EINVAL;
-//
-// only support PLAYBACK for now
-//
-	db = &s->dma_dac;
-
-	if (cs4x_pgoff(vma) != 0)
-		return -EINVAL;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder))
-		return -EINVAL;
-	if (remap_pfn_range(vma, vma->vm_start,
-				virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-				size, vma->vm_page_prot))
-		return -EAGAIN;
-	db->mapped = 1;
-
-	CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-		  printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",
-			 (unsigned) size));
-
-	return 0;
-}
-
-
-static int cs4281_ioctl(struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	unsigned long flags;
-	audio_buf_info abinfo;
-	count_info cinfo;
-	int val, mapped, ret;
-	int __user *p = (int __user *)arg;
-
-	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
-		 "cs4281: cs4281_ioctl(): file=%p cmd=0x%.8x\n", file, cmd));
-#if CSDEBUG
-	cs_printioctl(cmd);
-#endif
-	VALIDATE_STATE(s);
-	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-	    ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-			"cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n",
-				 SOUND_VERSION));
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): DSP_SYNC\n"));
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s,
-					 0 /*file->f_flags & O_NONBLOCK */
-					 );
-		return 0;
-
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-				DSP_CAP_TRIGGER | DSP_CAP_MMAP,
-				p);
-
-	case SNDCTL_DSP_RESET:
-		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): DSP_RESET\n"));
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq(s->irq);
-			s->dma_dac.swptr = s->dma_dac.hwptr =
-			    s->dma_dac.count = s->dma_dac.total_bytes =
-			    s->dma_dac.blocks = s->dma_dac.wakeup = 0;
-			prog_codec(s, CS_TYPE_DAC);
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->irq);
-			s->dma_adc.swptr = s->dma_adc.hwptr =
-			    s->dma_adc.count = s->dma_adc.total_bytes =
-			    s->dma_adc.blocks = s->dma_dac.wakeup = 0;
-			prog_codec(s, CS_TYPE_ADC);
-		}
-		return 0;
-
-	case SNDCTL_DSP_SPEED:
-		if (get_user(val, p))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): DSP_SPEED val=%d\n", val));
-		//
-		// support independent capture and playback channels
-		// assume that the file mode bit determines the 
-		// direction of the data flow.
-		//
-		if (file->f_mode & FMODE_READ) {
-			if (val >= 0) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				// program sampling rates 
-				if (val > 48000)
-					val = 48000;
-				if (val < 6300)
-					val = 6300;
-				s->prop_adc.rate = val;
-				prog_codec(s, CS_TYPE_ADC);
-			}
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val >= 0) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				// program sampling rates 
-				if (val > 48000)
-					val = 48000;
-				if (val < 6300)
-					val = 6300;
-				s->prop_dac.rate = val;
-				prog_codec(s, CS_TYPE_DAC);
-			}
-		}
-
-		if (file->f_mode & FMODE_WRITE)
-			val = s->prop_dac.rate;
-		else if (file->f_mode & FMODE_READ)
-			val = s->prop_adc.rate;
-
-		return put_user(val, p);
-
-	case SNDCTL_DSP_STEREO:
-		if (get_user(val, p))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): DSP_STEREO val=%d\n", val));
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ready = 0;
-			s->prop_adc.channels = val ? 2 : 1;
-			prog_codec(s, CS_TYPE_ADC);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.ready = 0;
-			s->prop_dac.channels = val ? 2 : 1;
-			prog_codec(s, CS_TYPE_DAC);
-		}
-		return 0;
-
-	case SNDCTL_DSP_CHANNELS:
-		if (get_user(val, p))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): DSP_CHANNELS val=%d\n",
-				 val));
-		if (val != 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val >= 2)
-					s->prop_adc.channels = 2;
-				else
-					s->prop_adc.channels = 1;
-				prog_codec(s, CS_TYPE_ADC);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val >= 2)
-					s->prop_dac.channels = 2;
-				else
-					s->prop_dac.channels = 1;
-				prog_codec(s, CS_TYPE_DAC);
-			}
-		}
-
-		if (file->f_mode & FMODE_WRITE)
-			val = s->prop_dac.channels;
-		else if (file->f_mode & FMODE_READ)
-			val = s->prop_adc.channels;
-
-		return put_user(val, p);
-
-	case SNDCTL_DSP_GETFMTS:	// Returns a mask 
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-			"cs4281: cs4281_ioctl(): DSP_GETFMT val=0x%.8x\n",
-				 AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-				 AFMT_U8));
-		return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-				AFMT_U8, p);
-
-	case SNDCTL_DSP_SETFMT:
-		if (get_user(val, p))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): DSP_SETFMT val=0x%.8x\n",
-				 val));
-		if (val != AFMT_QUERY) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val != AFMT_S16_LE
-				    && val != AFMT_U16_LE && val != AFMT_S8
-				    && val != AFMT_U8)
-					val = AFMT_U8;
-				s->prop_adc.fmt = val;
-				s->prop_adc.fmt_original = s->prop_adc.fmt;
-				prog_codec(s, CS_TYPE_ADC);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val != AFMT_S16_LE
-				    && val != AFMT_U16_LE && val != AFMT_S8
-				    && val != AFMT_U8)
-					val = AFMT_U8;
-				s->prop_dac.fmt = val;
-				s->prop_dac.fmt_original = s->prop_dac.fmt;
-				prog_codec(s, CS_TYPE_DAC);
-			}
-		} else {
-			if (file->f_mode & FMODE_WRITE)
-				val = s->prop_dac.fmt_original;
-			else if (file->f_mode & FMODE_READ)
-				val = s->prop_adc.fmt_original;
-		}
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-		  "cs4281: cs4281_ioctl(): DSP_SETFMT return val=0x%.8x\n", 
-			val));
-		return put_user(val, p);
-
-	case SNDCTL_DSP_POST:
-		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): DSP_POST\n"));
-		return 0;
-
-	case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if (file->f_mode & s->ena & FMODE_READ)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & s->ena & FMODE_WRITE)
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, p);
-
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready
-				    && (ret = prog_dmabuf_adc(s)))
-					return ret;
-				start_adc(s);
-			} else
-				stop_adc(s);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac.ready
-				    && (ret = prog_dmabuf_dac(s)))
-					return ret;
-				start_dac(s);
-			} else
-				stop_dac(s);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s,CS_FALSE);
-		abinfo.fragsize = s->dma_dac.fragsize;
-		if (s->dma_dac.mapped)
-			abinfo.bytes = s->dma_dac.dmasize;
-		else
-			abinfo.bytes =
-			    s->dma_dac.dmasize - s->dma_dac.count;
-		abinfo.fragstotal = s->dma_dac.numfrag;
-		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-		CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
-			"cs4281: cs4281_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n",
-				abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
-				abinfo.fragments));
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(p, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s,CS_FALSE);
-		if (s->conversion) {
-			abinfo.fragsize = s->dma_adc.fragsize / 2;
-			abinfo.bytes = s->dma_adc.count / 2;
-			abinfo.fragstotal = s->dma_adc.numfrag;
-			abinfo.fragments =
-			    abinfo.bytes >> (s->dma_adc.fragshift - 1);
-		} else {
-			abinfo.fragsize = s->dma_adc.fragsize;
-			abinfo.bytes = s->dma_adc.count;
-			abinfo.fragstotal = s->dma_adc.numfrag;
-			abinfo.fragments =
-			    abinfo.bytes >> s->dma_adc.fragshift;
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(p, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_NONBLOCK:
-		file->f_flags |= O_NONBLOCK;
-		return 0;
-
-	case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-			return 0;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s,CS_FALSE);
-		val = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return put_user(val, p);
-
-	case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if(!s->dma_adc.ready && prog_dmabuf_adc(s))
-			return 0;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s,CS_FALSE);
-		cinfo.bytes = s->dma_adc.total_bytes;
-		if (s->dma_adc.mapped) {
-			cinfo.blocks =
-			    (cinfo.bytes >> s->dma_adc.fragshift) -
-			    s->dma_adc.blocks;
-			s->dma_adc.blocks =
-			    cinfo.bytes >> s->dma_adc.fragshift;
-		} else {
-			if (s->conversion) {
-				cinfo.blocks =
-				    s->dma_adc.count /
-				    2 >> (s->dma_adc.fragshift - 1);
-			} else
-				cinfo.blocks =
-				    s->dma_adc.count >> s->dma_adc.
-				    fragshift;
-		}
-		if (s->conversion)
-			cinfo.ptr = s->dma_adc.hwptr / 2;
-		else
-			cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize - 1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(p, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-	case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-			return 0;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s,CS_FALSE);
-		cinfo.bytes = s->dma_dac.total_bytes;
-		if (s->dma_dac.mapped) {
-			cinfo.blocks =
-			    (cinfo.bytes >> s->dma_dac.fragshift) -
-			    s->dma_dac.blocks;
-			s->dma_dac.blocks =
-			    cinfo.bytes >> s->dma_dac.fragshift;
-		} else {
-			cinfo.blocks =
-			    s->dma_dac.count >> s->dma_dac.fragshift;
-		}
-		cinfo.ptr = s->dma_dac.hwptr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= s->dma_dac.fragsize - 1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(p, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf_dac(s)))
-				return val;
-			return put_user(s->dma_dac.fragsize, p);
-		}
-		if ((val = prog_dmabuf_adc(s)))
-			return val;
-		if (s->conversion)
-			return put_user(s->dma_adc.fragsize / 2, p);
-		else
-			return put_user(s->dma_adc.fragsize, p);
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(val, p))
-			return -EFAULT;
-		return 0;	// Say OK, but do nothing.
-
-	case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
-		    || (file->f_mode & FMODE_WRITE
-			&& s->dma_dac.subdivision)) return -EINVAL;
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		else if (file->f_mode & FMODE_WRITE)
-			s->dma_dac.subdivision = val;
-		return 0;
-
-	case SOUND_PCM_READ_RATE:
-		if (file->f_mode & FMODE_READ)
-			return put_user(s->prop_adc.rate, p);
-		else if (file->f_mode & FMODE_WRITE)
-			return put_user(s->prop_dac.rate, p);
-
-	case SOUND_PCM_READ_CHANNELS:
-		if (file->f_mode & FMODE_READ)
-			return put_user(s->prop_adc.channels, p);
-		else if (file->f_mode & FMODE_WRITE)
-			return put_user(s->prop_dac.channels, p);
-
-	case SOUND_PCM_READ_BITS:
-		if (file->f_mode & FMODE_READ)
-			return
-			    put_user(
-				     (s->prop_adc.
-				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-				     p);
-		else if (file->f_mode & FMODE_WRITE)
-			return
-			    put_user(
-				     (s->prop_dac.
-				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-				     p);
-
-	case SOUND_PCM_WRITE_FILTER:
-	case SNDCTL_DSP_SETSYNCRO:
-	case SOUND_PCM_READ_FILTER:
-		return -EINVAL;
-	}
-	return mixer_ioctl(s, cmd, arg);
-}
-
-
-static int cs4281_release(struct inode *inode, struct file *file)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-
-	CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO
-		 "cs4281: cs4281_release(): inode=%p file=%p f_mode=%d\n",
-			 inode, file, file->f_mode));
-
-	VALIDATE_STATE(s);
-
-	if (file->f_mode & FMODE_WRITE) {
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-		mutex_lock(&s->open_sem_dac);
-		stop_dac(s);
-		dealloc_dmabuf(s, &s->dma_dac);
-		s->open_mode &= ~FMODE_WRITE;
-		mutex_unlock(&s->open_sem_dac);
-		wake_up(&s->open_wait_dac);
-	}
-	if (file->f_mode & FMODE_READ) {
-		drain_adc(s, file->f_flags & O_NONBLOCK);
-		mutex_lock(&s->open_sem_adc);
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-		s->open_mode &= ~FMODE_READ;
-		mutex_unlock(&s->open_sem_adc);
-		wake_up(&s->open_wait_adc);
-	}
-	return 0;
-}
-
-static int cs4281_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	struct cs4281_state *s=NULL;
-	struct list_head *entry;
-
-	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-		"cs4281: cs4281_open(): inode=%p file=%p f_mode=0x%x\n",
-			inode, file, file->f_mode));
-
-	list_for_each(entry, &cs4281_devs)
-	{
-		s = list_entry(entry, struct cs4281_state, list);
-
-		if (!((s->dev_audio ^ minor) & ~0xf))
-			break;
-	}
-	if (entry == &cs4281_devs)
-		return -ENODEV;
-	if (!s) {
-		CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-			"cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
-		return -ENODEV;
-	}
-	VALIDATE_STATE(s);
-	file->private_data = s;
-
-	// wait for device to become free 
-	if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) {
-		CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO
-			 "cs4281: cs4281_open(): Error - must open READ and/or WRITE\n"));
-		return -ENODEV;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		mutex_lock(&s->open_sem_dac);
-		while (s->open_mode & FMODE_WRITE) {
-			if (file->f_flags & O_NONBLOCK) {
-				mutex_unlock(&s->open_sem_dac);
-				return -EBUSY;
-			}
-			mutex_unlock(&s->open_sem_dac);
-			interruptible_sleep_on(&s->open_wait_dac);
-
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-			mutex_lock(&s->open_sem_dac);
-		}
-	}
-	if (file->f_mode & FMODE_READ) {
-		mutex_lock(&s->open_sem_adc);
-		while (s->open_mode & FMODE_READ) {
-			if (file->f_flags & O_NONBLOCK) {
-				mutex_unlock(&s->open_sem_adc);
-				return -EBUSY;
-			}
-			mutex_unlock(&s->open_sem_adc);
-			interruptible_sleep_on(&s->open_wait_adc);
-
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-			mutex_lock(&s->open_sem_adc);
-		}
-	}
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	if (file->f_mode & FMODE_READ) {
-		s->prop_adc.fmt = AFMT_U8;
-		s->prop_adc.fmt_original = s->prop_adc.fmt;
-		s->prop_adc.channels = 1;
-		s->prop_adc.rate = 8000;
-		s->prop_adc.clkdiv = 96 | 0x80;
-		s->conversion = 0;
-		s->ena &= ~FMODE_READ;
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-		    s->dma_adc.subdivision = 0;
-		mutex_unlock(&s->open_sem_adc);
-
-		if (prog_dmabuf_adc(s)) {
-			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-				"cs4281: adc Program dmabufs failed.\n"));
-			cs4281_release(inode, file);
-			return -ENOMEM;
-		}
-		prog_codec(s, CS_TYPE_ADC);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->prop_dac.fmt = AFMT_U8;
-		s->prop_dac.fmt_original = s->prop_dac.fmt;
-		s->prop_dac.channels = 1;
-		s->prop_dac.rate = 8000;
-		s->prop_dac.clkdiv = 96 | 0x80;
-		s->conversion = 0;
-		s->ena &= ~FMODE_WRITE;
-		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-		    s->dma_dac.subdivision = 0;
-		mutex_unlock(&s->open_sem_dac);
-
-		if (prog_dmabuf_dac(s)) {
-			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-				"cs4281: dac Program dmabufs failed.\n"));
-			cs4281_release(inode, file);
-			return -ENOMEM;
-		}
-		prog_codec(s, CS_TYPE_DAC);
-	}
-	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
-		  printk(KERN_INFO "cs4281: cs4281_open()- 0\n"));
-	return nonseekable_open(inode, file);
-}
-
-
-// ******************************************************************************************
-//   Wave (audio) file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_audio_fops = {
-	.owner	 = THIS_MODULE,
-	.llseek	 = no_llseek,
-	.read	 = cs4281_read,
-	.write	 = cs4281_write,
-	.poll	 = cs4281_poll,
-	.ioctl	 = cs4281_ioctl,
-	.mmap	 = cs4281_mmap,
-	.open	 = cs4281_open,
-	.release = cs4281_release,
-};
-
-// --------------------------------------------------------------------- 
-
-// hold spinlock for the following! 
-static void cs4281_handle_midi(struct cs4281_state *s)
-{
-	unsigned char ch;
-	int wake;
-	unsigned temp1;
-
-	wake = 0;
-	while (!(readl(s->pBA0 + BA0_MIDSR) & 0x80)) {
-		ch = readl(s->pBA0 + BA0_MIDRP);
-		if (s->midi.icnt < MIDIINBUF) {
-			s->midi.ibuf[s->midi.iwr] = ch;
-			s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-			s->midi.icnt++;
-		}
-		wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.iwait);
-	wake = 0;
-	while (!(readl(s->pBA0 + BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) {
-		temp1 = (s->midi.obuf[s->midi.ord]) & 0x000000ff;
-		writel(temp1, s->pBA0 + BA0_MIDWP);
-		s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-		s->midi.ocnt--;
-		if (s->midi.ocnt < MIDIOUTBUF - 16)
-			wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.owait);
-}
-
-
-
-static irqreturn_t cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct cs4281_state *s = (struct cs4281_state *) dev_id;
-	unsigned int temp1;
-
-	// fastpath out, to ease interrupt sharing 
-	temp1 = readl(s->pBA0 + BA0_HISR);	// Get Int Status reg.
-
-	CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
-		  "cs4281: cs4281_interrupt() BA0_HISR=0x%.8x\n", temp1));
-/*
-* If not DMA or MIDI interrupt, then just return.
-*/
-	if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
-		CS_DBGOUT(CS_INTERRUPT, 9, printk(KERN_INFO
-			"cs4281: cs4281_interrupt(): returning not cs4281 interrupt.\n"));
-		return IRQ_NONE;
-	}
-
-	if (temp1 & HISR_DMA0)	// If play interrupt,
-		readl(s->pBA0 + BA0_HDSR0);	//   clear the source.
-
-	if (temp1 & HISR_DMA1)	// Same for play.
-		readl(s->pBA0 + BA0_HDSR1);
-	writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Local EOI
-
-	spin_lock(&s->lock);
-	cs4281_update_ptr(s,CS_TRUE);
-	cs4281_handle_midi(s);
-	spin_unlock(&s->lock);
-	return IRQ_HANDLED;
-}
-
-// **************************************************************************
-
-static void cs4281_midi_timer(unsigned long data)
-{
-	struct cs4281_state *s = (struct cs4281_state *) data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	cs4281_handle_midi(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->midi.timer.expires = jiffies + 1;
-	add_timer(&s->midi.timer);
-}
-
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_midi_read(struct file *file, char __user *buffer,
-				size_t count, loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.ird;
-		cnt = MIDIINBUF - ptr;
-		if (s->midi.icnt < cnt)
-			cnt = s->midi.icnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->midi.iwait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
-			return ret ? ret : -EFAULT;
-		ptr = (ptr + cnt) % MIDIINBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.ird = ptr;
-		s->midi.icnt -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-	}
-	return ret;
-}
-
-
-static ssize_t cs4281_midi_write(struct file *file, const char __user *buffer,
-				 size_t count, loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.owr;
-		cnt = MIDIOUTBUF - ptr;
-		if (s->midi.ocnt + cnt > MIDIOUTBUF)
-			cnt = MIDIOUTBUF - s->midi.ocnt;
-		if (cnt <= 0)
-			cs4281_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->midi.owait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
-			return ret ? ret : -EFAULT;
-		ptr = (ptr + cnt) % MIDIOUTBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.owr = ptr;
-		s->midi.ocnt += cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	}
-	return ret;
-}
-
-
-static unsigned int cs4281_midi_poll(struct file *file,
-				     struct poll_table_struct *wait)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_flags & FMODE_WRITE)
-		poll_wait(file, &s->midi.owait, wait);
-	if (file->f_flags & FMODE_READ)
-		poll_wait(file, &s->midi.iwait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_flags & FMODE_READ) {
-		if (s->midi.icnt > 0)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_flags & FMODE_WRITE) {
-		if (s->midi.ocnt < MIDIOUTBUF)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-
-static int cs4281_midi_open(struct inode *inode, struct file *file)
-{
-	unsigned long flags, temp1;
-	unsigned int minor = iminor(inode);
-	struct cs4281_state *s=NULL;
-	struct list_head *entry;
-	list_for_each(entry, &cs4281_devs)
-	{
-		s = list_entry(entry, struct cs4281_state, list);
-
-		if (s->dev_midi == minor)
-			break;
-	}
-
-	if (entry == &cs4281_devs)
-		return -ENODEV;
-	if (!s)
-	{
-		CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-			"cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
-		return -ENODEV;
-	}
-	VALIDATE_STATE(s);
-	file->private_data = s;
-	// wait for device to become free 
-	mutex_lock(&s->open_sem);
-	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_sem);
-			return -EBUSY;
-		}
-		mutex_unlock(&s->open_sem);
-		interruptible_sleep_on(&s->open_wait);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_sem);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-		writel(1, s->pBA0 + BA0_MIDCR);	// Reset the interface.
-		writel(0, s->pBA0 + BA0_MIDCR);	// Return to normal mode.
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		writel(0x0000000f, s->pBA0 + BA0_MIDCR);	// Enable transmit, record, ints.
-		temp1 = readl(s->pBA0 + BA0_HIMR);
-		writel(temp1 & 0xffbfffff, s->pBA0 + BA0_HIMR);	// Enable midi int. recognition.
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts
-		init_timer(&s->midi.timer);
-		s->midi.timer.expires = jiffies + 1;
-		s->midi.timer.data = (unsigned long) s;
-		s->midi.timer.function = cs4281_midi_timer;
-		add_timer(&s->midi.timer);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |=
-	    (file->
-	     f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ |
-					    FMODE_MIDI_WRITE);
-	mutex_unlock(&s->open_sem);
-	return nonseekable_open(inode, file);
-}
-
-
-static int cs4281_midi_release(struct inode *inode, struct file *file)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	unsigned count, tmo;
-
-	VALIDATE_STATE(s);
-
-	if (file->f_mode & FMODE_WRITE) {
-		add_wait_queue(&s->midi.owait, &wait);
-		for (;;) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			spin_lock_irqsave(&s->lock, flags);
-			count = s->midi.ocnt;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (count <= 0)
-				break;
-			if (signal_pending(current))
-				break;
-			if (file->f_flags & O_NONBLOCK) {
-				remove_wait_queue(&s->midi.owait, &wait);
-				current->state = TASK_RUNNING;
-				return -EBUSY;
-			}
-			tmo = (count * HZ) / 3100;
-			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG
-				       "cs4281: midi timed out??\n");
-		}
-		remove_wait_queue(&s->midi.owait, &wait);
-		current->state = TASK_RUNNING;
-	}
-	mutex_lock(&s->open_sem);
-	s->open_mode &=
-	    (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ |
-						     FMODE_MIDI_WRITE);
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		writel(0, s->pBA0 + BA0_MIDCR);	// Disable Midi interrupts.  
-		del_timer(&s->midi.timer);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	mutex_unlock(&s->open_sem);
-	wake_up(&s->open_wait);
-	return 0;
-}
-
-// ******************************************************************************************
-//   Midi file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_midi_fops = {
-	.owner	 = THIS_MODULE,
-	.llseek	 = no_llseek,
-	.read	 = cs4281_midi_read,
-	.write	 = cs4281_midi_write,
-	.poll	 = cs4281_midi_poll,
-	.open	 = cs4281_midi_open,
-	.release = cs4281_midi_release,
-};
-
-
-// --------------------------------------------------------------------- 
-
-// maximum number of devices 
-#define NR_DEVICE 8		// Only eight devices supported currently.
-
-// --------------------------------------------------------------------- 
-
-static struct initvol {
-	int mixch;
-	int vol;
-} initvol[] __devinitdata = {
-
-	{
-	SOUND_MIXER_WRITE_VOLUME, 0x4040}, {
-	SOUND_MIXER_WRITE_PCM, 0x4040}, {
-	SOUND_MIXER_WRITE_SYNTH, 0x4040}, {
-	SOUND_MIXER_WRITE_CD, 0x4040}, {
-	SOUND_MIXER_WRITE_LINE, 0x4040}, {
-	SOUND_MIXER_WRITE_LINE1, 0x4040}, {
-	SOUND_MIXER_WRITE_RECLEV, 0x0000}, {
-	SOUND_MIXER_WRITE_SPEAKER, 0x4040}, {
-	SOUND_MIXER_WRITE_MIC, 0x0000}
-};
-
-
-#ifndef NOT_CS4281_PM
-static void __devinit cs4281_BuildFIFO(
-	struct cs4281_pipeline *p, 
-	struct cs4281_state *s)
-{
-	switch(p->number)
-	{
-		case 0:  /* playback */
-		{
-			p->u32FCRnAddress  =  BA0_FCR0;
-			p->u32FSICnAddress = BA0_FSIC0;
-			p->u32FPDRnAddress = BA0_FPDR0;
-			break;
-		}
-		case 1:  /* capture */
-		{
-			p->u32FCRnAddress  =  BA0_FCR1;
-			p->u32FSICnAddress = BA0_FSIC1;
-			p->u32FPDRnAddress = BA0_FPDR1;
-			break;
-		}
-
-		case 2: 
-		{
-			p->u32FCRnAddress  =  BA0_FCR2;
-			p->u32FSICnAddress = BA0_FSIC2;
-			p->u32FPDRnAddress = BA0_FPDR2;
-			break;
-		}
-		case 3: 
-		{
-			p->u32FCRnAddress  =  BA0_FCR3;
-			p->u32FSICnAddress = BA0_FSIC3;
-			p->u32FPDRnAddress = BA0_FPDR3;
-			break;
-		}
-		default:
-			break;
-	}
-	//
-	// first read the hardware to initialize the member variables
-	//
-	p->u32FCRnValue = readl(s->pBA0 + p->u32FCRnAddress);
-	p->u32FSICnValue = readl(s->pBA0 + p->u32FSICnAddress);
-	p->u32FPDRnValue = readl(s->pBA0 + p->u32FPDRnAddress);
-
-}
-
-static void __devinit cs4281_BuildDMAengine(
-	struct cs4281_pipeline *p, 
-	struct cs4281_state *s)
-{
-/*
-* initialize all the addresses of this pipeline dma info.
-*/
-	switch(p->number)
-	{
-		case 0:  /* playback */
-		{
-			p->u32DBAnAddress = BA0_DBA0;
-			p->u32DCAnAddress = BA0_DCA0;
-			p->u32DBCnAddress = BA0_DBC0;
-			p->u32DCCnAddress = BA0_DCC0;
-			p->u32DMRnAddress = BA0_DMR0;
-			p->u32DCRnAddress = BA0_DCR0;
-			p->u32HDSRnAddress = BA0_HDSR0;
-			break;
-		}
-
-		case 1: /* capture */
-		{
-			p->u32DBAnAddress = BA0_DBA1;
-			p->u32DCAnAddress = BA0_DCA1;
-			p->u32DBCnAddress = BA0_DBC1;
-			p->u32DCCnAddress = BA0_DCC1;
-			p->u32DMRnAddress = BA0_DMR1;
-			p->u32DCRnAddress = BA0_DCR1;
-			p->u32HDSRnAddress = BA0_HDSR1;
-			break;
-		}
-
-		case 2:
-		{
-			p->u32DBAnAddress = BA0_DBA2;
-			p->u32DCAnAddress = BA0_DCA2;
-			p->u32DBCnAddress = BA0_DBC2;
-			p->u32DCCnAddress = BA0_DCC2;
-			p->u32DMRnAddress = BA0_DMR2;
-			p->u32DCRnAddress = BA0_DCR2;
-			p->u32HDSRnAddress = BA0_HDSR2;
-			break;
-		}
-
-		case 3:
-		{
-			p->u32DBAnAddress = BA0_DBA3;
-			p->u32DCAnAddress = BA0_DCA3;
-			p->u32DBCnAddress = BA0_DBC3;
-			p->u32DCCnAddress = BA0_DCC3;
-			p->u32DMRnAddress = BA0_DMR3;
-			p->u32DCRnAddress = BA0_DCR3;
-			p->u32HDSRnAddress = BA0_HDSR3;
-			break;
-		}
-		default:
-			break;
-	}
-
-//
-// Initialize the dma values for this pipeline
-//
-	p->u32DBAnValue = readl(s->pBA0 + p->u32DBAnAddress);
-	p->u32DBCnValue = readl(s->pBA0 + p->u32DBCnAddress);
-	p->u32DMRnValue = readl(s->pBA0 + p->u32DMRnAddress);
-	p->u32DCRnValue = readl(s->pBA0 + p->u32DCRnAddress);
-
-}
-
-static void __devinit cs4281_InitPM(struct cs4281_state *s)
-{
-	int i;
-	struct cs4281_pipeline *p;
-
-	for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
-	{
-		p = &s->pl[i];
-		p->number = i;
-		cs4281_BuildDMAengine(p,s);
-		cs4281_BuildFIFO(p,s);
-	/*
-	* currently only  2 pipelines are used
-	* so, only set the valid bit on the playback and capture.
-	*/
-		if( (i == CS4281_PLAYBACK_PIPELINE_NUMBER) || 
-			(i == CS4281_CAPTURE_PIPELINE_NUMBER))
-			p->flags |= CS4281_PIPELINE_VALID;
-	}
-	s->pm.u32SSPM_BITS = 0x7e;  /* rev c, use 0x7c for rev a or b */
-}
-#endif
-
-static int __devinit cs4281_probe(struct pci_dev *pcidev,
-				  const struct pci_device_id *pciid)
-{
-	struct cs4281_state *s;
-	dma_addr_t dma_mask;
-	mm_segment_t fs;
-	int i, val;
-	unsigned int temp1, temp2;
-
-	CS_DBGOUT(CS_FUNCTION | CS_INIT, 2,
-		  printk(KERN_INFO "cs4281: probe()+\n"));
-
-	if (pci_enable_device(pcidev)) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-			 "cs4281: pci_enable_device() failed\n"));
-		return -1;
-	}
-	if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM) ||
-	    !(pci_resource_flags(pcidev, 1) & IORESOURCE_MEM)) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-			 "cs4281: probe()- Memory region not assigned\n"));
-		return -ENODEV;
-	}
-	if (pcidev->irq == 0) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-			 "cs4281: probe() IRQ not assigned\n"));
-		return -ENODEV;
-	}
-	dma_mask = 0xffffffff;	/* this enables playback and recording */
-	i = pci_set_dma_mask(pcidev, dma_mask);
-	if (i) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-		      "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n"));
-		return i;
-	}
-	if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-		      "cs4281: probe() no memory for state struct.\n"));
-		return -1;
-	}
-	memset(s, 0, sizeof(struct cs4281_state));
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac.wait);
-	init_waitqueue_head(&s->open_wait);
-	init_waitqueue_head(&s->open_wait_adc);
-	init_waitqueue_head(&s->open_wait_dac);
-	init_waitqueue_head(&s->midi.iwait);
-	init_waitqueue_head(&s->midi.owait);
-	mutex_init(&s->open_sem);
-	mutex_init(&s->open_sem_adc);
-	mutex_init(&s->open_sem_dac);
-	spin_lock_init(&s->lock);
-	s->pBA0phys = pci_resource_start(pcidev, 0);
-	s->pBA1phys = pci_resource_start(pcidev, 1);
-
-	/* Convert phys to linear. */
-	s->pBA0 = ioremap_nocache(s->pBA0phys, 4096);
-	if (!s->pBA0) {
-		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-			 "cs4281: BA0 I/O mapping failed. Skipping part.\n"));
-		goto err_free;
-	}
-	s->pBA1 = ioremap_nocache(s->pBA1phys, 65536);
-	if (!s->pBA1) {
-		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-			 "cs4281: BA1 I/O mapping failed. Skipping part.\n"));
-		goto err_unmap;
-	}
-
-	temp1 = readl(s->pBA0 + BA0_PCICFG00);
-	temp2 = readl(s->pBA0 + BA0_PCICFG04);
-
-	CS_DBGOUT(CS_INIT, 2,
-		  printk(KERN_INFO
-			 "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=%p pBA1=%p \n",
-			 (unsigned) temp1, (unsigned) temp2, s->pBA0, s->pBA1));
-	CS_DBGOUT(CS_INIT, 2,
-		  printk(KERN_INFO
-			 "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n",
-			 (unsigned) s->pBA0phys, (unsigned) s->pBA1phys));
-
-#ifndef NOT_CS4281_PM
-	s->pm.flags = CS4281_PM_IDLE;
-#endif
-	temp1 = cs4281_hw_init(s);
-	if (temp1) {
-		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-			 "cs4281: cs4281_hw_init() failed. Skipping part.\n"));
-		goto err_irq;
-	}
-	s->magic = CS4281_MAGIC;
-	s->pcidev = pcidev;
-	s->irq = pcidev->irq;
-	if (request_irq
-	    (s->irq, cs4281_interrupt, IRQF_SHARED, "Crystal CS4281", s)) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-			  printk(KERN_ERR "cs4281: irq %u in use\n", s->irq));
-		goto err_irq;
-	}
-	if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) <
-	    0) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-			 "cs4281: probe() register_sound_dsp() failed.\n"));
-		goto err_dev1;
-	}
-	if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) <
-	    0) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-			 "cs4281: probe() register_sound_mixer() failed.\n"));
-		goto err_dev2;
-	}
-	if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-			 "cs4281: probe() register_sound_midi() failed.\n"));
-		goto err_dev3;
-	}
-#ifndef NOT_CS4281_PM
-	cs4281_InitPM(s);
-	s->pm.flags |= CS4281_PM_NOT_REGISTERED;
-#endif
-
-	pci_set_master(pcidev);	// enable bus mastering 
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	val = SOUND_MASK_LINE;
-	mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val);
-	for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) {
-		val = initvol[i].vol;
-		mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val);
-	}
-	val = 1;		// enable mic preamp 
-	mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long) &val);
-	set_fs(fs);
-
-	pci_set_drvdata(pcidev, s);
-	list_add(&s->list, &cs4281_devs);
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-		"cs4281: probe()- device allocated successfully\n"));
-	return 0;
-
-      err_dev3:
-	unregister_sound_mixer(s->dev_mixer);
-      err_dev2:
-	unregister_sound_dsp(s->dev_audio);
-      err_dev1:
-	free_irq(s->irq, s);
-      err_irq:
-	iounmap(s->pBA1);
-      err_unmap:
-	iounmap(s->pBA0);
-      err_free:
-	kfree(s);
-
-	CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO
-		"cs4281: probe()- no device allocated\n"));
-	return -ENODEV;
-} // probe_cs4281
-
-
-// --------------------------------------------------------------------- 
-
-static void __devexit cs4281_remove(struct pci_dev *pci_dev)
-{
-	struct cs4281_state *s = pci_get_drvdata(pci_dev);
-	// stop DMA controller 
-	synchronize_irq(s->irq);
-	free_irq(s->irq, s);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->dev_mixer);
-	unregister_sound_midi(s->dev_midi);
-	iounmap(s->pBA1);
-	iounmap(s->pBA0);
-	pci_set_drvdata(pci_dev,NULL);
-	list_del(&s->list);
-	kfree(s);
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-		 "cs4281: cs4281_remove()-: remove successful\n"));
-}
-
-static struct pci_device_id cs4281_pci_tbl[] = {
-	{
-		.vendor    = PCI_VENDOR_ID_CIRRUS,
-		.device    = PCI_DEVICE_ID_CRYSTAL_CS4281,
-		.subvendor = PCI_ANY_ID,
-		.subdevice = PCI_ANY_ID,
-	},
-	{ 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, cs4281_pci_tbl);
-
-static struct pci_driver cs4281_pci_driver = {
-	.name	  = "cs4281",
-	.id_table = cs4281_pci_tbl,
-	.probe	  = cs4281_probe,
-	.remove	  = __devexit_p(cs4281_remove),
-	.suspend  = CS4281_SUSPEND_TBL,
-	.resume	  = CS4281_RESUME_TBL,
-};
-
-static int __init cs4281_init_module(void)
-{
-	int rtn = 0;
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
-		"cs4281: cs4281_init_module()+ \n"));
-	printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " "
-	       __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION,
-	       CS4281_ARCH);
-	rtn = pci_register_driver(&cs4281_pci_driver);
-
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs4281_init_module()- (%d)\n",rtn));
-	return rtn;
-}
-
-static void __exit cs4281_cleanup_module(void)
-{
-	pci_unregister_driver(&cs4281_pci_driver);
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n"));
-}
-// --------------------------------------------------------------------- 
-
-MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com");
-MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
-MODULE_LICENSE("GPL");
-
-// --------------------------------------------------------------------- 
-
-module_init(cs4281_init_module);
-module_exit(cs4281_cleanup_module);
-
diff --git a/sound/oss/cs4281/cs4281pm-24.c b/sound/oss/cs4281/cs4281pm-24.c
deleted file mode 100644
index 90cbd76..0000000
--- a/sound/oss/cs4281/cs4281pm-24.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281pm.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file. 
-*
-*******************************************************************************/
-
-#ifndef NOT_CS4281_PM
-#include <linux/pm.h>
-
-static int cs4281_suspend(struct cs4281_state *s);
-static int cs4281_resume(struct cs4281_state *s);
-/* 
-* for now (12/22/00) only enable the pm_register PM support.
-* allow these table entries to be null.
-#define CS4281_SUSPEND_TBL cs4281_suspend_tbl
-#define CS4281_RESUME_TBL cs4281_resume_tbl
-*/
-#define CS4281_SUSPEND_TBL cs4281_suspend_null
-#define CS4281_RESUME_TBL cs4281_resume_null
-
-#else /* CS4281_PM */
-#define CS4281_SUSPEND_TBL cs4281_suspend_null
-#define CS4281_RESUME_TBL cs4281_resume_null
-#endif /* CS4281_PM */
-
diff --git a/sound/oss/cs4281/cs4281pm.h b/sound/oss/cs4281/cs4281pm.h
deleted file mode 100644
index b44fdc9..0000000
--- a/sound/oss/cs4281/cs4281pm.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef NOT_CS4281_PM
-/*******************************************************************************
-*
-*      "cs4281pm.h" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file. 
-*
-*******************************************************************************/
-/* general pm definitions */
-#define CS4281_AC97_HIGHESTREGTORESTORE 0x26
-#define CS4281_AC97_NUMBER_RESTORE_REGS (CS4281_AC97_HIGHESTREGTORESTORE/2-1)
-
-/* pipeline definitions */
-#define CS4281_NUMBER_OF_PIPELINES 	4
-#define CS4281_PIPELINE_VALID 		0x0001
-#define CS4281_PLAYBACK_PIPELINE_NUMBER	0x0000
-#define CS4281_CAPTURE_PIPELINE_NUMBER 	0x0001
-
-/* PM state defintions */
-#define CS4281_PM_NOT_REGISTERED	0x1000
-#define CS4281_PM_IDLE			0x0001
-#define CS4281_PM_SUSPENDING		0x0002
-#define CS4281_PM_SUSPENDED		0x0004
-#define CS4281_PM_RESUMING		0x0008
-#define CS4281_PM_RESUMED		0x0010
-
-struct cs4281_pm {
-	unsigned long flags;
-	u32 u32CLKCR1_SAVE,u32SSPMValue,u32PPLVCvalue,u32PPRVCvalue;
-	u32 u32FMLVCvalue,u32FMRVCvalue,u32GPIORvalue,u32JSCTLvalue,u32SSCR;
-	u32 u32SRCSA,u32DacASR,u32AdcASR,u32DacSR,u32AdcSR,u32MIDCR_Save;
-	u32 u32SSPM_BITS;
-	u32 ac97[CS4281_AC97_NUMBER_RESTORE_REGS];
-	u32 u32AC97_master_volume, u32AC97_headphone_volume, u32AC97_master_volume_mono;
-	u32 u32AC97_pcm_out_volume, u32AC97_powerdown, u32AC97_general_purpose;
-	u32 u32hwptr_playback,u32hwptr_capture;
-};
-
-struct cs4281_pipeline {
-	unsigned flags;
-	unsigned number;
-	u32 u32DBAnValue,u32DBCnValue,u32DMRnValue,u32DCRnValue;
-	u32 u32DBAnAddress,u32DCAnAddress,u32DBCnAddress,u32DCCnAddress;
-	u32 u32DMRnAddress,u32DCRnAddress,u32HDSRnAddress;
-	u32 u32DBAn_Save,u32DBCn_Save,u32DMRn_Save,u32DCRn_Save;
-	u32 u32DCCn_Save,u32DCAn_Save;
-/* 
-* technically, these are fifo variables, but just map the 
-* first fifo with the first pipeline and then use the fifo
-* variables inside of the pipeline struct.
-*/
-	u32 u32FCRn_Save,u32FSICn_Save;
-	u32 u32FCRnValue,u32FCRnAddress,u32FSICnValue,u32FSICnAddress;
-	u32 u32FPDRnValue,u32FPDRnAddress;
-};
-#endif
diff --git a/sound/oss/dev_table.c b/sound/oss/dev_table.c
index f65a904..08274c9 100644
--- a/sound/oss/dev_table.c
+++ b/sound/oss/dev_table.c
@@ -1,5 +1,5 @@
 /*
- * sound/dev_table.c
+ * sound/oss/dev_table.c
  *
  * Device call tables.
  *
@@ -13,9 +13,39 @@
 
 #include <linux/init.h>
 
-#define _DEV_TABLE_C_
 #include "sound_config.h"
 
+struct audio_operations *audio_devs[MAX_AUDIO_DEV];
+EXPORT_SYMBOL(audio_devs);
+
+int num_audiodevs;
+EXPORT_SYMBOL(num_audiodevs);
+
+struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
+EXPORT_SYMBOL(mixer_devs);
+
+int num_mixers;
+EXPORT_SYMBOL(num_mixers);
+
+struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV];
+EXPORT_SYMBOL(synth_devs);
+
+int num_synths;
+
+struct midi_operations *midi_devs[MAX_MIDI_DEV];
+EXPORT_SYMBOL(midi_devs);
+
+int num_midis;
+EXPORT_SYMBOL(num_midis);
+
+struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
+	&default_sound_timer, NULL
+};
+EXPORT_SYMBOL(sound_timer_devs);
+
+int num_sound_timers = 1;
+
+
 static int sound_alloc_audiodev(void);
 
 int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
@@ -75,6 +105,7 @@
 	audio_init_devices();
 	return num;
 }
+EXPORT_SYMBOL(sound_install_audiodrv);
 
 int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
 	int driver_size, void *devc)
@@ -113,6 +144,7 @@
 	mixer_devs[n] = op;
 	return n;
 }
+EXPORT_SYMBOL(sound_install_mixer);
 
 void sound_unload_audiodev(int dev)
 {
@@ -122,6 +154,7 @@
 		unregister_sound_dsp((dev<<4)+3);
 	}
 }
+EXPORT_SYMBOL(sound_unload_audiodev);
 
 static int sound_alloc_audiodev(void)
 { 
@@ -144,6 +177,7 @@
 		num_midis = i + 1;
 	return i;
 }
+EXPORT_SYMBOL(sound_alloc_mididev);
 
 int sound_alloc_synthdev(void)
 {
@@ -158,6 +192,7 @@
 	}
 	return -1;
 }
+EXPORT_SYMBOL(sound_alloc_synthdev);
 
 int sound_alloc_mixerdev(void)
 {
@@ -169,6 +204,7 @@
 		num_mixers = i + 1;
 	return i;
 }
+EXPORT_SYMBOL(sound_alloc_mixerdev);
 
 int sound_alloc_timerdev(void)
 {
@@ -183,6 +219,7 @@
 	}
 	return -1;
 }
+EXPORT_SYMBOL(sound_alloc_timerdev);
 
 void sound_unload_mixerdev(int dev)
 {
@@ -192,6 +229,7 @@
 		num_mixers--;
 	}
 }
+EXPORT_SYMBOL(sound_unload_mixerdev);
 
 void sound_unload_mididev(int dev)
 {
@@ -200,15 +238,19 @@
 		unregister_sound_midi((dev<<4)+2);
 	}
 }
+EXPORT_SYMBOL(sound_unload_mididev);
 
 void sound_unload_synthdev(int dev)
 {
 	if (dev != -1)
 		synth_devs[dev] = NULL;
 }
+EXPORT_SYMBOL(sound_unload_synthdev);
 
 void sound_unload_timerdev(int dev)
 {
 	if (dev != -1)
 		sound_timer_devs[dev] = NULL;
 }
+EXPORT_SYMBOL(sound_unload_timerdev);
+
diff --git a/sound/oss/dev_table.h b/sound/oss/dev_table.h
index adf1d62..b7617be 100644
--- a/sound/oss/dev_table.h
+++ b/sound/oss/dev_table.h
@@ -352,22 +352,8 @@
 	void (*arm_timer)(int dev, long time);
 };
 
-#ifdef _DEV_TABLE_C_   
-struct audio_operations *audio_devs[MAX_AUDIO_DEV];
-int num_audiodevs;
-struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
-int num_mixers;
-struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV];
-int num_synths;
-struct midi_operations *midi_devs[MAX_MIDI_DEV];
-int num_midis;
-
 extern struct sound_timer_operations default_sound_timer;
-struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
-	&default_sound_timer, NULL
-}; 
-int num_sound_timers = 1;
-#else
+
 extern struct audio_operations *audio_devs[MAX_AUDIO_DEV];
 extern int num_audiodevs;
 extern struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
@@ -378,7 +364,6 @@
 extern int num_midis;
 extern struct sound_timer_operations * sound_timer_devs[MAX_TIMER_DEV];
 extern int num_sound_timers;
-#endif	/* _DEV_TABLE_C_ */
 
 extern int sound_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc *info);
 void sound_timer_init (struct sound_lowlev_timer *t, char *name);
diff --git a/sound/oss/dm.h b/sound/oss/dm.h
deleted file mode 100644
index 14a9059..0000000
--- a/sound/oss/dm.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef _DRIVERS_SOUND_DM_H
-#define _DRIVERS_SOUND_DM_H
-
-/*
- *	Definitions of the 'direct midi sound' interface used
- *	by the newer commercial OSS package. We should export
- *	this to userland somewhere in glibc later.
- */
-
-/*
- * Data structure composing an FM "note" or sound event.
- */
-
-struct dm_fm_voice
-{
-	u8 op;
-	u8 voice;
-	u8 am;
-	u8 vibrato;
-	u8 do_sustain;
-	u8 kbd_scale;
-	u8 harmonic;
-	u8 scale_level;
-	u8 volume;
-	u8 attack;
-	u8 decay;
-	u8 sustain;
-	u8 release;
-	u8 feedback;
-	u8 connection;
-	u8 left;
-	u8 right;
-	u8 waveform;
-};
-
-/*
- *	This describes an FM note by its voice, octave, frequency number (10bit)
- *	and key on/off.
- */
-
-struct dm_fm_note
-{
-	u8 voice;
-	u8 octave;
-	u32 fnum;
-	u8 key_on;
-};
-
-/*
- * FM parameters that apply globally to all voices, and thus are not "notes"
- */
-
-struct dm_fm_params
-{
-	u8 am_depth;
-	u8 vib_depth;
-	u8 kbd_split;
-	u8 rhythm;
-
-	/* This block is the percussion instrument data */
-	u8 bass;
-	u8 snare;
-	u8 tomtom;
-	u8 cymbal;
-	u8 hihat;
-};
-
-/*
- *	FM mode ioctl settings
- */
- 
-#define FM_IOCTL_RESET        0x20
-#define FM_IOCTL_PLAY_NOTE    0x21
-#define FM_IOCTL_SET_VOICE    0x22
-#define FM_IOCTL_SET_PARAMS   0x23
-#define FM_IOCTL_SET_MODE     0x24
-#define FM_IOCTL_SET_OPL      0x25
-
-#endif
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c
index 15ce711..b256c04 100644
--- a/sound/oss/dmabuf.c
+++ b/sound/oss/dmabuf.c
@@ -1,5 +1,5 @@
 /*
- * sound/dmabuf.c
+ * sound/oss/dmabuf.c
  *
  * The DMA buffer manager for digitized voice applications
  */
@@ -926,6 +926,7 @@
 	sound_start_dma(dmap, physaddr, count, dma_mode);
 	return count;
 }
+EXPORT_SYMBOL(DMAbuf_start_dma);
 
 static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode)
 {
@@ -1055,6 +1056,8 @@
 		do_outputintr(dev, notify_only);
 	spin_unlock_irqrestore(&dmap->lock,flags);
 }
+EXPORT_SYMBOL(DMAbuf_outputintr);
+
 /* called with dmap->lock held in irq context */
 static void do_inputintr(int dev)
 {
@@ -1154,36 +1157,7 @@
 		do_inputintr(dev);
 	spin_unlock_irqrestore(&dmap->lock,flags);
 }
-
-int DMAbuf_open_dma(int dev)
-{
-	/*
-	 *    NOTE!  This routine opens only the primary DMA channel (output).
-	 */
-	struct audio_operations *adev = audio_devs[dev];
-	int err;
-
-	if ((err = open_dmap(adev, OPEN_READWRITE, adev->dmap_out)) < 0)
-		return -EBUSY;
-	dma_init_buffers(adev->dmap_out);
-	adev->dmap_out->flags |= DMA_ALLOC_DONE;
-	adev->dmap_out->fragment_size = adev->dmap_out->buffsize;
-
-	if (adev->dmap_out->dma >= 0) {
-		unsigned long flags;
-
-		flags=claim_dma_lock();
-		clear_dma_ff(adev->dmap_out->dma);
-		disable_dma(adev->dmap_out->dma);
-		release_dma_lock(flags);
-	}
-	return 0;
-}
-
-void DMAbuf_close_dma(int dev)
-{
-	close_dmap(audio_devs[dev], audio_devs[dev]->dmap_out);
-}
+EXPORT_SYMBOL(DMAbuf_inputintr);
 
 void DMAbuf_init(int dev, int dma1, int dma2)
 {
@@ -1192,12 +1166,6 @@
 	 * NOTE! This routine could be called several times.
 	 */
 
-	/* drag in audio_syms.o */
-	{
-		extern char audio_syms_symbol;
-		audio_syms_symbol = 0;
-	}
-
 	if (adev && adev->dmap_out == NULL) {
 		if (adev->d == NULL)
 			panic("OSS: audio_devs[%d]->d == NULL\n", dev);
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c
deleted file mode 100644
index 13f4831..0000000
--- a/sound/oss/es1370.c
+++ /dev/null
@@ -1,2819 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      es1370.c  --  Ensoniq ES1370/Asahi Kasei AK4531 audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi
- *
- *
- * Module command line parameters:
- *   lineout  if 1 the LINE jack is used as an output instead of an input.
- *            LINE then contains the unmixed dsp output. This can be used
- *            to make the card a four channel one: use dsp to output two
- *            channels to LINE and dac to output the other two channels to
- *            SPKR. Set the mixer to only output synth to SPKR.
- *   micbias  sets the +5V bias to the mic if using an electretmic.
- *            
- *
- *  Note: sync mode is not yet supported (i.e. running dsp and dac from the same
- *  clock source)
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/dsp1   additional DAC, like /dev/dsp, but output only,
- *              only 5512, 11025, 22050 and 44100 samples/s,
- *              outputs to mixer "SYNTH" setting
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed
- *  to be done in software. That is what /dev/dac is for. By now (Q2 1998)
- *  there are several MIDI to PCM (WAV) packages, one of them is timidity.
- *
- *  Revision history
- *    26.03.1998   0.1   Initial release
- *    31.03.1998   0.2   Fix bug in GETOSPACE
- *    04.04.1998   0.3   Make it work (again) under 2.0.33
- *                       Fix mixer write operation not returning the actual
- *                       settings
- *    05.04.1998   0.4   First attempt at using the new PCI stuff
- *    29.04.1998   0.5   Fix hang when ^C is pressed on amp
- *    07.05.1998   0.6   Don't double lock around stop_*() in *_release()
- *    10.05.1998   0.7   First stab at a simple midi interface (no bells&whistles)
- *    14.05.1998   0.8   Don't allow excessive interrupt rates
- *    08.06.1998   0.9   First release using Alan Cox' soundcore instead of
- *                       miscdevice
- *    05.07.1998   0.10  Fixed the driver to correctly maintin OSS style volume
- *                       settings (not sure if this should be standard)
- *                       Fixed many references: f_flags should be f_mode
- *                       -- Gerald Britton <gbritton@mit.edu>
- *    03.08.1998   0.11  Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *                       Fixed mixer table thanks to Hakan.Lennestal@lu.erisoft.se
- *                       On module startup, set DAC2 to 11kSPS instead of 5.5kSPS,
- *                       as it produces an annoying ssssh in the lower sampling rate
- *                       Do not include modversions.h
- *    22.08.1998   0.12  Mixer registers actually have 5 instead of 4 bits
- *                       pointed out by Itai Nahshon
- *    31.08.1998   0.13  Fix realplayer problems - dac.count issues
- *    08.10.1998   0.14  Joystick support fixed
- *		         -- Oliver Neukum <c188@org.chemie.uni-muenchen.de>
- *    10.12.1998   0.15  Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.1998   0.16  Don't wake up app until there are fragsize bytes to read/write
- *    06.01.1999   0.17  remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.18  cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.19  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.20  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Note: joystick address handling might still be wrong on archs
- *                       other than i386
- *    10.05.1999   0.21  Added support for an electret mic for SB PCI64
- *                       to the Linux kernel sound driver. This mod also straighten
- *                       out the question marks around the mic impedance setting
- *                       (micz). From Kim.Berts@fisub.mail.abb.com
- *    11.05.1999   0.22  Implemented the IMIX call to mute recording monitor.
- *                       Guenter Geiger <geiger@epy.co.at>
- *    15.06.1999   0.23  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.24  Add pci_set_master
- *    02.08.1999   0.25  Added workaround for the "phantom write" bug first
- *                       documented by Dave Sharpless from Anchor Games
- *    03.08.1999   0.26  adapt to Linus' new __setup/__initcall
- *                       added kernel command line option "es1370=joystick[,lineout[,micbias]]"
- *                       removed CONFIG_SOUND_ES1370_JOYPORT_BOOT kludge
- *    12.08.1999   0.27  module_init/__setup fixes
- *    19.08.1999   0.28  SOUND_MIXER_IMIX fixes, reported by Gianluca <gialluca@mail.tiscalinet.it>
- *    31.08.1999   0.29  add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.30  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    28.10.1999   0.31  More waitqueue races fixed
- *    08.01.2000   0.32  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *    07.02.2000   0.33  Use pci_alloc_consistent and pci_register_driver
- *    21.11.2000   0.34  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.35  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    07.01.2001   0.36  Timeout change in wrcodec as requested by Frank Klemm <pfk@fuchs.offl.uni-jena.de>
- *    31.01.2001   0.37  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    03.01.2003   0.38  open_mode fixes from Georg Acher <acher@in.tum.de>
- *
- * some important things missing in Ensoniq documentation:
- *
- * Experimental PCLKDIV results:  play the same waveforms on both DAC1 and DAC2
- * and vary PCLKDIV to obtain zero beat.
- *  5512sps:  254
- * 44100sps:   30
- * seems to be fs = 1411200/(PCLKDIV+2)
- *
- * should find out when curr_sample_ct is cleared and
- * where exactly the CCB fetches data
- *
- * The card uses a 22.5792 MHz crystal.
- * The LINEIN jack may be converted to an AOUT jack by
- * setting pin 47 (XCTL0) of the ES1370 to high.
- * Pin 48 (XCTL1) of the ES1370 sets the +5V bias for an electretmic
- * 
- *
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define DBG(x) {}
-/*#define DBG(x) {x}*/
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ENSONIQ
-#define PCI_VENDOR_ID_ENSONIQ        0x1274    
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1370
-#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
-#endif
-
-#define ES1370_MAGIC  ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1370)
-
-#define ES1370_EXTENT             0x40
-#define JOY_EXTENT                8
-
-#define ES1370_REG_CONTROL        0x00
-#define ES1370_REG_STATUS         0x04
-#define ES1370_REG_UART_DATA      0x08
-#define ES1370_REG_UART_STATUS    0x09
-#define ES1370_REG_UART_CONTROL   0x09
-#define ES1370_REG_UART_TEST      0x0a
-#define ES1370_REG_MEMPAGE        0x0c
-#define ES1370_REG_CODEC          0x10
-#define ES1370_REG_SERIAL_CONTROL 0x20
-#define ES1370_REG_DAC1_SCOUNT    0x24
-#define ES1370_REG_DAC2_SCOUNT    0x28
-#define ES1370_REG_ADC_SCOUNT     0x2c
-
-#define ES1370_REG_DAC1_FRAMEADR    0xc30
-#define ES1370_REG_DAC1_FRAMECNT    0xc34
-#define ES1370_REG_DAC2_FRAMEADR    0xc38
-#define ES1370_REG_DAC2_FRAMECNT    0xc3c
-#define ES1370_REG_ADC_FRAMEADR     0xd30
-#define ES1370_REG_ADC_FRAMECNT     0xd34
-#define ES1370_REG_PHANTOM_FRAMEADR 0xd38
-#define ES1370_REG_PHANTOM_FRAMECNT 0xd3c
-
-#define ES1370_FMT_U8_MONO     0
-#define ES1370_FMT_U8_STEREO   1
-#define ES1370_FMT_S16_MONO    2
-#define ES1370_FMT_S16_STEREO  3
-#define ES1370_FMT_STEREO      1
-#define ES1370_FMT_S16         2
-#define ES1370_FMT_MASK        3
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-static const unsigned dac1_samplerate[] = { 5512, 11025, 22050, 44100 };
-
-#define DAC2_SRTODIV(x) (((1411200+(x)/2)/(x))-2)
-#define DAC2_DIVTOSR(x) (1411200/((x)+2))
-
-#define CTRL_ADC_STOP   0x80000000  /* 1 = ADC stopped */
-#define CTRL_XCTL1      0x40000000  /* electret mic bias */
-#define CTRL_OPEN       0x20000000  /* no function, can be read and written */
-#define CTRL_PCLKDIV    0x1fff0000  /* ADC/DAC2 clock divider */
-#define CTRL_SH_PCLKDIV 16
-#define CTRL_MSFMTSEL   0x00008000  /* MPEG serial data fmt: 0 = Sony, 1 = I2S */
-#define CTRL_M_SBB      0x00004000  /* DAC2 clock: 0 = PCLKDIV, 1 = MPEG */
-#define CTRL_WTSRSEL    0x00003000  /* DAC1 clock freq: 0=5512, 1=11025, 2=22050, 3=44100 */
-#define CTRL_SH_WTSRSEL 12
-#define CTRL_DAC_SYNC   0x00000800  /* 1 = DAC2 runs off DAC1 clock */
-#define CTRL_CCB_INTRM  0x00000400  /* 1 = CCB "voice" ints enabled */
-#define CTRL_M_CB       0x00000200  /* recording source: 0 = ADC, 1 = MPEG */
-#define CTRL_XCTL0      0x00000100  /* 0 = Line in, 1 = Line out */
-#define CTRL_BREQ       0x00000080  /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN    0x00000040  /* enable DAC1 */
-#define CTRL_DAC2_EN    0x00000020  /* enable DAC2 */
-#define CTRL_ADC_EN     0x00000010  /* enable ADC */
-#define CTRL_UART_EN    0x00000008  /* enable MIDI uart */
-#define CTRL_JYSTK_EN   0x00000004  /* enable Joystick port (presumably at address 0x200) */
-#define CTRL_CDC_EN     0x00000002  /* enable serial (CODEC) interface */
-#define CTRL_SERR_DIS   0x00000001  /* 1 = disable PCI SERR signal */
-
-#define STAT_INTR       0x80000000  /* wired or of all interrupt bits */
-#define STAT_CSTAT      0x00000400  /* 1 = codec busy or codec write in progress */
-#define STAT_CBUSY      0x00000200  /* 1 = codec busy */
-#define STAT_CWRIP      0x00000100  /* 1 = codec write in progress */
-#define STAT_VC         0x00000060  /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
-#define STAT_SH_VC      5
-#define STAT_MCCB       0x00000010  /* CCB int pending */
-#define STAT_UART       0x00000008  /* UART int pending */
-#define STAT_DAC1       0x00000004  /* DAC1 int pending */
-#define STAT_DAC2       0x00000002  /* DAC2 int pending */
-#define STAT_ADC        0x00000001  /* ADC int pending */
-
-#define USTAT_RXINT     0x80        /* UART rx int pending */
-#define USTAT_TXINT     0x04        /* UART tx int pending */
-#define USTAT_TXRDY     0x02        /* UART tx ready */
-#define USTAT_RXRDY     0x01        /* UART rx ready */
-
-#define UCTRL_RXINTEN   0x80        /* 1 = enable RX ints */
-#define UCTRL_TXINTEN   0x60        /* TX int enable field mask */
-#define UCTRL_ENA_TXINT 0x20        /* enable TX int */
-#define UCTRL_CNTRL     0x03        /* control field */
-#define UCTRL_CNTRL_SWR 0x03        /* software reset command */
-
-#define SCTRL_P2ENDINC    0x00380000  /*  */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC     0x00070000  /*  */
-#define SCTRL_SH_P2STINC  16
-#define SCTRL_R1LOOPSEL   0x00008000  /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL   0x00004000  /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL   0x00002000  /* 0 = loop mode */
-#define SCTRL_P2PAUSE     0x00001000  /* 1 = pause mode */
-#define SCTRL_P1PAUSE     0x00000800  /* 1 = pause mode */
-#define SCTRL_R1INTEN     0x00000400  /* enable interrupt */
-#define SCTRL_P2INTEN     0x00000200  /* enable interrupt */
-#define SCTRL_P1INTEN     0x00000100  /* enable interrupt */
-#define SCTRL_P1SCTRLD    0x00000080  /* reload sample count register for DAC1 */
-#define SCTRL_P2DACSEN    0x00000040  /* 1 = DAC2 play back last sample when disabled */
-#define SCTRL_R1SEB       0x00000020  /* 1 = 16bit */
-#define SCTRL_R1SMB       0x00000010  /* 1 = stereo */
-#define SCTRL_R1FMT       0x00000030  /* format mask */
-#define SCTRL_SH_R1FMT    4
-#define SCTRL_P2SEB       0x00000008  /* 1 = 16bit */
-#define SCTRL_P2SMB       0x00000004  /* 1 = stereo */
-#define SCTRL_P2FMT       0x0000000c  /* format mask */
-#define SCTRL_SH_P2FMT    2
-#define SCTRL_P1SEB       0x00000002  /* 1 = 16bit */
-#define SCTRL_P1SMB       0x00000001  /* 1 = stereo */
-#define SCTRL_P1FMT       0x00000003  /* format mask */
-#define SCTRL_SH_P1FMT    0
-
-/* misc stuff */
-
-#define FMODE_DAC         4           /* slight misuse of mode_t */
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-/* --------------------------------------------------------------------- */
-
-struct es1370_state {
-	/* magic */
-	unsigned int magic;
-
-	/* list of es1370 devices */
-	struct list_head devs;
-
-	/* the corresponding pci_dev structure */
-	struct pci_dev *dev;
-
-	/* soundcore stuff */
-	int dev_audio;
-	int dev_mixer;
-	int dev_dac;
-	int dev_midi;
-	
-	/* hardware resources */
-	unsigned long io; /* long for SPARC */
-	unsigned int irq;
-
-	/* mixer registers; there is no HW readback */
-	struct {
-		unsigned short vol[10];
-		unsigned int recsrc;
-		unsigned int modcnt;
-		unsigned short micpreamp;
-	        unsigned int imix;
-	} mix;
-
-	/* wave stuff */
-	unsigned ctrl;
-	unsigned sctrl;
-
-	spinlock_t lock;
-	struct mutex open_mutex;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-
-	struct dmabuf {
-		void *rawbuf;
-		dma_addr_t dmaaddr;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-		unsigned hwptr, swptr;
-		unsigned total_bytes;
-		int count;
-		unsigned error; /* over/underrun */
-		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;
-		unsigned dmasize;
-		unsigned fragsamples;
-		/* OSS stuff */
-		unsigned mapped:1;
-		unsigned ready:1;
-		unsigned endcleared:1;
-		unsigned enabled:1;
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac1, dma_dac2, dma_adc;
-
-	/* The following buffer is used to point the phantom write channel to. */
-	unsigned char *bugbuf_cpu;
-	dma_addr_t bugbuf_dma;
-
-	/* midi stuff */
-	struct {
-		unsigned ird, iwr, icnt;
-		unsigned ord, owr, ocnt;
-		wait_queue_head_t iwait;
-		wait_queue_head_t owait;
-		unsigned char ibuf[MIDIINBUF];
-		unsigned char obuf[MIDIOUTBUF];
-	} midi;
-
-#ifdef SUPPORT_JOYSTICK
-	struct gameport *gameport;
-#endif
-
-	struct mutex mutex;
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned r = 0;
-	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wrcodec(struct es1370_state *s, unsigned char idx, unsigned char data)
-{
-	unsigned long tmo = jiffies + HZ/10, j;
-	
-	do {
-		j = jiffies;
-		if (!(inl(s->io+ES1370_REG_STATUS) & STAT_CSTAT)) {
-			outw((((unsigned short)idx)<<8)|data, s->io+ES1370_REG_CODEC);
-			return;
-		}
-		schedule();
-	} while ((signed)(tmo-j) > 0);
-	printk(KERN_ERR "es1370: write to codec register timeout\n");
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct es1370_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ctrl &= ~CTRL_ADC_EN;
-	outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static inline void stop_dac1(struct es1370_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ctrl &= ~CTRL_DAC1_EN;
-	outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static inline void stop_dac2(struct es1370_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ctrl &= ~CTRL_DAC2_EN;
-	outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_dac1(struct es1370_state *s)
-{
-	unsigned long flags;
-	unsigned fragremain, fshift;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0)
-	    && s->dma_dac1.ready) {
-		s->ctrl |= CTRL_DAC1_EN;
-		s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN;
-		outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-		fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1));
-		fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-		if (fragremain < 2*fshift)
-			fragremain = s->dma_dac1.fragsize;
-		outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT);
-		outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-		outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_dac2(struct es1370_state *s)
-{
-	unsigned long flags;
-	unsigned fragremain, fshift;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0)
-	    && s->dma_dac2.ready) {
-		s->ctrl |= CTRL_DAC2_EN;
-		s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | 
-					 SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN |
-			(((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | 
-			(0 << SCTRL_SH_P2STINC);
-		outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-		fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1));
-		fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-		if (fragremain < 2*fshift)
-			fragremain = s->dma_dac2.fragsize;
-		outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT);
-		outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-		outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_adc(struct es1370_state *s)
-{
-	unsigned long flags;
-	unsigned fragremain, fshift;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-	    && s->dma_adc.ready) {
-		s->ctrl |= CTRL_ADC_EN;
-		s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN;
-		outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-		fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1));
-		fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT];
-		if (fragremain < 2*fshift)
-			fragremain = s->dma_adc.fragsize;
-		outl((fragremain >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT);
-		outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-		outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct es1370_state *s, struct dmabuf *db)
-{
-	struct page *page, *pend;
-
-	if (db->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			ClearPageReserved(page);
-		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-	}
-	db->rawbuf = NULL;
-	db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct es1370_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg)
-{
-	int order;
-	unsigned bytepersec;
-	unsigned bufs;
-	struct page *page, *pend;
-
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-				break;
-		if (!db->rawbuf)
-			return -ENOMEM;
-		db->buforder = order;
-		/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			SetPageReserved(page);
-	}
-	fmt &= ES1370_FMT_MASK;
-	bytepersec = rate << sample_shift[fmt];
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < bytepersec)
-			db->fragshift = ld2(bytepersec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3;
-	}
-	db->numfrag = bufs >> db->fragshift;
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->numfrag = bufs >> db->fragshift;
-	}
-	db->fragsize = 1 << db->fragshift;
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
-	db->fragsamples = db->fragsize >> sample_shift[fmt];
-	db->dmasize = db->numfrag << db->fragshift;
-	memset(db->rawbuf, (fmt & ES1370_FMT_S16) ? 0 : 0x80, db->dmasize);
-	outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-	outl(db->dmaaddr, s->io+(reg & 0xff));
-	outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff));
-	db->enabled = 1;
-	db->ready = 1;
-	return 0;
-}
-
-static inline int prog_dmabuf_adc(struct es1370_state *s)
-{
-	stop_adc(s);
-	return prog_dmabuf(s, &s->dma_adc, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV),
-			   (s->sctrl >> SCTRL_SH_R1FMT) & ES1370_FMT_MASK, ES1370_REG_ADC_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac2(struct es1370_state *s)
-{
-	stop_dac2(s);
-	return prog_dmabuf(s, &s->dma_dac2, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV),
-			   (s->sctrl >> SCTRL_SH_P2FMT) & ES1370_FMT_MASK, ES1370_REG_DAC2_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac1(struct es1370_state *s)
-{
-	stop_dac1(s);
-	return prog_dmabuf(s, &s->dma_dac1, dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL],
-			   (s->sctrl >> SCTRL_SH_P1FMT) & ES1370_FMT_MASK, ES1370_REG_DAC1_FRAMEADR);
-}
-
-static inline unsigned get_hwptr(struct es1370_state *s, struct dmabuf *db, unsigned reg)
-{
-	unsigned hwptr, diff;
-
-	outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-	hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc;
-	diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize;
-	db->hwptr = hwptr;
-	return diff;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(((char *)buf) + bptr, c, x);
-		bptr = 0;
-		len -= x;
-	}
-	memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void es1370_update_ptr(struct es1370_state *s)
-{
-	int diff;
-
-	/* update ADC pointer */
-	if (s->ctrl & CTRL_ADC_EN) {
-		diff = get_hwptr(s, &s->dma_adc, ES1370_REG_ADC_FRAMECNT);
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-			wake_up(&s->dma_adc.wait);
-		if (!s->dma_adc.mapped) {
-			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-				s->ctrl &= ~CTRL_ADC_EN;
-				outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-				s->dma_adc.error++;
-			}
-		}
-	}
-	/* update DAC1 pointer */
-	if (s->ctrl & CTRL_DAC1_EN) {
-		diff = get_hwptr(s, &s->dma_dac1, ES1370_REG_DAC1_FRAMECNT);
-		s->dma_dac1.total_bytes += diff;
-		if (s->dma_dac1.mapped) {
-			s->dma_dac1.count += diff;
-			if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-				wake_up(&s->dma_dac1.wait);
-		} else {
-			s->dma_dac1.count -= diff;
-			if (s->dma_dac1.count <= 0) {
-				s->ctrl &= ~CTRL_DAC1_EN;
-				outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-				s->dma_dac1.error++;
-			} else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) {
-				clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, 
-					      s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
-				s->dma_dac1.endcleared = 1;
-			}
-			if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
-				wake_up(&s->dma_dac1.wait);
-		}
-	}
-	/* update DAC2 pointer */
-	if (s->ctrl & CTRL_DAC2_EN) {
-		diff = get_hwptr(s, &s->dma_dac2, ES1370_REG_DAC2_FRAMECNT);
-		s->dma_dac2.total_bytes += diff;
-		if (s->dma_dac2.mapped) {
-			s->dma_dac2.count += diff;
-			if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize)
-				wake_up(&s->dma_dac2.wait);
-		} else {
-			s->dma_dac2.count -= diff;
-			if (s->dma_dac2.count <= 0) {
-				s->ctrl &= ~CTRL_DAC2_EN;
-				outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-				s->dma_dac2.error++;
-			} else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) {
-				clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, 
-					      s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
-				s->dma_dac2.endcleared = 1;
-			}
-			if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
-				wake_up(&s->dma_dac2.wait);
-		}
-	}
-}
-
-/* hold spinlock for the following! */
-static void es1370_handle_midi(struct es1370_state *s)
-{
-	unsigned char ch;
-	int wake;
-
-	if (!(s->ctrl & CTRL_UART_EN))
-		return;
-	wake = 0;
-	while (inb(s->io+ES1370_REG_UART_STATUS) & USTAT_RXRDY) {
-		ch = inb(s->io+ES1370_REG_UART_DATA);
-		if (s->midi.icnt < MIDIINBUF) {
-			s->midi.ibuf[s->midi.iwr] = ch;
-			s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-			s->midi.icnt++;
-		}
-		wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.iwait);
-	wake = 0;
-	while ((inb(s->io+ES1370_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) {
-		outb(s->midi.obuf[s->midi.ord], s->io+ES1370_REG_UART_DATA);
-		s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-		s->midi.ocnt--;
-		if (s->midi.ocnt < MIDIOUTBUF-16)
-			wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.owait);
-	outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1370_REG_UART_CONTROL);
-}
-
-static irqreturn_t es1370_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct es1370_state *s = (struct es1370_state *)dev_id;
-	unsigned int intsrc, sctl;
-	
-	/* fastpath out, to ease interrupt sharing */
-	intsrc = inl(s->io+ES1370_REG_STATUS);
-	if (!(intsrc & 0x80000000))
-		return IRQ_NONE;
-	spin_lock(&s->lock);
-	/* clear audio interrupts first */
-	sctl = s->sctrl;
-	if (intsrc & STAT_ADC)
-		sctl &= ~SCTRL_R1INTEN;
-	if (intsrc & STAT_DAC1)
-		sctl &= ~SCTRL_P1INTEN;
-	if (intsrc & STAT_DAC2)
-		sctl &= ~SCTRL_P2INTEN;
-	outl(sctl, s->io+ES1370_REG_SERIAL_CONTROL);
-	outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-	es1370_update_ptr(s);
-	es1370_handle_midi(s);
-	spin_unlock(&s->lock);
-	return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "es1370: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-	if (!(s) || (s)->magic != ES1370_MAGIC) { \
-		printk(invalid_magic);            \
-		return -ENXIO;                    \
-	}                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-static const struct {
-	unsigned volidx:4;
-	unsigned left:4;
-	unsigned right:4;
-	unsigned stereo:1;
-	unsigned recmask:13;
-	unsigned avail:1;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-	[SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x0000, 1 },   /* master */
-	[SOUND_MIXER_PCM]    = { 1, 0x2, 0x3, 1, 0x0400, 1 },   /* voice */
-	[SOUND_MIXER_SYNTH]  = { 2, 0x4, 0x5, 1, 0x0060, 1 },   /* FM */
-	[SOUND_MIXER_CD]     = { 3, 0x6, 0x7, 1, 0x0006, 1 },   /* CD */
-	[SOUND_MIXER_LINE]   = { 4, 0x8, 0x9, 1, 0x0018, 1 },   /* Line */
-	[SOUND_MIXER_LINE1]  = { 5, 0xa, 0xb, 1, 0x1800, 1 },   /* AUX */
-	[SOUND_MIXER_LINE2]  = { 6, 0xc, 0x0, 0, 0x0100, 1 },   /* Mono1 */
-	[SOUND_MIXER_LINE3]  = { 7, 0xd, 0x0, 0, 0x0200, 1 },   /* Mono2 */
-	[SOUND_MIXER_MIC]    = { 8, 0xe, 0x0, 0, 0x0001, 1 },   /* Mic */
-	[SOUND_MIXER_OGAIN]  = { 9, 0xf, 0x0, 0, 0x0000, 1 }    /* mono out */
-};
-
-static void set_recsrc(struct es1370_state *s, unsigned int val)
-{
-	unsigned int i, j;
-
-	for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-		if (!(val & (1 << i)))
-			continue;
-		if (!mixtable[i].recmask) {
-			val &= ~(1 << i);
-			continue;
-		}
-		j |= mixtable[i].recmask;
-	}
-	s->mix.recsrc = val;
-	wrcodec(s, 0x12, j & 0xd5);
-	wrcodec(s, 0x13, j & 0xaa);
-	wrcodec(s, 0x14, (j >> 8) & 0x17);
-	wrcodec(s, 0x15, (j >> 8) & 0x0f);
-	i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc60;
-	if (!s->mix.imix) {
-		i &= 0xff60;  /* mute record and line monitor */
-	}
-	wrcodec(s, 0x10, i);
-	wrcodec(s, 0x11, i >> 8);
-}
-
-static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long arg)
-{
-	unsigned long flags;
-	int i, val;
-	unsigned char l, r, rl, rr;
-	int __user *p = (int __user *)arg;
-
-	VALIDATE_STATE(s);
-	if (cmd == SOUND_MIXER_PRIVATE1) {
-		/* enable/disable/query mixer preamp */
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != -1) {
-			s->mix.micpreamp = !!val;
-			wrcodec(s, 0x19, s->mix.micpreamp);
-		}
-		return put_user(s->mix.micpreamp, p);
-	}
-	if (cmd == SOUND_MIXER_PRIVATE2) {
-		/* enable/disable/query use of linein as second lineout */
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != -1) {
-			spin_lock_irqsave(&s->lock, flags);
-			if (val)
-				s->ctrl |= CTRL_XCTL0;
-			else
-				s->ctrl &= ~CTRL_XCTL0;
-			outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user((s->ctrl & CTRL_XCTL0) ? 1 : 0, p);
-	}
-	if (cmd == SOUND_MIXER_PRIVATE3) {
-		/* enable/disable/query microphone impedance setting */
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != -1) {
-			spin_lock_irqsave(&s->lock, flags);
-			if (val)
-				s->ctrl |= CTRL_XCTL1;
-			else
-				s->ctrl &= ~CTRL_XCTL1;
-			outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user((s->ctrl & CTRL_XCTL1) ? 1 : 0, p);
-	}
-        if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		strncpy(info.id, "ES1370", sizeof(info.id));
-		strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
-		info.modify_counter = s->mix.modcnt;
-		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == SOUND_OLD_MIXER_INFO) {
-		_old_mixer_info info;
-		strncpy(info.id, "ES1370", sizeof(info.id));
-		strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
-		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, p);
-	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-			return put_user(s->mix.recsrc, p);
-			
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-			val = SOUND_MASK_IMIX;
-			for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].avail)
-					val |= 1 << i;
-			return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].recmask)
-					val |= 1 << i;
-			return put_user(val, p);
-			
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].stereo)
-					val |= 1 << i;
-			return put_user(val, p);
-			
-                case SOUND_MIXER_CAPS:
-			return put_user(0, p);
-		
-		case SOUND_MIXER_IMIX:
-			return put_user(s->mix.imix, p);
-
-		default:
-			i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
-                                return -EINVAL;
-			return put_user(s->mix.vol[mixtable[i].volidx], p);
-		}
-	}
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-		return -EINVAL;
-	s->mix.modcnt++;
-	switch (_IOC_NR(cmd)) {
-
-	case SOUND_MIXER_IMIX:
-		if (get_user(s->mix.imix, p))
-			return -EFAULT;
-		set_recsrc(s, s->mix.recsrc);
-		return 0;
-
-	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-		if (get_user(val, p))
-			return -EFAULT;
-		set_recsrc(s, val);
-		return 0;
-
-	default:
-		i = _IOC_NR(cmd);
-		if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
-			return -EINVAL;
-		if (get_user(val, p))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (mixtable[i].stereo) {
-			r = (val >> 8) & 0xff;
-			if (r > 100)
-				r = 100;
-			if (l < 7) {
-				rl = 0x80;
-				l = 0;
-			} else {
-				rl = 31 - ((l - 7) / 3);
-				l = (31 - rl) * 3 + 7;
-			}
-			if (r < 7) {
-				rr = 0x80;
-				r = 0;
-			} else {
-				rr =  31 - ((r - 7) / 3);
-				r = (31 - rr) * 3 + 7;
-			}
-			wrcodec(s, mixtable[i].right, rr);
-		} else { 
-			if (mixtable[i].left == 15) {
-				if (l < 2) {
-					rr = rl = 0x80;
-					r = l = 0;
-				} else {
-					rl = 7 - ((l - 2) / 14);
-					r = l = (7 - rl) * 14 + 2;
-				}
-			} else {
-				if (l < 7) {
-					rl = 0x80;
-					r = l = 0;
-				} else {
-					rl = 31 - ((l - 7) / 3);
-					r = l = (31 - rl) * 3 + 7;
-				}
-			}
-		}
-		wrcodec(s, mixtable[i].left, rl);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[mixtable[i].volidx] = ((unsigned int)r << 8) | l;
-#else
-		s->mix.vol[mixtable[i].volidx] = val;
-#endif
-                return put_user(s->mix.vol[mixtable[i].volidx], p);
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static int es1370_open_mixdev(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	struct list_head *list;
-	struct es1370_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1370_state, devs);
-		if (s->dev_mixer == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	return nonseekable_open(inode, file);
-}
-
-static int es1370_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	
-	VALIDATE_STATE(s);
-	return 0;
-}
-
-static int es1370_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	return mixer_ioctl((struct es1370_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations es1370_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= es1370_ioctl_mixdev,
-	.open		= es1370_open_mixdev,
-	.release	= es1370_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac1(struct es1370_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count, tmo;
-	
-	if (s->dma_dac1.mapped || !s->dma_dac1.ready)
-		return 0;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-        for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac1.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac1.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-		tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2
-			/ dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL];
-		tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-		if (!schedule_timeout(tmo + 1))
-			DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-static int drain_dac2(struct es1370_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count, tmo;
-
-	if (s->dma_dac2.mapped || !s->dma_dac2.ready)
-		return 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-        for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac2.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac2.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-		tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2
-			/ DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV);
-		tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-		if (!schedule_timeout(tmo + 1))
-			DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret = 0;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	mutex_lock(&s->mutex);
-	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-		goto out;
-        
-	add_wait_queue(&s->dma_adc.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		swptr = s->dma_adc.swptr;
-		cnt = s->dma_adc.dmasize-swptr;
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_adc.enabled)
-				start_adc(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto out;
-			}
-			mutex_unlock(&s->mutex);
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				goto out;
-			}
-			mutex_lock(&s->mutex);
-			if (s->dma_adc.mapped)
-			{
-				ret = -ENXIO;
-				goto out;
-			}
-			continue;
-		}
-		if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			goto out;
-		}
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_adc.enabled)
-			start_adc(s);
-	}
-out:
-	mutex_unlock(&s->mutex);
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret = 0;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_dac2.mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	mutex_lock(&s->mutex);
-	if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-		goto out;
-	ret = 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac2.count < 0) {
-			s->dma_dac2.count = 0;
-			s->dma_dac2.swptr = s->dma_dac2.hwptr;
-		}
-		swptr = s->dma_dac2.swptr;
-		cnt = s->dma_dac2.dmasize-swptr;
-		if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize)
-			cnt = s->dma_dac2.dmasize - s->dma_dac2.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_dac2.enabled)
-				start_dac2(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto out;
-			}
-			mutex_unlock(&s->mutex);
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				goto out;	
-			}
-			mutex_lock(&s->mutex);
-			if (s->dma_dac2.mapped)
-			{
-			ret = -ENXIO;
-			goto out;
-			}
-			continue;
-		}
-		if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			goto out;
-		}
-		swptr = (swptr + cnt) % s->dma_dac2.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac2.swptr = swptr;
-		s->dma_dac2.count += cnt;
-		s->dma_dac2.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_dac2.enabled)
-			start_dac2(s);
-	}
-out:
-	mutex_unlock(&s->mutex);
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
-			return 0;
-		poll_wait(file, &s->dma_dac2.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	es1370_update_ptr(s);
-	if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac2.mapped) {
-			if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int es1370_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	struct dmabuf *db;
-	int ret = 0;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	mutex_lock(&s->mutex);
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf_dac2(s)) != 0) {
-			goto out;
-		}
-		db = &s->dma_dac2;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf_adc(s)) != 0) {
-			goto out;
-		}
-		db = &s->dma_adc;
-	} else  {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (vma->vm_pgoff != 0) {
-		ret = -EINVAL;
-		goto out;
-	}
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder)) {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (remap_pfn_range(vma, vma->vm_start,
-				virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-				size, vma->vm_page_prot)) {
-		ret = -EAGAIN;
-		goto out;
-	}
-	db->mapped = 1;
-out:
-	mutex_unlock(&s->mutex);
-	unlock_kernel();
-	return ret;
-}
-
-static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int count;
-	int val, mapped, ret;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-		return 0;
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac2(s);
-			synchronize_irq(s->irq);
-			s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->irq);
-			s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			if (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
-				return -EINVAL;
-			if (val < 4000)
-				val = 4000;
-			if (val > 50000)
-				val = 50000;
-			stop_adc(s);
-			stop_dac2(s);
-			s->dma_adc.ready = s->dma_dac2.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV);
-			outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
-		
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val)
-				s->sctrl |= SCTRL_R1SMB;
-			else
-				s->sctrl &= ~SCTRL_R1SMB;
-			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac2(s);
-			s->dma_dac2.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val)
-				s->sctrl |= SCTRL_P2SMB;
-			else
-				s->sctrl &= ~SCTRL_P2SMB;
-			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-                }
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val >= 2)
-					s->sctrl |= SCTRL_R1SMB;
-				else
-					s->sctrl &= ~SCTRL_R1SMB;
-				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac2(s);
-				s->dma_dac2.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val >= 2)
-					s->sctrl |= SCTRL_P2SMB;
-				else
-					s->sctrl &= ~SCTRL_P2SMB;
-				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-		}
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-		
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-		
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val == AFMT_S16_LE)
-					s->sctrl |= SCTRL_R1SEB;
-				else
-					s->sctrl &= ~SCTRL_R1SEB;
-				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac2(s);
-				s->dma_dac2.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val == AFMT_S16_LE)
-					s->sctrl |= SCTRL_P2SEB;
-				else
-					s->sctrl &= ~SCTRL_P2SEB;
-				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-		}
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-				AFMT_S16_LE : AFMT_U8, p);
-		
-	case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, p);
-		
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-					return ret;
-				s->dma_adc.enabled = 1;
-				start_adc(s);
-			} else {
-				s->dma_adc.enabled = 0;
-				stop_adc(s);
-			}
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-					return ret;
-				s->dma_dac2.enabled = 1;
-				start_dac2(s);
-			} else {
-				s->dma_dac2.enabled = 0;
-				stop_dac2(s);
-			}
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-		abinfo.fragsize = s->dma_dac2.fragsize;
-		count = s->dma_dac2.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = s->dma_dac2.dmasize - count;
-                abinfo.fragstotal = s->dma_dac2.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-		abinfo.fragsize = s->dma_adc.fragsize;
-		count = s->dma_adc.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-		
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-                count = s->dma_dac2.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-		count = s->dma_adc.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-                cinfo.bytes = s->dma_dac2.total_bytes;
-		count = s->dma_dac2.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_dac2.fragshift;
-                cinfo.ptr = s->dma_dac2.hwptr;
-		if (s->dma_dac2.mapped)
-			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf_dac2(s)))
-				return val;
-			return put_user(s->dma_dac2.fragsize, p);
-		}
-		if ((val = prog_dmabuf_adc(s)))
-			return val;
-		return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			s->dma_dac2.ossfragshift = val & 0xffff;
-			s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac2.ossfragshift < 4)
-				s->dma_dac2.ossfragshift = 4;
-			if (s->dma_dac2.ossfragshift > 15)
-				s->dma_dac2.ossfragshift = 15;
-			if (s->dma_dac2.ossmaxfrags < 4)
-				s->dma_dac2.ossmaxfrags = 4;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE)
-			s->dma_dac2.subdivision = val;
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ?
-				2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-				16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-	return mixer_ioctl(s, cmd, arg);
-}
-
-static int es1370_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct es1370_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1370_state, devs);
-		if (!((s->dev_audio ^ minor) & ~0xf))
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & file->f_mode) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_READ|FMODE_WRITE)))
-		s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV);
-	if (file->f_mode & FMODE_READ) {
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-		s->dma_adc.enabled = 1;
-		s->sctrl &= ~SCTRL_R1FMT;
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_R1FMT;
-		else
-			s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_R1FMT;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;
-		s->dma_dac2.enabled = 1;
-		s->sctrl &= ~SCTRL_P2FMT;
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P2FMT;
-		else
-			s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P2FMT;
-	}
-	outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-	outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	mutex_unlock(&s->open_mutex);
-	mutex_init(&s->mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int es1370_release(struct inode *inode, struct file *file)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
-		drain_dac2(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac2(s);
-		synchronize_irq(s->irq);
-		dealloc_dmabuf(s, &s->dma_dac2);
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-	}
-	s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations es1370_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= es1370_read,
-	.write		= es1370_write,
-	.poll		= es1370_poll,
-	.ioctl		= es1370_ioctl,
-	.mmap		= es1370_mmap,
-	.open		= es1370_open,
-	.release	= es1370_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret = 0;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_dac1.mapped)
-		return -ENXIO;
-	if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac1.count < 0) {
-			s->dma_dac1.count = 0;
-			s->dma_dac1.swptr = s->dma_dac1.hwptr;
-		}
-		swptr = s->dma_dac1.swptr;
-		cnt = s->dma_dac1.dmasize-swptr;
-		if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize)
-			cnt = s->dma_dac1.dmasize - s->dma_dac1.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_dac1.enabled)
-				start_dac1(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		swptr = (swptr + cnt) % s->dma_dac1.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac1.swptr = swptr;
-		s->dma_dac1.count += cnt;
-		s->dma_dac1.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_dac1.enabled)
-			start_dac1(s);
-	}
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_poll_dac(struct file *file, struct poll_table_struct *wait)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (!s->dma_dac1.ready && prog_dmabuf_dac1(s))
-		return 0;
-	poll_wait(file, &s->dma_dac1.wait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	es1370_update_ptr(s);
-	if (s->dma_dac1.mapped) {
-		if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-			mask |= POLLOUT | POLLWRNORM;
-	} else {
-		if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int es1370_mmap_dac(struct file *file, struct vm_area_struct *vma)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	int ret;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	if (!(vma->vm_flags & VM_WRITE))
-		return -EINVAL;
-	lock_kernel();
-	if ((ret = prog_dmabuf_dac1(s)) != 0)
-		goto out;
-	ret = -EINVAL;
-	if (vma->vm_pgoff != 0)
-		goto out;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << s->dma_dac1.buforder))
-		goto out;
-	ret = -EAGAIN;
-	if (remap_pfn_range(vma, vma->vm_start,
-			virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT,
-			size, vma->vm_page_prot))
-		goto out;
-	s->dma_dac1.mapped = 1;
-	ret = 0;
-out:
-	unlock_kernel();
-	return ret;
-}
-
-static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int count;
-	unsigned ctrl;
-	int val, ret;
-	int __user *p = (int __user *)arg;
-
-	VALIDATE_STATE(s);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return -EINVAL;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-		stop_dac1(s);
-		synchronize_irq(s->irq);
-		s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0;
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			stop_dac1(s);
-			s->dma_dac1.ready = 0;
-			for (ctrl = 0; ctrl <= 2; ctrl++)
-				if (val < (dac1_samplerate[ctrl] + dac1_samplerate[ctrl+1]) / 2)
-					break;
-			spin_lock_irqsave(&s->lock, flags);
-			s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (ctrl << CTRL_SH_WTSRSEL);
-			outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
-		
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-			return -EFAULT;
-		stop_dac1(s);
-		s->dma_dac1.ready = 0;
-		spin_lock_irqsave(&s->lock, flags);
-		if (val)
-			s->sctrl |= SCTRL_P1SMB;
-		else
-			s->sctrl &= ~SCTRL_P1SMB;
-		outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-		spin_unlock_irqrestore(&s->lock, flags);
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			if (s->dma_dac1.mapped)
-				return -EINVAL;
-			stop_dac1(s);
-			s->dma_dac1.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val >= 2)
-				s->sctrl |= SCTRL_P1SMB;
-			else
-				s->sctrl &= ~SCTRL_P1SMB;
-			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-		
-        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-		
-        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			stop_dac1(s);
-			s->dma_dac1.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val == AFMT_S16_LE)
-				s->sctrl |= SCTRL_P1SEB;
-			else
-				s->sctrl &= ~SCTRL_P1SEB;
-			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
-
-        case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
-						
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val & PCM_ENABLE_OUTPUT) {
-			if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-				return ret;
-			s->dma_dac1.enabled = 1;
-			start_dac1(s);
-		} else {
-			s->dma_dac1.enabled = 0;
-			stop_dac1(s);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-		abinfo.fragsize = s->dma_dac1.fragsize;
-		count = s->dma_dac1.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = s->dma_dac1.dmasize - count;
-                abinfo.fragstotal = s->dma_dac1.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-                count = s->dma_dac1.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		return put_user(count, p);
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_update_ptr(s);
-                cinfo.bytes = s->dma_dac1.total_bytes;
-		count = s->dma_dac1.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_dac1.fragshift;
-                cinfo.ptr = s->dma_dac1.hwptr;
-		if (s->dma_dac1.mapped)
-			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if ((val = prog_dmabuf_dac1(s)))
-			return val;
-                return put_user(s->dma_dac1.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		s->dma_dac1.ossfragshift = val & 0xffff;
-		s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
-		if (s->dma_dac1.ossfragshift < 4)
-			s->dma_dac1.ossfragshift = 4;
-		if (s->dma_dac1.ossfragshift > 15)
-			s->dma_dac1.ossfragshift = 15;
-		if (s->dma_dac1.ossmaxfrags < 4)
-			s->dma_dac1.ossmaxfrags = 4;
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if (s->dma_dac1.subdivision)
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		s->dma_dac1.subdivision = val;
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-	return mixer_ioctl(s, cmd, arg);
-}
-
-static int es1370_open_dac(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct es1370_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1370_state, devs);
-		if (!((s->dev_dac ^ minor) & ~0xf))
-			break;
-	}
-       	VALIDATE_STATE(s);
-       	/* we allow opening with O_RDWR, most programs do it although they will only write */
-#if 0
-	if (file->f_mode & FMODE_READ)
-		return -EPERM;
-#endif
-	if (!(file->f_mode & FMODE_WRITE))
-		return -EINVAL;
-       	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & FMODE_DAC) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
-	s->dma_dac1.enabled = 1;
-	spin_lock_irqsave(&s->lock, flags);
-	s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (1 << CTRL_SH_WTSRSEL);
-      	s->sctrl &= ~SCTRL_P1FMT;
-	if ((minor & 0xf) == SND_DEV_DSP16)
-		s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P1FMT;
-	else
-		s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P1FMT;
-	outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-	outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= FMODE_DAC;
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int es1370_release_dac(struct inode *inode, struct file *file)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	drain_dac1(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	stop_dac1(s);
-	dealloc_dmabuf(s, &s->dma_dac1);
-	s->open_mode &= ~FMODE_DAC;
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations es1370_dac_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.write		= es1370_write_dac,
-	.poll		= es1370_poll_dac,
-	.ioctl		= es1370_ioctl_dac,
-	.mmap		= es1370_mmap_dac,
-	.open		= es1370_open_dac,
-	.release	= es1370_release_dac,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-        add_wait_queue(&s->midi.iwait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.ird;
-		cnt = MIDIINBUF - ptr;
-		if (s->midi.icnt < cnt)
-			cnt = s->midi.icnt;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIINBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.ird = ptr;
-		s->midi.icnt -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		break;
-	}
-	__set_current_state(TASK_RUNNING);
-        remove_wait_queue(&s->midi.iwait, &wait);
-	return ret;
-}
-
-static ssize_t es1370_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.owr;
-		cnt = MIDIOUTBUF - ptr;
-		if (s->midi.ocnt + cnt > MIDIOUTBUF)
-			cnt = MIDIOUTBUF - s->midi.ocnt;
-		if (cnt <= 0) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			es1370_handle_midi(s);
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIOUTBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.owr = ptr;
-		s->midi.ocnt += cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		spin_lock_irqsave(&s->lock, flags);
-		es1370_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	}
-	__set_current_state(TASK_RUNNING);
-        remove_wait_queue(&s->midi.owait, &wait);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
-		poll_wait(file, &s->midi.owait, wait);
-	if (file->f_mode & FMODE_READ)
-		poll_wait(file, &s->midi.iwait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_mode & FMODE_READ) {
-		if (s->midi.icnt > 0)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->midi.ocnt < MIDIOUTBUF)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int es1370_midi_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct es1370_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1370_state, devs);
-		if (s->dev_midi == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-		outb(UCTRL_CNTRL_SWR, s->io+ES1370_REG_UART_CONTROL);
-		outb(0, s->io+ES1370_REG_UART_CONTROL);
-		outb(0, s->io+ES1370_REG_UART_TEST);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-	}
-	s->ctrl |= CTRL_UART_EN;
-	outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	es1370_handle_midi(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int es1370_midi_release(struct inode *inode, struct file *file)
-{
-	struct es1370_state *s = (struct es1370_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	unsigned count, tmo;
-
-	VALIDATE_STATE(s);
-
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE) {
-		add_wait_queue(&s->midi.owait, &wait);
-		for (;;) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			spin_lock_irqsave(&s->lock, flags);
-			count = s->midi.ocnt;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (count <= 0)
-				break;
-			if (signal_pending(current))
-				break;
-			if (file->f_flags & O_NONBLOCK) 
-				break;
-			tmo = (count * HZ) / 3100;
-			if (!schedule_timeout(tmo ? : 1) && tmo)
-				DBG(printk(KERN_DEBUG "es1370: midi timed out??\n");)
-		}
-		remove_wait_queue(&s->midi.owait, &wait);
-		set_current_state(TASK_RUNNING);
-	}
-	mutex_lock(&s->open_mutex);
-	s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->ctrl &= ~CTRL_UART_EN;
-		outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations es1370_midi_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= es1370_midi_read,
-	.write		= es1370_midi_write,
-	.poll		= es1370_midi_poll,
-	.open		= es1370_midi_open,
-	.release	= es1370_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int lineout[NR_DEVICE];
-static int micbias[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(lineout, bool, NULL, 0);
-MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out");
-module_param_array(micbias, bool, NULL, 0);
-MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ES1370 AudioPCI Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-	int mixch;
-	int vol;
-} initvol[] __devinitdata = {
-	{ SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-	{ SOUND_MIXER_WRITE_PCM, 0x4040 },
-	{ SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-	{ SOUND_MIXER_WRITE_CD, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE1, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE2, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE3, 0x4040 },
-	{ SOUND_MIXER_WRITE_MIC, 0x4040 },
-	{ SOUND_MIXER_WRITE_OGAIN, 0x4040 }
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static int __devinit es1370_register_gameport(struct es1370_state *s)
-{
-	struct gameport *gp;
-
-	if (!request_region(0x200, JOY_EXTENT, "es1370")) {
-		printk(KERN_ERR "es1370: joystick io port 0x200 in use\n");
-		return -EBUSY;
-	}
-
-	s->gameport = gp = gameport_allocate_port();
-	if (!gp) {
-		printk(KERN_ERR "es1370: can not allocate memory for gameport\n");
-		release_region(0x200, JOY_EXTENT);
-		return -ENOMEM;
-	}
-
-	gameport_set_name(gp, "ESS1370");
-	gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
-	gp->dev.parent = &s->dev->dev;
-	gp->io = 0x200;
-
-	s->ctrl |= CTRL_JYSTK_EN;
-	outl(s->ctrl, s->io + ES1370_REG_CONTROL);
-
-	gameport_register_port(gp);
-
-	return 0;
-}
-
-static inline void es1370_unregister_gameport(struct es1370_state *s)
-{
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, JOY_EXTENT);
-
-	}
-}
-
-#else
-static inline int es1370_register_gameport(struct es1370_state *s) { return -ENOSYS; }
-static inline void es1370_unregister_gameport(struct es1370_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-	struct es1370_state *s;
-	mm_segment_t fs;
-	int i, val, ret;
-
-	if ((ret=pci_enable_device(pcidev)))
-		return ret;
-
-	if ( !(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) ||
-	     !pci_resource_start(pcidev, 0)
-	)
-		return -ENODEV;
-	if (pcidev->irq == 0) 
-		return -ENODEV;
-	i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-	if (i) {
-		printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n");
-		return i;
-	}
-	if (!(s = kmalloc(sizeof(struct es1370_state), GFP_KERNEL))) {
-		printk(KERN_WARNING "es1370: out of memory\n");
-		return -ENOMEM;
-	}
-	memset(s, 0, sizeof(struct es1370_state));
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac1.wait);
-	init_waitqueue_head(&s->dma_dac2.wait);
-	init_waitqueue_head(&s->open_wait);
-	init_waitqueue_head(&s->midi.iwait);
-	init_waitqueue_head(&s->midi.owait);
-	mutex_init(&s->open_mutex);
-	spin_lock_init(&s->lock);
-	s->magic = ES1370_MAGIC;
-	s->dev = pcidev;
-	s->io = pci_resource_start(pcidev, 0);
-	s->irq = pcidev->irq;
-	if (!request_region(s->io, ES1370_EXTENT, "es1370")) {
-		printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1);
-		ret = -EBUSY;
-		goto err_region;
-	}
-	if ((ret=request_irq(s->irq, es1370_interrupt, IRQF_SHARED, "es1370",s))) {
-		printk(KERN_ERR "es1370: irq %u in use\n", s->irq);
-		goto err_irq;
-	}
-
-	/* initialize codec registers */
-	/* note: setting CTRL_SERR_DIS is reported to break
-	 * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */
-	s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL);
-	if (lineout[devindex])
-		s->ctrl |= CTRL_XCTL0;
-	if (micbias[devindex])
-		s->ctrl |= CTRL_XCTL1;
-	s->sctrl = 0;
-	printk(KERN_INFO "es1370: adapter at io %#lx irq %u, line %s, mic impedance %s\n",
-	       s->io, s->irq, (s->ctrl & CTRL_XCTL0) ? "out" : "in",
-	       (s->ctrl & CTRL_XCTL1) ? "1" : "0");
-	/* register devices */
-	if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0) {
-		ret = s->dev_audio;
-		goto err_dev1;
-	}
-	if ((s->dev_mixer = register_sound_mixer(&es1370_mixer_fops, -1)) < 0) {
-		ret = s->dev_mixer;
-		goto err_dev2;
-	}
-	if ((s->dev_dac = register_sound_dsp(&es1370_dac_fops, -1)) < 0) {
-		ret = s->dev_dac;
-		goto err_dev3;
-	}
-	if ((s->dev_midi = register_sound_midi(&es1370_midi_fops, -1)) < 0) {
-		ret = s->dev_midi;
-		goto err_dev4;
-	}
-	/* initialize the chips */
-	outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-	outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-	/* point phantom write channel to "bugbuf" */
-	s->bugbuf_cpu = pci_alloc_consistent(pcidev,16,&s->bugbuf_dma);
-	if (!s->bugbuf_cpu) {
-		ret = -ENOMEM;
-		goto err_dev5;
-	}
-	outl((ES1370_REG_PHANTOM_FRAMEADR >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-	outl(s->bugbuf_dma, s->io+(ES1370_REG_PHANTOM_FRAMEADR & 0xff));
-	outl(0, s->io+(ES1370_REG_PHANTOM_FRAMECNT & 0xff));
-	pci_set_master(pcidev);  /* enable bus mastering */
-	wrcodec(s, 0x16, 3); /* no RST, PD */
-	wrcodec(s, 0x17, 0); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; program DAC_SYNC=0!!  */
-	wrcodec(s, 0x18, 0); /* recording source is mixer */
-	wrcodec(s, 0x19, s->mix.micpreamp = 1); /* turn on MIC preamp */
-	s->mix.imix = 1;
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD;
-	mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-	for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-		val = initvol[i].vol;
-		mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-	}
-	set_fs(fs);
-
-	es1370_register_gameport(s);
-
-	/* store it in the driver field */
-	pci_set_drvdata(pcidev, s);
-	/* put it into driver list */
-	list_add_tail(&s->devs, &devs);
-	/* increment devindex */
-	if (devindex < NR_DEVICE-1)
-		devindex++;
-	return 0;
-
- err_dev5:
-	unregister_sound_midi(s->dev_midi);
- err_dev4:
-	unregister_sound_dsp(s->dev_dac);
- err_dev3:
-	unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-	unregister_sound_dsp(s->dev_audio);
- err_dev1:
-	printk(KERN_ERR "es1370: cannot register misc device\n");
-	free_irq(s->irq, s);
- err_irq:
-	release_region(s->io, ES1370_EXTENT);
- err_region:
-	kfree(s);
-	return ret;
-}
-
-static void __devexit es1370_remove(struct pci_dev *dev)
-{
-	struct es1370_state *s = pci_get_drvdata(dev);
-
-	if (!s)
-		return;
-	list_del(&s->devs);
-	outl(CTRL_SERR_DIS | (1 << CTRL_SH_WTSRSEL), s->io+ES1370_REG_CONTROL); /* switch everything off */
-	outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */
-	synchronize_irq(s->irq);
-	free_irq(s->irq, s);
-	es1370_unregister_gameport(s);
-	release_region(s->io, ES1370_EXTENT);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->dev_mixer);
-	unregister_sound_dsp(s->dev_dac);
-	unregister_sound_midi(s->dev_midi);
-	pci_free_consistent(dev, 16, s->bugbuf_cpu, s->bugbuf_dma);
-	kfree(s);
-	pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-	{ PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver es1370_driver = {
-	.name		= "es1370",
-	.id_table	= id_table,
-	.probe		= es1370_probe,
-	.remove		= __devexit_p(es1370_remove),
-};
-
-static int __init init_es1370(void)
-{
-	printk(KERN_INFO "es1370: version v0.38 time " __TIME__ " " __DATE__ "\n");
-	return pci_register_driver(&es1370_driver);
-}
-
-static void __exit cleanup_es1370(void)
-{
-	printk(KERN_INFO "es1370: unloading\n");
-	pci_unregister_driver(&es1370_driver);
-}
-
-module_init(init_es1370);
-module_exit(cleanup_es1370);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: es1370=lineout[,micbias]] */
-
-static int __init es1370_setup(char *str)
-{
-	static unsigned __initdata nr_dev = 0;
-
-	if (nr_dev >= NR_DEVICE)
-		return 0;
-
-	(void)
-	((get_option(&str,&lineout [nr_dev]) == 2)
-	 && get_option(&str,&micbias [nr_dev])
-	);
-
-	nr_dev++;
-	return 1;
-}
-
-__setup("es1370=", es1370_setup);
-
-#endif /* MODULE */
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
deleted file mode 100644
index 82f40a0..0000000
--- a/sound/oss/esssolo1.c
+++ /dev/null
@@ -1,2516 +0,0 @@
-/****************************************************************************/
-
-/*
- *      esssolo1.c  --  ESS Technology Solo1 (ES1946) audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Module command line parameters:
- *   none so far
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  Revision history
- *    10.11.1998   0.1   Initial release (without any hardware)
- *    22.03.1999   0.2   cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *                       return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.3   implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *    15.06.1999   0.4   Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.5   Add pci_set_master
- *    12.08.1999   0.6   Fix MIDI UART crashing the driver
- *                       Changed mixer semantics from OSS documented
- *                       behaviour to OSS "code behaviour".
- *                       Recording might actually work now.
- *                       The real DDMA controller address register is at PCI config
- *                       0x60, while the register at 0x18 is used as a placeholder
- *                       register for BIOS address allocation. This register
- *                       is supposed to be copied into 0x60, according
- *                       to the Solo1 datasheet. When I do that, I can access
- *                       the DDMA registers except the mask bit, which
- *                       is stuck at 1. When I copy the contents of 0x18 +0x10
- *                       to the DDMA base register, everything seems to work.
- *                       The fun part is that the Windows Solo1 driver doesn't
- *                       seem to do these tricks.
- *                       Bugs remaining: plops and clicks when starting/stopping playback
- *    31.08.1999   0.7   add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.8   change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    07.10.1999   0.9   Fix initialization; complain if sequencer writes time out
- *                       Revised resource grabbing for the FM synthesizer
- *    28.10.1999   0.10  More waitqueue races fixed
- *    09.12.1999   0.11  Work around stupid Alpha port issue (virt_to_bus(kmalloc(GFP_DMA)) > 16M)
- *                       Disabling recording on Alpha
- *    12.01.2000   0.12  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *                       Integrated (aka redid 8-)) APM support patch by Zach Brown
- *    07.02.2000   0.13  Use pci_alloc_consistent and pci_register_driver
- *    19.02.2000   0.14  Use pci_dma_supported to determine if recording should be disabled
- *    13.03.2000   0.15  Reintroduce initialization of a couple of PCI config space registers
- *    21.11.2000   0.16  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.17  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    31.01.2001   0.18  Register/Unregister gameport, original patch from
- *                       Nathaniel Daw <daw@cs.cmu.edu>
- *                       Fix SETTRIGGER non OSS API conformity
- *    10.03.2001         provide abs function, prevent picking up a bogus kernel macro
- *                       for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
- *    15.05.2001         pci_enable_device moved, return values in probe cleaned
- *                       up. Marcus Meissner <mm@caldera.de>
- *    22.05.2001   0.19  more cleanups, changed PM to PCI 2.4 style, got rid
- *                       of global list of devices, using pci device data.
- *                       Marcus Meissner <mm@caldera.de>
- *    03.01.2003   0.20  open_mode fixes from Georg Acher <acher@in.tum.de>
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "dm.h"
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS         0x125d
-#endif
-#ifndef PCI_DEVICE_ID_ESS_SOLO1
-#define PCI_DEVICE_ID_ESS_SOLO1   0x1969
-#endif
-
-#define SOLO1_MAGIC  ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1)
-
-#define DDMABASE_OFFSET           0    /* chip bug workaround kludge */
-#define DDMABASE_EXTENT           16
-
-#define IOBASE_EXTENT             16
-#define SBBASE_EXTENT             16
-#define VCBASE_EXTENT             (DDMABASE_EXTENT+DDMABASE_OFFSET)
-#define MPUBASE_EXTENT            4
-#define GPBASE_EXTENT             4
-#define GAMEPORT_EXTENT		  4
-
-#define FMSYNTH_EXTENT            4
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define FMODE_DMFM 0x10
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static struct pci_driver solo1_driver;
-
-/* --------------------------------------------------------------------- */
-
-struct solo1_state {
-	/* magic */
-	unsigned int magic;
-
-	/* the corresponding pci_dev structure */
-	struct pci_dev *dev;
-
-	/* soundcore stuff */
-	int dev_audio;
-	int dev_mixer;
-	int dev_midi;
-	int dev_dmfm;
-
-	/* hardware resources */
-	unsigned long iobase, sbbase, vcbase, ddmabase, mpubase; /* long for SPARC */
-	unsigned int irq;
-
-	/* mixer registers */
-	struct {
-		unsigned short vol[10];
-		unsigned int recsrc;
-		unsigned int modcnt;
-		unsigned short micpreamp;
-	} mix;
-
-	/* wave stuff */
-	unsigned fmt;
-	unsigned channels;
-	unsigned rate;
-	unsigned char clkdiv;
-	unsigned ena;
-
-	spinlock_t lock;
-	struct mutex open_mutex;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-
-	struct dmabuf {
-		void *rawbuf;
-		dma_addr_t dmaaddr;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-		unsigned hwptr, swptr;
-		unsigned total_bytes;
-		int count;
-		unsigned error; /* over/underrun */
-		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;
-		unsigned dmasize;
-		unsigned fragsamples;
-		/* OSS stuff */
-		unsigned mapped:1;
-		unsigned ready:1;
-		unsigned endcleared:1;
-		unsigned enabled:1;
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac, dma_adc;
-
-	/* midi stuff */
-	struct {
-		unsigned ird, iwr, icnt;
-		unsigned ord, owr, ocnt;
-		wait_queue_head_t iwait;
-		wait_queue_head_t owait;
-		struct timer_list timer;
-		unsigned char ibuf[MIDIINBUF];
-		unsigned char obuf[MIDIOUTBUF];
-	} midi;
-
-#if SUPPORT_JOYSTICK
-	struct gameport *gameport;
-#endif
-};
-
-/* --------------------------------------------------------------------- */
-
-static inline void write_seq(struct solo1_state *s, unsigned char data)
-{
-        int i;
-	unsigned long flags;
-
-	/* the local_irq_save stunt is to send the data within the command window */
-        for (i = 0; i < 0xffff; i++) {
-		local_irq_save(flags);
-                if (!(inb(s->sbbase+0xc) & 0x80)) {
-                        outb(data, s->sbbase+0xc);
-			local_irq_restore(flags);
-                        return;
-                }
-		local_irq_restore(flags);
-	}
-	printk(KERN_ERR "esssolo1: write_seq timeout\n");
-	outb(data, s->sbbase+0xc);
-}
-
-static inline int read_seq(struct solo1_state *s, unsigned char *data)
-{
-        int i;
-
-        if (!data)
-                return 0;
-        for (i = 0; i < 0xffff; i++)
-                if (inb(s->sbbase+0xe) & 0x80) {
-                        *data = inb(s->sbbase+0xa);
-                        return 1;
-                }
-	printk(KERN_ERR "esssolo1: read_seq timeout\n");
-        return 0;
-}
-
-static inline int reset_ctrl(struct solo1_state *s)
-{
-        int i;
-
-        outb(3, s->sbbase+6); /* clear sequencer and FIFO */
-        udelay(10);
-        outb(0, s->sbbase+6);
-        for (i = 0; i < 0xffff; i++)
-                if (inb(s->sbbase+0xe) & 0x80)
-                        if (inb(s->sbbase+0xa) == 0xaa) {
-				write_seq(s, 0xc6); /* enter enhanced mode */
-                                return 1;
-			}
-        return 0;
-}
-
-static void write_ctrl(struct solo1_state *s, unsigned char reg, unsigned char data)
-{
-	write_seq(s, reg);
-	write_seq(s, data);
-}
-
-#if 0 /* unused */
-static unsigned char read_ctrl(struct solo1_state *s, unsigned char reg)
-{
-        unsigned char r;
-
-	write_seq(s, 0xc0);
-	write_seq(s, reg);
-	read_seq(s, &r);
-	return r;
-}
-#endif /* unused */
-
-static void write_mixer(struct solo1_state *s, unsigned char reg, unsigned char data)
-{
-	outb(reg, s->sbbase+4);
-	outb(data, s->sbbase+5);
-}
-
-static unsigned char read_mixer(struct solo1_state *s, unsigned char reg)
-{
-	outb(reg, s->sbbase+4);
-	return inb(s->sbbase+5);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned r = 0;
-	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_dac(struct solo1_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ena &= ~FMODE_WRITE;
-	write_mixer(s, 0x78, 0x10);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac(struct solo1_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-		s->ena |= FMODE_WRITE;
-		write_mixer(s, 0x78, 0x12);
-		udelay(10);
-		write_mixer(s, 0x78, 0x13);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static inline void stop_adc(struct solo1_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ena &= ~FMODE_READ;
-	write_ctrl(s, 0xb8, 0xe);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_adc(struct solo1_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-	    && s->dma_adc.ready) {
-		s->ena |= FMODE_READ;
-		write_ctrl(s, 0xb8, 0xf);
-#if 0
-		printk(KERN_DEBUG "solo1: DMAbuffer: 0x%08lx\n", (long)s->dma_adc.rawbuf);
-		printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x  stat: 0x%02x\n", 
-		       inb(s->ddmabase+0xf), inw(s->ddmabase+4), inl(s->ddmabase), inb(s->ddmabase+8));
-#endif
-                outb(0, s->ddmabase+0xd); /* master reset */
-		outb(1, s->ddmabase+0xf);  /* mask */
-		outb(0x54/*0x14*/, s->ddmabase+0xb);  /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
-		outl(virt_to_bus(s->dma_adc.rawbuf), s->ddmabase);
-		outw(s->dma_adc.dmasize-1, s->ddmabase+4);
-		outb(0, s->ddmabase+0xf);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-#if 0
-	printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x  SBstat: 0x%02x\n"
-	       KERN_DEBUG "solo1: DMA: stat: 0x%02x  cnt: 0x%04x  mask: 0x%02x\n", 
-	       read_ctrl(s, 0xb8), inb(s->sbbase+0xc), 
-	       inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->ddmabase+0xf));
-	printk(KERN_DEBUG "solo1: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"  
-	       KERN_DEBUG "solo1: B1: 0x%02x  B2: 0x%02x  B4: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n",
-	       read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-	       read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb4), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), 
-	       read_ctrl(s, 0xb9));
-#endif
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct solo1_state *s, struct dmabuf *db)
-{
-	struct page *page, *pend;
-
-	if (db->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			ClearPageReserved(page);
-		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-	}
-	db->rawbuf = NULL;
-	db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct solo1_state *s, struct dmabuf *db)
-{
-	int order;
-	unsigned bytespersec;
-	unsigned bufs, sample_shift = 0;
-	struct page *page, *pend;
-
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-                for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-				break;
-		if (!db->rawbuf)
-			return -ENOMEM;
-		db->buforder = order;
-		/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			SetPageReserved(page);
-	}
-	if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-		sample_shift++;
-	if (s->channels > 1)
-		sample_shift++;
-	bytespersec = s->rate << sample_shift;
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < bytespersec)
-			db->fragshift = ld2(bytespersec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(bytespersec/100/(db->subdivision ? db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3;
-	}
-	db->numfrag = bufs >> db->fragshift;
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->numfrag = bufs >> db->fragshift;
-	}
-	db->fragsize = 1 << db->fragshift;
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
-	db->fragsamples = db->fragsize >> sample_shift;
-	db->dmasize = db->numfrag << db->fragshift;
-	db->enabled = 1;
-	return 0;
-}
-
-static inline int prog_dmabuf_adc(struct solo1_state *s)
-{
-	unsigned long va;
-	int c;
-
-	stop_adc(s);
-	/* check if PCI implementation supports 24bit busmaster DMA */
-	if (s->dev->dma_mask > 0xffffff)
-		return -EIO;
-	if ((c = prog_dmabuf(s, &s->dma_adc)))
-		return c;
-	va = s->dma_adc.dmaaddr;
-	if ((va & ~((1<<24)-1)))
-		panic("solo1: buffer above 16M boundary");
-	outb(0, s->ddmabase+0xd);  /* clear */
-	outb(1, s->ddmabase+0xf); /* mask */
-	/*outb(0, s->ddmabase+8);*/  /* enable (enable is active low!) */
-	outb(0x54, s->ddmabase+0xb);  /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
-	outl(va, s->ddmabase);
-	outw(s->dma_adc.dmasize-1, s->ddmabase+4);
-	c = - s->dma_adc.fragsamples;
-	write_ctrl(s, 0xa4, c);
-	write_ctrl(s, 0xa5, c >> 8);
-	outb(0, s->ddmabase+0xf);
-	s->dma_adc.ready = 1;
-	return 0;
-}
-
-static int prog_dmabuf_dac(struct solo1_state *s)
-{
-	unsigned long va;
-	int c;
-
-	stop_dac(s);
-	if ((c = prog_dmabuf(s, &s->dma_dac)))
-		return c;
-	memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80, s->dma_dac.dmasize); /* almost correct for U16 */
-	va = s->dma_dac.dmaaddr;
-	if ((va ^ (va + s->dma_dac.dmasize - 1)) & ~((1<<20)-1))
-		panic("solo1: buffer crosses 1M boundary");
-	outl(va, s->iobase);
-	/* warning: s->dma_dac.dmasize & 0xffff must not be zero! i.e. this limits us to a 32k buffer */
-	outw(s->dma_dac.dmasize, s->iobase+4);
-	c = - s->dma_dac.fragsamples;
-	write_mixer(s, 0x74, c);
-	write_mixer(s, 0x76, c >> 8);
-	outb(0xa, s->iobase+6);
-	s->dma_dac.ready = 1;
-	return 0;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(((char *)buf) + bptr, c, x);
-		bptr = 0;
-		len -= x;
-	}
-	memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-
-static void solo1_update_ptr(struct solo1_state *s)
-{
-	int diff;
-	unsigned hwptr;
-
-	/* update ADC pointer */
-	if (s->ena & FMODE_READ) {
-		hwptr = (s->dma_adc.dmasize - 1 - inw(s->ddmabase+4)) % s->dma_adc.dmasize;
-                diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-                s->dma_adc.hwptr = hwptr;
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-#if 0
-		printk(KERN_DEBUG "solo1: rd: hwptr %u swptr %u dmasize %u count %u\n",
-		       s->dma_adc.hwptr, s->dma_adc.swptr, s->dma_adc.dmasize, s->dma_adc.count);
-#endif
-		if (s->dma_adc.mapped) {
-			if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-				wake_up(&s->dma_adc.wait);
-		} else {
-			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-				s->ena &= ~FMODE_READ;
-				write_ctrl(s, 0xb8, 0xe);
-				s->dma_adc.error++;
-			}
-			if (s->dma_adc.count > 0)
-				wake_up(&s->dma_adc.wait);
-		}
-	}
-	/* update DAC pointer */
-	if (s->ena & FMODE_WRITE) {
-                hwptr = (s->dma_dac.dmasize - inw(s->iobase+4)) % s->dma_dac.dmasize;
-                diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-                s->dma_dac.hwptr = hwptr;
-		s->dma_dac.total_bytes += diff;
-#if 0
-		printk(KERN_DEBUG "solo1: wr: hwptr %u swptr %u dmasize %u count %u\n",
-		       s->dma_dac.hwptr, s->dma_dac.swptr, s->dma_dac.dmasize, s->dma_dac.count);
-#endif
-		if (s->dma_dac.mapped) {
-			s->dma_dac.count += diff;
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-				wake_up(&s->dma_dac.wait);
-		} else {
-			s->dma_dac.count -= diff;
-			if (s->dma_dac.count <= 0) {
-				s->ena &= ~FMODE_WRITE;
-				write_mixer(s, 0x78, 0x12);
-				s->dma_dac.error++;
-			} else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-				clear_advance(s->dma_dac.rawbuf, s->dma_dac.dmasize, s->dma_dac.swptr,
-					      s->dma_dac.fragsize, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80);
-				s->dma_dac.endcleared = 1;
-			}
-			if (s->dma_dac.count < (signed)s->dma_dac.dmasize)
-				wake_up(&s->dma_dac.wait);
-		}
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static void prog_codec(struct solo1_state *s)
-{
-	unsigned long flags;
-	int fdiv, filter;
-	unsigned char c;
-
-	reset_ctrl(s);
-	write_seq(s, 0xd3);
-	/* program sampling rates */
-	filter = s->rate * 9 / 20; /* Set filter roll-off to 90% of rate/2 */
-	fdiv = 256 - 7160000 / (filter * 82);
-	spin_lock_irqsave(&s->lock, flags);
-	write_ctrl(s, 0xa1, s->clkdiv);
-	write_ctrl(s, 0xa2, fdiv);
-	write_mixer(s, 0x70, s->clkdiv);
-	write_mixer(s, 0x72, fdiv);
-	/* program ADC parameters */
-	write_ctrl(s, 0xb8, 0xe);
-	write_ctrl(s, 0xb9, /*0x1*/0);
-	write_ctrl(s, 0xa8, (s->channels > 1) ? 0x11 : 0x12);
-	c = 0xd0;
-	if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-		c |= 0x04;
-	if (s->fmt & (AFMT_S16_LE | AFMT_S8))
-		c |= 0x20;
-	if (s->channels > 1)
-		c ^= 0x48;
-	write_ctrl(s, 0xb7, (c & 0x70) | 1);
-	write_ctrl(s, 0xb7, c);
-	write_ctrl(s, 0xb1, 0x50);
-	write_ctrl(s, 0xb2, 0x50);
-	/* program DAC parameters */
-	c = 0x40;
-	if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-		c |= 1;
-	if (s->fmt & (AFMT_S16_LE | AFMT_S8))
-		c |= 4;
-	if (s->channels > 1)
-		c |= 2;
-	write_mixer(s, 0x7a, c);
-	write_mixer(s, 0x78, 0x10);
-	s->ena = 0;
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "solo1: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-	if (!(s) || (s)->magic != SOLO1_MAGIC) { \
-		printk(invalid_magic);            \
-		return -ENXIO;                    \
-	}                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long arg)
-{
-	static const unsigned int mixer_src[8] = {
-		SOUND_MASK_MIC, SOUND_MASK_MIC, SOUND_MASK_CD, SOUND_MASK_VOLUME,
-		SOUND_MASK_MIC, 0, SOUND_MASK_LINE, 0
-	};
-	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-		[SOUND_MIXER_PCM]     = 1,   /* voice */
-		[SOUND_MIXER_SYNTH]   = 2,   /* FM */
-		[SOUND_MIXER_CD]      = 3,   /* CD */
-		[SOUND_MIXER_LINE]    = 4,   /* Line */
-		[SOUND_MIXER_LINE1]   = 5,   /* AUX */
-		[SOUND_MIXER_MIC]     = 6,   /* Mic */
-		[SOUND_MIXER_LINE2]   = 7,   /* Mono in */
-		[SOUND_MIXER_SPEAKER] = 8,   /* Speaker */
-		[SOUND_MIXER_RECLEV]  = 9,   /* Recording level */
-		[SOUND_MIXER_VOLUME]  = 10   /* Master Volume */
-	};
-	static const unsigned char mixreg[] = {
-		0x7c,   /* voice */
-		0x36,   /* FM */
-		0x38,   /* CD */
-		0x3e,   /* Line */
-		0x3a,   /* AUX */
-		0x1a,   /* Mic */
-		0x6d    /* Mono in */
-	};
-	unsigned char l, r, rl, rr, vidx;
-	int i, val;
-	int __user *p = (int __user *)arg;
-
-	VALIDATE_STATE(s);
-
-	if (cmd == SOUND_MIXER_PRIVATE1) {
-		/* enable/disable/query mixer preamp */
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != -1) {
-			val = val ? 0xff : 0xf7;
-			write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val);
-		}
-		val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0;
-		return put_user(val, p);
-	}
-	if (cmd == SOUND_MIXER_PRIVATE2) {
-		/* enable/disable/query spatializer */
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != -1) {
-			val &= 0x3f;
-			write_mixer(s, 0x52, val);
-			write_mixer(s, 0x50, val ? 0x08 : 0);
-		}
-		return put_user(read_mixer(s, 0x52), p);
-	}
-        if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		strncpy(info.id, "Solo1", sizeof(info.id));
-		strncpy(info.name, "ESS Solo1", sizeof(info.name));
-		info.modify_counter = s->mix.modcnt;
-		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == SOUND_OLD_MIXER_INFO) {
-		_old_mixer_info info;
-		strncpy(info.id, "Solo1", sizeof(info.id));
-		strncpy(info.name, "ESS Solo1", sizeof(info.name));
-		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, p);
-	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-			return put_user(mixer_src[read_mixer(s, 0x1c) & 7], p);
-
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
-					SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-					SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV |
-					SOUND_MASK_SPEAKER, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-			return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME, p);
-
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
-					SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-					SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, p);
-			
-                case SOUND_MIXER_CAPS:
-			return put_user(SOUND_CAP_EXCL_INPUT, p);
-
-		default:
-			i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-                                return -EINVAL;
-			return put_user(s->mix.vol[vidx-1], p);
-		}
-	}
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-		return -EINVAL;
-	s->mix.modcnt++;
-	switch (_IOC_NR(cmd)) {
-	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-#if 0
-	        {
-			static const unsigned char regs[] = {
-				0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d, 0x7c
-			};
-			int i;
-			
-			for (i = 0; i < sizeof(regs); i++)
-				printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n",
-				       regs[i], read_mixer(s, regs[i]));
-			printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n",
-			       0xb4, read_ctrl(s, 0xb4));
-		}
-#endif
-	        if (get_user(val, p))
-			return -EFAULT;
-                i = hweight32(val);
-                if (i == 0)
-                        return 0;
-                else if (i > 1) 
-                        val &= ~mixer_src[read_mixer(s, 0x1c) & 7];
-		for (i = 0; i < 8; i++) {
-			if (mixer_src[i] & val)
-				break;
-		}
-		if (i > 7)
-			return 0;
-		write_mixer(s, 0x1c, i);
-		return 0;
-
-	case SOUND_MIXER_VOLUME:
-		if (get_user(val, p))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;
-		if (l < 6) {
-			rl = 0x40;
-			l = 0;
-		} else {
-			rl = (l * 2 - 11) / 3;
-			l = (rl * 3 + 11) / 2;
-		}
-		if (r < 6) {
-			rr = 0x40;
-			r = 0;
-		} else {
-			rr = (r * 2 - 11) / 3;
-			r = (rr * 3 + 11) / 2;
-		}
-		write_mixer(s, 0x60, rl);
-		write_mixer(s, 0x62, rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[9] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[9] = val;
-#endif
-		return put_user(s->mix.vol[9], p);
-
-	case SOUND_MIXER_SPEAKER:
-		if (get_user(val, p))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		else if (l < 2)
-			l = 2;
-		rl = (l - 2) / 14;
-		l = rl * 14 + 2;
-		write_mixer(s, 0x3c, rl);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[7] = l * 0x101;
-#else
-                s->mix.vol[7] = val;
-#endif
-		return put_user(s->mix.vol[7], p);
-
-	case SOUND_MIXER_RECLEV:
-		if (get_user(val, p))
-			return -EFAULT;
-		l = (val << 1) & 0x1fe;
-		if (l > 200)
-			l = 200;
-		else if (l < 5)
-			l = 5;
-		r = (val >> 7) & 0x1fe;
-		if (r > 200)
-			r = 200;
-		else if (r < 5)
-			r = 5;
-		rl = (l - 5) / 13;
-		rr = (r - 5) / 13;
-		r = (rl * 13 + 5) / 2;
-		l = (rr * 13 + 5) / 2;
-		write_ctrl(s, 0xb4, (rl << 4) | rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[8] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[8] = val;
-#endif
-		return put_user(s->mix.vol[8], p);
-
-	default:
-		i = _IOC_NR(cmd);
-		if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-			return -EINVAL;
-		if (get_user(val, p))
-			return -EFAULT;
-		l = (val << 1) & 0x1fe;
-		if (l > 200)
-			l = 200;
-		else if (l < 5)
-			l = 5;
-		r = (val >> 7) & 0x1fe;
-		if (r > 200)
-			r = 200;
-		else if (r < 5)
-			r = 5;
-		rl = (l - 5) / 13;
-		rr = (r - 5) / 13;
-		r = (rl * 13 + 5) / 2;
-		l = (rr * 13 + 5) / 2;
-		write_mixer(s, mixreg[vidx-1], (rl << 4) | rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[vidx-1] = val;
-#endif
-		return put_user(s->mix.vol[vidx-1], p);
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static int solo1_open_mixdev(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev = NULL;
-
-	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-		struct pci_driver *drvr;
-		drvr = pci_dev_driver (pci_dev);
-		if (drvr != &solo1_driver)
-			continue;
-		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-		if (!s)
-			continue;
-		if (s->dev_mixer == minor)
-			break;
-	}
-	if (!s)
-		return -ENODEV;
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	return nonseekable_open(inode, file);
-}
-
-static int solo1_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	return 0;
-}
-
-static int solo1_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	return mixer_ioctl((struct solo1_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations solo1_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= solo1_ioctl_mixdev,
-	.open		= solo1_open_mixdev,
-	.release	= solo1_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct solo1_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count;
-	unsigned tmo;
-	
-	if (s->dma_dac.mapped)
-		return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-		tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate;
-		if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			tmo >>= 1;
-		if (s->channels > 1)
-			tmo >>= 1;
-                if (!schedule_timeout(tmo + 1))
-                        printk(KERN_DEBUG "solo1: dma timed out??\n");
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t solo1_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	add_wait_queue(&s->dma_adc.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		swptr = s->dma_adc.swptr;
-		cnt = s->dma_adc.dmasize-swptr;
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-#ifdef DEBUGREC
-		printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x  DMAstat: 0x%02x  DMAcnt: 0x%04x  SBstat: 0x%02x  cnt: %u\n", 
-		       read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc), cnt);
-#endif
-		if (cnt <= 0) {
-			if (s->dma_adc.enabled)
-				start_adc(s);
-#ifdef DEBUGREC
-			printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"
-			       KERN_DEBUG "solo1_read: regs: B1: 0x%02x  B2: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n"
-			       KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n"  
-			       KERN_DEBUG "solo1_read: SBstat: 0x%02x  cnt: %u\n",
-			       read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-			       read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), 
-			       inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
-#endif
-			if (inb(s->ddmabase+15) & 1)
-				printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n");
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-#ifdef DEBUGREC
-			printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"
-			       KERN_DEBUG "solo1_read: regs: B1: 0x%02x  B2: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n"
-			       KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n"  
-			       KERN_DEBUG "solo1_read: SBstat: 0x%02x  cnt: %u\n",
-			       read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-			       read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), 
-			       inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
-#endif
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_adc.enabled)
-			start_adc(s);
-#ifdef DEBUGREC
-		printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x  DMAstat: 0x%02x  DMAcnt: 0x%04x  SBstat: 0x%02x\n", 
-		       read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc));
-#endif
-	}
-	remove_wait_queue(&s->dma_adc.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-static ssize_t solo1_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_dac.mapped)
-		return -ENXIO;
-	if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-#if 0
-	printk(KERN_DEBUG "solo1_write: reg 70: 0x%02x  71: 0x%02x  72: 0x%02x  74: 0x%02x  76: 0x%02x  78: 0x%02x  7A: 0x%02x\n"
-	       KERN_DEBUG "solo1_write: DMA: addr: 0x%08x  cnt: 0x%04x  stat: 0x%02x  SBstat: 0x%02x\n", 
-	       read_mixer(s, 0x70), read_mixer(s, 0x71), read_mixer(s, 0x72), read_mixer(s, 0x74), read_mixer(s, 0x76),
-	       read_mixer(s, 0x78), read_mixer(s, 0x7a), inl(s->iobase), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc));
-	printk(KERN_DEBUG "solo1_write: reg 78: 0x%02x  reg 7A: 0x%02x  DMAcnt: 0x%04x  DMAstat: 0x%02x  SBstat: 0x%02x\n", 
-	       read_mixer(s, 0x78), read_mixer(s, 0x7a), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc));
-#endif
-	ret = 0;
-	add_wait_queue(&s->dma_dac.wait, &wait);	
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac.count < 0) {
-			s->dma_dac.count = 0;
-			s->dma_dac.swptr = s->dma_dac.hwptr;
-		}
-		swptr = s->dma_dac.swptr;
-		cnt = s->dma_dac.dmasize-swptr;
-		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-			cnt = s->dma_dac.dmasize - s->dma_dac.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_dac.enabled)
-				start_dac(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac.swptr = swptr;
-		s->dma_dac.count += cnt;
-		s->dma_dac.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_dac.enabled)
-			start_dac(s);
-	}
-	remove_wait_queue(&s->dma_dac.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int solo1_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready && prog_dmabuf_dac(s))
-			return 0;
-		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	solo1_update_ptr(s);
-	if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.mapped) {
-			if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-				mask |= POLLIN | POLLRDNORM;
-		} else {
-			if (s->dma_adc.count > 0)
-				mask |= POLLIN | POLLRDNORM;
-		}
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed)s->dma_dac.dmasize > s->dma_dac.count)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-
-static int solo1_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	struct dmabuf *db;
-	int ret = -EINVAL;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf_dac(s)) != 0)
-			goto out;
-		db = &s->dma_dac;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf_adc(s)) != 0)
-			goto out;
-		db = &s->dma_adc;
-	} else 
-		goto out;
-	ret = -EINVAL;
-	if (vma->vm_pgoff != 0)
-		goto out;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder))
-		goto out;
-	ret = -EAGAIN;
-	if (remap_pfn_range(vma, vma->vm_start,
-				virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-				size, vma->vm_page_prot))
-		goto out;
-	db->mapped = 1;
-	ret = 0;
-out:
-	unlock_kernel();
-	return ret;
-}
-
-static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int val, mapped, ret, count;
-        int div1, div2;
-        unsigned rate1, rate2;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-		return 0;
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq(s->irq);
-			s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->irq);
-			s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-		}
-		prog_codec(s);
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			stop_adc(s);
-			stop_dac(s);
-			s->dma_adc.ready = s->dma_dac.ready = 0;
-			/* program sampling rates */
-			if (val > 48000)
-				val = 48000;
-			if (val < 6300)
-				val = 6300;
-			div1 = (768000 + val / 2) / val;
-			rate1 = (768000 + div1 / 2) / div1;
-			div1 = -div1;
-			div2 = (793800 + val / 2) / val;
-			rate2 = (793800 + div2 / 2) / div2;
-			div2 = (-div2) & 0x7f;
-			if (abs(val - rate2) < abs(val - rate1)) {
-				rate1 = rate2;
-				div1 = div2;
-			}
-			s->rate = rate1;
-			s->clkdiv = div1;
-			prog_codec(s);
-		}
-		return put_user(s->rate, p);
-		
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-			return -EFAULT;
-		stop_adc(s);
-		stop_dac(s);
-		s->dma_adc.ready = s->dma_dac.ready = 0;
-		/* program channels */
-		s->channels = val ? 2 : 1;
-		prog_codec(s);
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			stop_adc(s);
-			stop_dac(s);
-			s->dma_adc.ready = s->dma_dac.ready = 0;
-			/* program channels */
-			s->channels = (val >= 2) ? 2 : 1;
-			prog_codec(s);
-		}
-		return put_user(s->channels, p);
-
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, p);
-
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			stop_adc(s);
-			stop_dac(s);
-			s->dma_adc.ready = s->dma_dac.ready = 0;
-			/* program format */
-			if (val != AFMT_S16_LE && val != AFMT_U16_LE && 
-			    val != AFMT_S8 && val != AFMT_U8)
-				val = AFMT_U8;
-			s->fmt = val;
-			prog_codec(s);
-		}
-		return put_user(s->fmt, p);
-
-	case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if (file->f_mode & s->ena & FMODE_READ)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & s->ena & FMODE_WRITE)
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, p);
-
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-					return ret;
-				s->dma_dac.enabled = 1;
-				start_adc(s);
-				if (inb(s->ddmabase+15) & 1)
-					printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n");
-			} else {
-				s->dma_dac.enabled = 0;
-				stop_adc(s);
-			}
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-					return ret;
-				s->dma_dac.enabled = 1;
-				start_dac(s);
-			} else {
-				s->dma_dac.enabled = 0;
-				stop_dac(s);
-			}
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		solo1_update_ptr(s);
-		abinfo.fragsize = s->dma_dac.fragsize;
-		count = s->dma_dac.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = s->dma_dac.dmasize - count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		solo1_update_ptr(s);
-		abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		solo1_update_ptr(s);
-                count = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		solo1_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		solo1_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-		count = s->dma_dac.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= s->dma_dac.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-#if 0
-		printk(KERN_DEBUG "esssolo1: GETOPTR: bytes %u blocks %u ptr %u, buforder %u numfrag %u fragshift %u\n"
-		       KERN_DEBUG "esssolo1: swptr %u count %u fragsize %u dmasize %u fragsamples %u\n",
-		       cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift,
-		       s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples);
-#endif
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf_dac(s)))
-				return val;
-			return put_user(s->dma_dac.fragsize, p);
-		}
-		if ((val = prog_dmabuf_adc(s)))
-			return val;
-		return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			s->dma_dac.ossfragshift = val & 0xffff;
-			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac.ossfragshift < 4)
-				s->dma_dac.ossfragshift = 4;
-			if (s->dma_dac.ossfragshift > 15)
-				s->dma_dac.ossfragshift = 15;
-			if (s->dma_dac.ossmaxfrags < 4)
-				s->dma_dac.ossmaxfrags = 4;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE)
-			s->dma_dac.subdivision = val;
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user(s->rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user(s->channels, p);
-
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-	return mixer_ioctl(s, cmd, arg);
-}
-
-static int solo1_release(struct inode *inode, struct file *file)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-		outb(0, s->iobase+6);  /* disable DMA */
-		dealloc_dmabuf(s, &s->dma_dac);
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		outb(1, s->ddmabase+0xf); /* mask DMA channel */
-		outb(0, s->ddmabase+0xd); /* DMA master clear */
-		dealloc_dmabuf(s, &s->dma_adc);
-	}
-	s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static int solo1_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev = NULL;
-	
-	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-		struct pci_driver *drvr;
-
-		drvr = pci_dev_driver(pci_dev);
-		if (drvr != &solo1_driver)
-			continue;
-		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-		if (!s)
-			continue;
-		if (!((s->dev_audio ^ minor) & ~0xf))
-			break;
-	}
-	if (!s)
-		return -ENODEV;
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & (FMODE_READ | FMODE_WRITE)) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	s->fmt = AFMT_U8;
-	s->channels = 1;
-	s->rate = 8000;
-	s->clkdiv = 96 | 0x80;
-	s->ena = 0;
-	s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-	s->dma_adc.enabled = 1;
-	s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-	s->dma_dac.enabled = 1;
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	mutex_unlock(&s->open_mutex);
-	prog_codec(s);
-	return nonseekable_open(inode, file);
-}
-
-static /*const*/ struct file_operations solo1_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= solo1_read,
-	.write		= solo1_write,
-	.poll		= solo1_poll,
-	.ioctl		= solo1_ioctl,
-	.mmap		= solo1_mmap,
-	.open		= solo1_open,
-	.release	= solo1_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* hold spinlock for the following! */
-static void solo1_handle_midi(struct solo1_state *s)
-{
-	unsigned char ch;
-	int wake;
-
-	if (!(s->mpubase))
-		return;
-	wake = 0;
-	while (!(inb(s->mpubase+1) & 0x80)) {
-		ch = inb(s->mpubase);
-		if (s->midi.icnt < MIDIINBUF) {
-			s->midi.ibuf[s->midi.iwr] = ch;
-			s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-			s->midi.icnt++;
-		}
-		wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.iwait);
-	wake = 0;
-	while (!(inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) {
-		outb(s->midi.obuf[s->midi.ord], s->mpubase);
-		s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-		s->midi.ocnt--;
-		if (s->midi.ocnt < MIDIOUTBUF-16)
-			wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.owait);
-}
-
-static irqreturn_t solo1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct solo1_state *s = (struct solo1_state *)dev_id;
-	unsigned int intsrc;
-	
-	/* fastpath out, to ease interrupt sharing */
-	intsrc = inb(s->iobase+7); /* get interrupt source(s) */
-	if (!intsrc)
-		return IRQ_NONE;
-	(void)inb(s->sbbase+0xe);  /* clear interrupt */
-	spin_lock(&s->lock);
-	/* clear audio interrupts first */
-	if (intsrc & 0x20)
-		write_mixer(s, 0x7a, read_mixer(s, 0x7a) & 0x7f);
-	solo1_update_ptr(s);
-	solo1_handle_midi(s);
-	spin_unlock(&s->lock);
-	return IRQ_HANDLED;
-}
-
-static void solo1_midi_timer(unsigned long data)
-{
-	struct solo1_state *s = (struct solo1_state *)data;
-	unsigned long flags;
-	
-	spin_lock_irqsave(&s->lock, flags);
-	solo1_handle_midi(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->midi.timer.expires = jiffies+1;
-	add_timer(&s->midi.timer);
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t solo1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-	add_wait_queue(&s->midi.iwait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.ird;
-		cnt = MIDIINBUF - ptr;
-		if (s->midi.icnt < cnt)
-			cnt = s->midi.icnt;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIINBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.ird = ptr;
-		s->midi.icnt -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		break;
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&s->midi.iwait, &wait);
-	return ret;
-}
-
-static ssize_t solo1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.owr;
-		cnt = MIDIOUTBUF - ptr;
-		if (s->midi.ocnt + cnt > MIDIOUTBUF)
-			cnt = MIDIOUTBUF - s->midi.ocnt;
-		if (cnt <= 0) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			solo1_handle_midi(s);
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIOUTBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.owr = ptr;
-		s->midi.ocnt += cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		spin_lock_irqsave(&s->lock, flags);
-		solo1_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&s->midi.owait, &wait);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int solo1_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_flags & FMODE_WRITE)
-		poll_wait(file, &s->midi.owait, wait);
-	if (file->f_flags & FMODE_READ)
-		poll_wait(file, &s->midi.iwait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_flags & FMODE_READ) {
-		if (s->midi.icnt > 0)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_flags & FMODE_WRITE) {
-		if (s->midi.ocnt < MIDIOUTBUF)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int solo1_midi_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev = NULL;
-
-	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-		struct pci_driver *drvr;
-
-		drvr = pci_dev_driver(pci_dev);
-		if (drvr != &solo1_driver)
-			continue;
-		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-		if (!s)
-			continue;
-		if (s->dev_midi == minor)
-			break;
-	}
-	if (!s)
-		return -ENODEV;
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-		outb(0xff, s->mpubase+1); /* reset command */
-		outb(0x3f, s->mpubase+1); /* uart command */
-		if (!(inb(s->mpubase+1) & 0x80))
-			inb(s->mpubase);
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		outb(0xb0, s->iobase + 7); /* enable A1, A2, MPU irq's */
-		init_timer(&s->midi.timer);
-		s->midi.timer.expires = jiffies+1;
-		s->midi.timer.data = (unsigned long)s;
-		s->midi.timer.function = solo1_midi_timer;
-		add_timer(&s->midi.timer);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int solo1_midi_release(struct inode *inode, struct file *file)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	unsigned count, tmo;
-
-	VALIDATE_STATE(s);
-
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE) {
-		add_wait_queue(&s->midi.owait, &wait);
-		for (;;) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			spin_lock_irqsave(&s->lock, flags);
-			count = s->midi.ocnt;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (count <= 0)
-				break;
-			if (signal_pending(current))
-				break;
-			if (file->f_flags & O_NONBLOCK)
-				break;
-			tmo = (count * HZ) / 3100;
-			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG "solo1: midi timed out??\n");
-		}
-		remove_wait_queue(&s->midi.owait, &wait);
-		set_current_state(TASK_RUNNING);
-	}
-	mutex_lock(&s->open_mutex);
-	s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		outb(0x30, s->iobase + 7); /* enable A1, A2 irq's */
-		del_timer(&s->midi.timer);		
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations solo1_midi_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= solo1_midi_read,
-	.write		= solo1_midi_write,
-	.poll		= solo1_midi_poll,
-	.open		= solo1_midi_open,
-	.release	= solo1_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	static const unsigned char op_offset[18] = {
-		0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-		0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-		0x10, 0x11, 0x12, 0x13, 0x14, 0x15
-	};
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	struct dm_fm_voice v;
-	struct dm_fm_note n;
-	struct dm_fm_params p;
-	unsigned int io;
-	unsigned int regb;
-
-	switch (cmd) {		
-	case FM_IOCTL_RESET:
-		for (regb = 0xb0; regb < 0xb9; regb++) {
-			outb(regb, s->sbbase);
-			outb(0, s->sbbase+1);
-			outb(regb, s->sbbase+2);
-			outb(0, s->sbbase+3);
-		}
-		return 0;
-
-	case FM_IOCTL_PLAY_NOTE:
-		if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
-			return -EFAULT;
-		if (n.voice >= 18)
-			return -EINVAL;
-		if (n.voice >= 9) {
-			regb = n.voice - 9;
-			io = s->sbbase+2;
-		} else {
-			regb = n.voice;
-			io = s->sbbase;
-		}
-		outb(0xa0 + regb, io);
-		outb(n.fnum & 0xff, io+1);
-		outb(0xb0 + regb, io);
-		outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
-		return 0;
-
-	case FM_IOCTL_SET_VOICE:
-		if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
-			return -EFAULT;
-		if (v.voice >= 18)
-			return -EINVAL;
-		regb = op_offset[v.voice];
-		io = s->sbbase + ((v.op & 1) << 1);
-		outb(0x20 + regb, io);
-		outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | 
-		     ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
-		outb(0x40 + regb, io);
-		outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
-		outb(0x60 + regb, io);
-		outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
-		outb(0x80 + regb, io);
-		outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
-		outb(0xe0 + regb, io);
-		outb(v.waveform & 0x7, io+1);
-		if (n.voice >= 9) {
-			regb = n.voice - 9;
-			io = s->sbbase+2;
-		} else {
-			regb = n.voice;
-			io = s->sbbase;
-		}
-		outb(0xc0 + regb, io);
-		outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
-		     (v.connection & 1), io+1);
-		return 0;
-		
-	case FM_IOCTL_SET_PARAMS:
-		if (copy_from_user(&p, (void __user *)arg, sizeof(p)))
-			return -EFAULT;
-		outb(0x08, s->sbbase);
-		outb((p.kbd_split & 1) << 6, s->sbbase+1);
-		outb(0xbd, s->sbbase);
-		outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
-		     ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->sbbase+1);
-		return 0;
-
-	case FM_IOCTL_SET_OPL:
-		outb(4, s->sbbase+2);
-		outb(arg, s->sbbase+3);
-		return 0;
-
-	case FM_IOCTL_SET_MODE:
-		outb(5, s->sbbase+2);
-		outb(arg & 1, s->sbbase+3);
-		return 0;
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static int solo1_dmfm_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev = NULL;
-
-	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-		struct pci_driver *drvr;
-
-		drvr = pci_dev_driver(pci_dev);
-		if (drvr != &solo1_driver)
-			continue;
-		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-		if (!s)
-			continue;
-		if (s->dev_dmfm == minor)
-			break;
-	}
-	if (!s)
-		return -ENODEV;
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & FMODE_DMFM) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) {
-		mutex_unlock(&s->open_mutex);
-		printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n");
-		return -EBUSY;
-	}
-	/* init the stuff */
-	outb(1, s->sbbase);
-	outb(0x20, s->sbbase+1); /* enable waveforms */
-	outb(4, s->sbbase+2);
-	outb(0, s->sbbase+3);  /* no 4op enabled */
-	outb(5, s->sbbase+2);
-	outb(1, s->sbbase+3);  /* enable OPL3 */
-	s->open_mode |= FMODE_DMFM;
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int solo1_dmfm_release(struct inode *inode, struct file *file)
-{
-	struct solo1_state *s = (struct solo1_state *)file->private_data;
-	unsigned int regb;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	mutex_lock(&s->open_mutex);
-	s->open_mode &= ~FMODE_DMFM;
-	for (regb = 0xb0; regb < 0xb9; regb++) {
-		outb(regb, s->sbbase);
-		outb(0, s->sbbase+1);
-		outb(regb, s->sbbase+2);
-		outb(0, s->sbbase+3);
-	}
-	release_region(s->sbbase, FMSYNTH_EXTENT);
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations solo1_dmfm_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= solo1_dmfm_ioctl,
-	.open		= solo1_dmfm_open,
-	.release	= solo1_dmfm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-	int mixch;
-	int vol;
-} initvol[] __devinitdata = {
-	{ SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-	{ SOUND_MIXER_WRITE_PCM, 0x4040 },
-	{ SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-	{ SOUND_MIXER_WRITE_CD, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE1, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE2, 0x4040 },
-	{ SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-	{ SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
-	{ SOUND_MIXER_WRITE_MIC, 0x4040 }
-};
-
-static int setup_solo1(struct solo1_state *s)
-{
-	struct pci_dev *pcidev = s->dev;
-	mm_segment_t fs;
-	int i, val;
-
-	/* initialize DDMA base address */
-	printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
-	pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1);
-	/* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */
-	pci_write_config_dword(pcidev, 0x50, 0);
-	/* disable legacy audio address decode */
-	pci_write_config_word(pcidev, 0x40, 0x907f);
-
-	/* initialize the chips */
-	if (!reset_ctrl(s)) {
-		printk(KERN_ERR "esssolo1: cannot reset controller\n");
-		return -1;
-	}
-	outb(0xb0, s->iobase+7); /* enable A1, A2, MPU irq's */
-	
-	/* initialize mixer regs */
-	write_mixer(s, 0x7f, 0); /* disable music digital recording */
-	write_mixer(s, 0x7d, 0x0c); /* enable mic preamp, MONO_OUT is 2nd DAC right channel */
-	write_mixer(s, 0x64, 0x45); /* volume control */
-	write_mixer(s, 0x48, 0x10); /* enable music DAC/ES6xx interface */
-	write_mixer(s, 0x50, 0);  /* disable spatializer */
-	write_mixer(s, 0x52, 0);
-	write_mixer(s, 0x14, 0);  /* DAC1 minimum volume */
-	write_mixer(s, 0x71, 0x20); /* enable new 0xA1 reg format */
-	outb(0, s->ddmabase+0xd); /* DMA master clear */
-	outb(1, s->ddmabase+0xf); /* mask channel */
-	/*outb(0, s->ddmabase+0x8);*/ /* enable controller (enable is low active!!) */
-
-	pci_set_master(pcidev);  /* enable bus mastering */
-	
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	val = SOUND_MASK_LINE;
-	mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-	for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-		val = initvol[i].vol;
-		mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-	}
-	val = 1; /* enable mic preamp */
-	mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val);
-	set_fs(fs);
-	return 0;
-}
-
-static int
-solo1_suspend(struct pci_dev *pci_dev, pm_message_t state) {
-	struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-	if (!s)
-		return 1;
-	outb(0, s->iobase+6);
-	/* DMA master clear */
-	outb(0, s->ddmabase+0xd); 
-	/* reset sequencer and FIFO */
-	outb(3, s->sbbase+6); 
-	/* turn off DDMA controller address space */
-	pci_write_config_word(s->dev, 0x60, 0); 
-	return 0;
-}
-
-static int
-solo1_resume(struct pci_dev *pci_dev) {
-	struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-	if (!s)
-		return 1;
-	setup_solo1(s);
-	return 0;
-}
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit solo1_register_gameport(struct solo1_state *s, int io_port)
-{
-	struct gameport *gp;
-
-	if (!request_region(io_port, GAMEPORT_EXTENT, "ESS Solo1")) {
-		printk(KERN_ERR "solo1: gameport io ports are in use\n");
-		return -EBUSY;
-	}
-
-	s->gameport = gp = gameport_allocate_port();
-	if (!gp) {
-		printk(KERN_ERR "solo1: can not allocate memory for gameport\n");
-		release_region(io_port, GAMEPORT_EXTENT);
-		return -ENOMEM;
-	}
-
-	gameport_set_name(gp, "ESS Solo1 Gameport");
-	gameport_set_phys(gp, "isa%04x/gameport0", io_port);
-	gp->dev.parent = &s->dev->dev;
-	gp->io = io_port;
-
-	gameport_register_port(gp);
-
-	return 0;
-}
-
-static inline void solo1_unregister_gameport(struct solo1_state *s)
-{
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, GAMEPORT_EXTENT);
-	}
-}
-#else
-static inline int solo1_register_gameport(struct solo1_state *s, int io_port) { return -ENOSYS; }
-static inline void solo1_unregister_gameport(struct solo1_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-	struct solo1_state *s;
-	int gpio;
-	int ret;
-
- 	if ((ret=pci_enable_device(pcidev)))
-		return ret;
-	if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) ||
-	    !(pci_resource_flags(pcidev, 1) & IORESOURCE_IO) ||
-	    !(pci_resource_flags(pcidev, 2) & IORESOURCE_IO) ||
-	    !(pci_resource_flags(pcidev, 3) & IORESOURCE_IO))
-		return -ENODEV;
-	if (pcidev->irq == 0)
-		return -ENODEV;
-
-	/* Recording requires 24-bit DMA, so attempt to set dma mask
-	 * to 24 bits first, then 32 bits (playback only) if that fails.
-	 */
-	if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK) &&
-	    pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
-		printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n");
-		return -ENODEV;
-	}
-
-	if (!(s = kmalloc(sizeof(struct solo1_state), GFP_KERNEL))) {
-		printk(KERN_WARNING "solo1: out of memory\n");
-		return -ENOMEM;
-	}
-	memset(s, 0, sizeof(struct solo1_state));
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac.wait);
-	init_waitqueue_head(&s->open_wait);
-	init_waitqueue_head(&s->midi.iwait);
-	init_waitqueue_head(&s->midi.owait);
-	mutex_init(&s->open_mutex);
-	spin_lock_init(&s->lock);
-	s->magic = SOLO1_MAGIC;
-	s->dev = pcidev;
-	s->iobase = pci_resource_start(pcidev, 0);
-	s->sbbase = pci_resource_start(pcidev, 1);
-	s->vcbase = pci_resource_start(pcidev, 2);
-	s->ddmabase = s->vcbase + DDMABASE_OFFSET;
-	s->mpubase = pci_resource_start(pcidev, 3);
-	gpio = pci_resource_start(pcidev, 4);
-	s->irq = pcidev->irq;
-	ret = -EBUSY;
-	if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) {
-		printk(KERN_ERR "solo1: io ports in use\n");
-		goto err_region1;
-	}
-	if (!request_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT, "ESS Solo1")) {
-		printk(KERN_ERR "solo1: io ports in use\n");
-		goto err_region2;
-	}
-	if (!request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1")) {
-		printk(KERN_ERR "solo1: io ports in use\n");
-		goto err_region3;
-	}
-	if (!request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1")) {
-		printk(KERN_ERR "solo1: io ports in use\n");
-		goto err_region4;
-	}
-	if ((ret=request_irq(s->irq,solo1_interrupt,IRQF_SHARED,"ESS Solo1",s))) {
-		printk(KERN_ERR "solo1: irq %u in use\n", s->irq);
-		goto err_irq;
-	}
-	/* register devices */
-	if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0) {
-		ret = s->dev_audio;
-		goto err_dev1;
-	}
-	if ((s->dev_mixer = register_sound_mixer(&solo1_mixer_fops, -1)) < 0) {
-		ret = s->dev_mixer;
-		goto err_dev2;
-	}
-	if ((s->dev_midi = register_sound_midi(&solo1_midi_fops, -1)) < 0) {
-		ret = s->dev_midi;
-		goto err_dev3;
-	}
-	if ((s->dev_dmfm = register_sound_special(&solo1_dmfm_fops, 15 /* ?? */)) < 0) {
-		ret = s->dev_dmfm;
-		goto err_dev4;
-	}
-	if (setup_solo1(s)) {
-		ret = -EIO;
-		goto err;
-	}
-	/* register gameport */
-	solo1_register_gameport(s, gpio);
-	/* store it in the driver field */
-	pci_set_drvdata(pcidev, s);
-	return 0;
-
- err:
-	unregister_sound_special(s->dev_dmfm);
- err_dev4:
-	unregister_sound_midi(s->dev_midi);
- err_dev3:
-	unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-	unregister_sound_dsp(s->dev_audio);
- err_dev1:
-	printk(KERN_ERR "solo1: initialisation error\n");
-	free_irq(s->irq, s);
- err_irq:
-	release_region(s->mpubase, MPUBASE_EXTENT);
- err_region4:
-	release_region(s->ddmabase, DDMABASE_EXTENT);
- err_region3:
-	release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
- err_region2:
-	release_region(s->iobase, IOBASE_EXTENT);
- err_region1:
-	kfree(s);
-	return ret;
-}
-
-static void __devexit solo1_remove(struct pci_dev *dev)
-{
-	struct solo1_state *s = pci_get_drvdata(dev);
-	
-	if (!s)
-		return;
-	/* stop DMA controller */
-	outb(0, s->iobase+6);
-	outb(0, s->ddmabase+0xd); /* DMA master clear */
-	outb(3, s->sbbase+6); /* reset sequencer and FIFO */
-	synchronize_irq(s->irq);
-	pci_write_config_word(s->dev, 0x60, 0); /* turn off DDMA controller address space */
-	free_irq(s->irq, s);
-	solo1_unregister_gameport(s);
-	release_region(s->iobase, IOBASE_EXTENT);
-	release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
-	release_region(s->ddmabase, DDMABASE_EXTENT);
-	release_region(s->mpubase, MPUBASE_EXTENT);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->dev_mixer);
-	unregister_sound_midi(s->dev_midi);
-	unregister_sound_special(s->dev_dmfm);
-	kfree(s);
-	pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-	{ PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver solo1_driver = {
-	.name		= "ESS Solo1",
-	.id_table	= id_table,
-	.probe		= solo1_probe,
-	.remove		= __devexit_p(solo1_remove),
-	.suspend	= solo1_suspend,
-	.resume		= solo1_resume,
-};
-
-
-static int __init init_solo1(void)
-{
-	printk(KERN_INFO "solo1: version v0.20 time " __TIME__ " " __DATE__ "\n");
-	return pci_register_driver(&solo1_driver);
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ESS Solo1 Driver");
-MODULE_LICENSE("GPL");
-
-
-static void __exit cleanup_solo1(void)
-{
-	printk(KERN_INFO "solo1: unloading\n");
-	pci_unregister_driver(&solo1_driver);
-}
-
-/* --------------------------------------------------------------------- */
-
-module_init(init_solo1);
-module_exit(cleanup_solo1);
-
diff --git a/sound/oss/forte.c b/sound/oss/forte.c
deleted file mode 100644
index ea1c020..0000000
--- a/sound/oss/forte.c
+++ /dev/null
@@ -1,2139 +0,0 @@
-/*
- * forte.c - ForteMedia FM801 OSS Driver
- *
- * Written by Martin K. Petersen <mkp@mkp.net>
- * Copyright (C) 2002 Hewlett-Packard Company
- * Portions Copyright (C) 2003 Martin K. Petersen
- *
- * Latest version: http://mkp.net/forte/
- *
- * Based upon the ALSA FM801 driver by Jaroslav Kysela and OSS drivers
- * by Thomas Sailer, Alan Cox, Zach Brown, and Jeff Garzik.  Thanks
- * guys!
- *
- * 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.
- *
- * 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/kernel.h>
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/pci.h>
-
-#include <linux/delay.h>
-#include <linux/poll.h>
-
-#include <linux/sound.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-
-#include <linux/proc_fs.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#define DRIVER_NAME	"forte"
-#define DRIVER_VERSION 	"$Id: forte.c,v 1.63 2003/03/01 05:32:42 mkp Exp $"
-#define PFX 		DRIVER_NAME ": "
-
-#undef M_DEBUG
-
-#ifdef M_DEBUG
-#define DPRINTK(args...) printk(KERN_WARNING args)
-#else
-#define DPRINTK(args...)
-#endif
-
-/* Card capabilities */
-#define FORTE_CAPS              (DSP_CAP_MMAP | DSP_CAP_TRIGGER)
-
-/* Supported audio formats */
-#define FORTE_FMTS		(AFMT_U8 | AFMT_S16_LE)
-
-/* Buffers */
-#define FORTE_MIN_FRAG_SIZE     256
-#define FORTE_MAX_FRAG_SIZE     PAGE_SIZE
-#define FORTE_DEF_FRAG_SIZE     256
-#define FORTE_MIN_FRAGMENTS     2
-#define FORTE_MAX_FRAGMENTS     256
-#define FORTE_DEF_FRAGMENTS     2
-#define FORTE_MIN_BUF_MSECS     500
-#define FORTE_MAX_BUF_MSECS     1000
-
-/* PCI BARs */
-#define FORTE_PCM_VOL           0x00    /* PCM Output Volume */
-#define FORTE_FM_VOL            0x02    /* FM Output Volume */
-#define FORTE_I2S_VOL           0x04    /* I2S Volume */
-#define FORTE_REC_SRC           0x06    /* Record Source */
-#define FORTE_PLY_CTRL          0x08    /* Playback Control */
-#define FORTE_PLY_COUNT         0x0a    /* Playback Count */
-#define FORTE_PLY_BUF1          0x0c    /* Playback Buffer I */
-#define FORTE_PLY_BUF2          0x10    /* Playback Buffer II */
-#define FORTE_CAP_CTRL          0x14    /* Capture Control */
-#define FORTE_CAP_COUNT         0x16    /* Capture Count */
-#define FORTE_CAP_BUF1          0x18    /* Capture Buffer I */
-#define FORTE_CAP_BUF2          0x1c    /* Capture Buffer II */
-#define FORTE_CODEC_CTRL        0x22    /* Codec Control */
-#define FORTE_I2S_MODE          0x24    /* I2S Mode Control */
-#define FORTE_VOLUME            0x26    /* Volume Up/Down/Mute Status */
-#define FORTE_I2C_CTRL          0x29    /* I2C Control */
-#define FORTE_AC97_CMD          0x2a    /* AC'97 Command */
-#define FORTE_AC97_DATA         0x2c    /* AC'97 Data */
-#define FORTE_MPU401_DATA       0x30    /* MPU401 Data */
-#define FORTE_MPU401_CMD        0x31    /* MPU401 Command */
-#define FORTE_GPIO_CTRL         0x52    /* General Purpose I/O Control */
-#define FORTE_GEN_CTRL          0x54    /* General Control */
-#define FORTE_IRQ_MASK          0x56    /* Interrupt Mask */
-#define FORTE_IRQ_STATUS        0x5a    /* Interrupt Status */
-#define FORTE_OPL3_BANK0        0x68    /* OPL3 Status Read / Bank 0 Write */
-#define FORTE_OPL3_DATA0        0x69    /* OPL3 Data 0 Write */
-#define FORTE_OPL3_BANK1        0x6a    /* OPL3 Bank 1 Write */
-#define FORTE_OPL3_DATA1        0x6b    /* OPL3 Bank 1 Write */
-#define FORTE_POWERDOWN         0x70    /* Blocks Power Down Control */
-
-#define FORTE_CAP_OFFSET        FORTE_CAP_CTRL - FORTE_PLY_CTRL
-
-#define FORTE_AC97_ADDR_SHIFT   10
-
-/* Playback and record control register bits */
-#define FORTE_BUF1_LAST         (1<<1)
-#define FORTE_BUF2_LAST         (1<<2)
-#define FORTE_START             (1<<5)
-#define FORTE_PAUSE             (1<<6)
-#define FORTE_IMMED_STOP        (1<<7)
-#define FORTE_RATE_SHIFT        8
-#define FORTE_RATE_MASK         (15 << FORTE_RATE_SHIFT)
-#define FORTE_CHANNELS_4        (1<<12) /* Playback only */
-#define FORTE_CHANNELS_6        (2<<12) /* Playback only */
-#define FORTE_CHANNELS_6MS      (3<<12) /* Playback only */
-#define FORTE_CHANNELS_MASK     (3<<12)
-#define FORTE_16BIT             (1<<14)
-#define FORTE_STEREO            (1<<15)
-
-/* IRQ status bits */
-#define FORTE_IRQ_PLAYBACK      (1<<8)
-#define FORTE_IRQ_CAPTURE       (1<<9)
-#define FORTE_IRQ_VOLUME        (1<<14)
-#define FORTE_IRQ_MPU           (1<<15)
-
-/* CODEC control */
-#define FORTE_CC_CODEC_RESET    (1<<5)
-#define FORTE_CC_AC97_RESET     (1<<6)
-
-/* AC97 cmd */
-#define FORTE_AC97_WRITE        (0<<7)
-#define FORTE_AC97_READ         (1<<7)
-#define FORTE_AC97_DP_INVALID   (0<<8)
-#define FORTE_AC97_DP_VALID     (1<<8)
-#define FORTE_AC97_PORT_RDY     (0<<9)
-#define FORTE_AC97_PORT_BSY     (1<<9)
-
-
-struct forte_channel {
-        const char 		*name;
-
-	unsigned short		ctrl; 		/* Ctrl BAR contents */
-	unsigned long 		iobase;		/* Ctrl BAR address */
-
-	wait_queue_head_t	wait;
-
-	void 			*buf; 		/* Buffer */
-	dma_addr_t		buf_handle; 	/* Buffer handle */
-
-        unsigned int 		record;
-	unsigned int		format;
-        unsigned int		rate;
-	unsigned int		stereo;
-
-	unsigned int		frag_sz; 	/* Current fragment size */
-	unsigned int		frag_num; 	/* Current # of fragments */
-	unsigned int		frag_msecs;     /* Milliseconds per frag */
-	unsigned int		buf_sz;		/* Current buffer size */
-
-	unsigned int		hwptr;		/* Tail */
-	unsigned int		swptr; 		/* Head */
-	unsigned int		filled_frags; 	/* Fragments currently full */
-	unsigned int		next_buf;	/* Index of next buffer */
-
-	unsigned int		active;		/* Channel currently in use */
-	unsigned int		mapped;		/* mmap */
-
-	unsigned int		buf_pages;	/* Real size of buffer */
-	unsigned int		nr_irqs;	/* Number of interrupts */
-	unsigned int		bytes;		/* Total bytes */
-	unsigned int		residue;	/* Partial fragment */
-};
-
-
-struct forte_chip {
-	struct pci_dev		*pci_dev;
-	unsigned long		iobase;
-	int			irq;
-
-	struct mutex		open_mutex; 	/* Device access */
-	spinlock_t		lock;		/* State */
-
-	spinlock_t		ac97_lock;
-	struct ac97_codec	*ac97;
-
-	int			multichannel;
-	int			dsp; 		/* OSS handle */
-	int                     trigger;	/* mmap I/O trigger */
-
-	struct forte_channel	play;
-	struct forte_channel	rec;
-};
-
-
-static int channels[] = { 2, 4, 6, };
-static int rates[]    = { 5500, 8000, 9600, 11025, 16000, 19200, 
-			  22050, 32000, 38400, 44100, 48000, };
-
-static struct forte_chip *forte;
-static int found;
-
-
-/* AC97 Codec -------------------------------------------------------------- */
-
-
-/** 
- * forte_ac97_wait:
- * @chip:	fm801 instance whose AC97 codec to wait on
- *
- * FIXME:
- *		Stop busy-waiting
- */
-
-static inline int
-forte_ac97_wait (struct forte_chip *chip)
-{
-	int i = 10000;
-
-	while ( (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_PORT_BSY) 
-		&& i-- )
-		cpu_relax();
-
-	return i == 0;
-}
-
-
-/**
- * forte_ac97_read:
- * @codec:	AC97 codec to read from
- * @reg:	register to read
- */
-
-static u16
-forte_ac97_read (struct ac97_codec *codec, u8 reg)
-{
-	u16 ret = 0;
-	struct forte_chip *chip = codec->private_data;
-
-	spin_lock (&chip->ac97_lock);
-
-	/* Knock, knock */
-	if (forte_ac97_wait (chip)) {
-		printk (KERN_ERR PFX "ac97_read: Serial bus busy\n");
-		goto out;
-	}
-
-	/* Send read command */
-	outw (reg | (1<<7), chip->iobase + FORTE_AC97_CMD);
-
-	if (forte_ac97_wait (chip)) {
-		printk (KERN_ERR PFX "ac97_read: Bus busy reading reg 0x%x\n",
-			reg);
-		goto out;
-	}
-	
-	/* Sanity checking */
-	if (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_DP_INVALID) {
-		printk (KERN_ERR PFX "ac97_read: Invalid data port");
-		goto out;
-	}
-
-	/* Fetch result */
-	ret = inw (chip->iobase + FORTE_AC97_DATA);
-
- out:
-	spin_unlock (&chip->ac97_lock);
-	return ret;
-}
-
-
-/**
- * forte_ac97_write:
- * @codec:	AC97 codec to send command to
- * @reg:	register to write
- * @val:	value to write
- */
-
-static void
-forte_ac97_write (struct ac97_codec *codec, u8 reg, u16 val)
-{
-	struct forte_chip *chip = codec->private_data;
-
-	spin_lock (&chip->ac97_lock);
-
-	/* Knock, knock */
-	if (forte_ac97_wait (chip)) {
-		printk (KERN_ERR PFX "ac97_write: Serial bus busy\n");
-		goto out;
-	}
-
-	outw (val, chip->iobase + FORTE_AC97_DATA);
-	outb (reg | FORTE_AC97_WRITE, chip->iobase + FORTE_AC97_CMD);
-
-	/* Wait for completion */
-	if (forte_ac97_wait (chip)) {
-		printk (KERN_ERR PFX "ac97_write: Bus busy after write\n");
-		goto out;
-	}
-
- out:
-	spin_unlock (&chip->ac97_lock);
-}
-
-
-/* Mixer ------------------------------------------------------------------- */
-
-
-/**
- * forte_mixer_open:
- * @inode:		
- * @file:		
- */
-
-static int
-forte_mixer_open (struct inode *inode, struct file *file)
-{
-	struct forte_chip *chip = forte;
-	file->private_data = chip->ac97;
-	return 0;
-}
-
-
-/**
- * forte_mixer_release:
- * @inode:		
- * @file:		
- */
-
-static int
-forte_mixer_release (struct inode *inode, struct file *file)
-{
-	/* We will welease Wodewick */
-	return 0;
-}
-
-
-/**
- * forte_mixer_ioctl:
- * @inode:		
- * @file:		
- */
-
-static int
-forte_mixer_ioctl (struct inode *inode, struct file *file, 
-		   unsigned int cmd, unsigned long arg)
-{
-	struct ac97_codec *codec = (struct ac97_codec *) file->private_data;
-
-	return codec->mixer_ioctl (codec, cmd, arg);
-}
-
-
-static struct file_operations forte_mixer_fops = {
-	.owner			= THIS_MODULE,
-	.llseek         	= no_llseek,
-	.ioctl          	= forte_mixer_ioctl,
-	.open           	= forte_mixer_open,
-	.release        	= forte_mixer_release,
-};
-
-
-/* Channel ----------------------------------------------------------------- */
-
-/** 
- * forte_channel_reset:
- * @channel:	Channel to reset
- * 
- * Locking:	Must be called with lock held.
- */
-
-static void
-forte_channel_reset (struct forte_channel *channel)
-{
-	if (!channel || !channel->iobase)
-		return;
-
-	DPRINTK ("%s: channel = %s\n", __FUNCTION__, channel->name);
-
-	channel->ctrl &= ~FORTE_START;
-	outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-	
-	/* We always play at least two fragments, hence these defaults */
- 	channel->hwptr = channel->frag_sz;
-	channel->next_buf = 1;
-	channel->swptr = 0;
-	channel->filled_frags = 0;
-	channel->active = 0;
-	channel->bytes = 0;
-	channel->nr_irqs = 0;
-	channel->mapped = 0;
-	channel->residue = 0;
-}
-
-
-/** 
- * forte_channel_start:
- * @channel: 	Channel to start (record/playback)
- *
- * Locking:	Must be called with lock held.
- */
-
-static void inline
-forte_channel_start (struct forte_channel *channel)
-{
-	if (!channel || !channel->iobase || channel->active) 
-		return;
-
-	channel->ctrl &= ~(FORTE_PAUSE | FORTE_BUF1_LAST | FORTE_BUF2_LAST
-			   | FORTE_IMMED_STOP);
-	channel->ctrl |= FORTE_START;
-	channel->active = 1;
-	outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_stop:
- * @channel: 	Channel to stop
- *
- * Locking:	Must be called with lock held.
- */
-
-static void inline
-forte_channel_stop (struct forte_channel *channel)
-{
-	if (!channel || !channel->iobase) 
-		return;
-
-	channel->ctrl &= ~(FORTE_START | FORTE_PAUSE);	
-	channel->ctrl |= FORTE_IMMED_STOP;
-
-	channel->active = 0;
-	outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_pause:
- * @channel: 	Channel to pause
- *
- * Locking:	Must be called with lock held.
- */
-
-static void inline
-forte_channel_pause (struct forte_channel *channel)
-{
-	if (!channel || !channel->iobase) 
-		return;
-
-	channel->ctrl |= FORTE_PAUSE;
-
-	channel->active = 0;
-	outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_rate:
- * @channel: 	Channel whose rate to set.  Playback and record are
- *           	independent.
- * @rate:    	Channel rate in Hz
- *
- * Locking:	Must be called with lock held.
- */
-
-static int
-forte_channel_rate (struct forte_channel *channel, unsigned int rate)
-{
-	int new_rate;
-
-	if (!channel || !channel->iobase) 
-		return -EINVAL;
-
-	/* The FM801 only supports a handful of fixed frequencies.
-	 * We find the value closest to what userland requested.
-	 */
-	if      (rate <= 6250)  { rate = 5500;  new_rate =  0; }
-	else if (rate <= 8800)  { rate = 8000;  new_rate =  1; }
-	else if (rate <= 10312) { rate = 9600;  new_rate =  2; }
-	else if (rate <= 13512) { rate = 11025; new_rate =  3; }
-	else if (rate <= 17600) { rate = 16000; new_rate =  4; }
-	else if (rate <= 20625) { rate = 19200; new_rate =  5; }
-	else if (rate <= 27025) { rate = 22050; new_rate =  6; }
-	else if (rate <= 35200) { rate = 32000; new_rate =  7; }
-	else if (rate <= 41250) { rate = 38400; new_rate =  8; }
-	else if (rate <= 46050) { rate = 44100; new_rate =  9; }
-	else                    { rate = 48000; new_rate = 10; }
-
-	channel->ctrl &= ~FORTE_RATE_MASK;
-	channel->ctrl |= new_rate << FORTE_RATE_SHIFT;
-	channel->rate = rate;
-
-	DPRINTK ("%s: %s rate = %d\n", __FUNCTION__, channel->name, rate);
-
-	return rate;
-}
-
-
-/** 
- * forte_channel_format:
- * @channel: 	Channel whose audio format to set
- * @format:  	OSS format ID
- *
- * Locking:	Must be called with lock held.
- */
-
-static int
-forte_channel_format (struct forte_channel *channel, int format)
-{
-	if (!channel || !channel->iobase) 
-		return -EINVAL;
-
-	switch (format) {
-
-	case AFMT_QUERY:
-		break;
-	
-	case AFMT_U8:
-		channel->ctrl &= ~FORTE_16BIT;
-		channel->format = AFMT_U8;
-		break;
-
-	case AFMT_S16_LE:
-	default:
-		channel->ctrl |= FORTE_16BIT;
-		channel->format = AFMT_S16_LE;
-		break;
-	}
-
-	DPRINTK ("%s: %s want %d format, got %d\n", __FUNCTION__, channel->name, 
-		 format, channel->format);
-
-	return channel->format;
-}
-
-
-/** 
- * forte_channel_stereo:
- * @channel: 	Channel to toggle
- * @stereo:  	0 for Mono, 1 for Stereo
- *
- * Locking:	Must be called with lock held.
- */
-
-static int
-forte_channel_stereo (struct forte_channel *channel, unsigned int stereo)
-{
-	int ret;
-
-	if (!channel || !channel->iobase)
-		return -EINVAL;
-
-	DPRINTK ("%s: %s stereo = %d\n", __FUNCTION__, channel->name, stereo);
-
-	switch (stereo) {
-
-	case 0:
-		channel->ctrl &= ~(FORTE_STEREO | FORTE_CHANNELS_MASK);
-		channel-> stereo = stereo;
-		ret = stereo;
-		break;
-
-	case 1:
-		channel->ctrl &= ~FORTE_CHANNELS_MASK;
-		channel->ctrl |= FORTE_STEREO;
-		channel-> stereo = stereo;
-		ret = stereo;
-		break;
-
-	default:
-		DPRINTK ("Unsupported channel format");
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-
-/** 
- * forte_channel_buffer:
- * @channel:	Channel whose buffer to set up
- *
- * Locking:	Must be called with lock held.
- */
-
-static void
-forte_channel_buffer (struct forte_channel *channel, int sz, int num)
-{
-	unsigned int msecs, shift;
-
-	/* Go away, I'm busy */
-	if (channel->filled_frags || channel->bytes)
-		return;
-
-	/* Fragment size must be a power of 2 */
-	shift = 0; sz++;
-	while (sz >>= 1)
-		shift++;
-	channel->frag_sz = 1 << shift;
-
-	/* Round fragment size to something reasonable */
-	if (channel->frag_sz < FORTE_MIN_FRAG_SIZE)
-		channel->frag_sz = FORTE_MIN_FRAG_SIZE;
-
-	if (channel->frag_sz > FORTE_MAX_FRAG_SIZE)
-		channel->frag_sz = FORTE_MAX_FRAG_SIZE;
-
-	/* Find fragment length in milliseconds */
-	msecs = channel->frag_sz /
-		(channel->format == AFMT_S16_LE ? 2 : 1) /
-		(channel->stereo ? 2 : 1) /
-		(channel->rate / 1000);
-
-	channel->frag_msecs = msecs;
-
-	/* Pick a suitable number of fragments */
-	if (msecs * num < FORTE_MIN_BUF_MSECS)
-	     num = FORTE_MIN_BUF_MSECS / msecs;
-
-	if (msecs * num > FORTE_MAX_BUF_MSECS)
-	     num = FORTE_MAX_BUF_MSECS / msecs;
-
-	/* Fragment number must be a power of 2 */
-	shift = 0;	
-	while (num >>= 1)
-		shift++;
-	channel->frag_num = 1 << (shift + 1);
-
-	/* Round fragment number to something reasonable */
-	if (channel->frag_num < FORTE_MIN_FRAGMENTS)
-		channel->frag_num = FORTE_MIN_FRAGMENTS;
-
-	if (channel->frag_num > FORTE_MAX_FRAGMENTS)
-		channel->frag_num = FORTE_MAX_FRAGMENTS;
-
-	channel->buf_sz = channel->frag_sz * channel->frag_num;
-
-	DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d\n",
-		 __FUNCTION__, channel->name, channel->frag_sz, 
-		 channel->frag_num, channel->buf_sz);
-}
-
-
-/** 
- * forte_channel_prep:
- * @channel:	Channel whose buffer to prepare
- *
- * Locking:	Lock held.
- */
-
-static void
-forte_channel_prep (struct forte_channel *channel)
-{
-	struct page *page;
-	int i;
-	
-	if (channel->buf)
-		return;
-
-	forte_channel_buffer (channel, channel->frag_sz, channel->frag_num);
-	channel->buf_pages = channel->buf_sz >> PAGE_SHIFT;
-
-	if (channel->buf_sz % PAGE_SIZE)
-		channel->buf_pages++;
-
-	DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d, pg = %d\n", 
-		 __FUNCTION__, channel->name, channel->frag_sz, 
-		 channel->frag_num, channel->buf_sz, channel->buf_pages);
-
-	/* DMA buffer */
-	channel->buf = pci_alloc_consistent (forte->pci_dev, 
-					     channel->buf_pages * PAGE_SIZE,
-					     &channel->buf_handle);
-
-	if (!channel->buf || !channel->buf_handle)
-		BUG();
-
-	page = virt_to_page (channel->buf);
-	
-	/* FIXME: can this go away ? */
-	for (i = 0 ; i < channel->buf_pages ; i++)
-		SetPageReserved(page++);
-
-	/* Prep buffer registers */
-	outw (channel->frag_sz - 1, channel->iobase + FORTE_PLY_COUNT);
-	outl (channel->buf_handle, channel->iobase + FORTE_PLY_BUF1);
-	outl (channel->buf_handle + channel->frag_sz, 
-	      channel->iobase + FORTE_PLY_BUF2);
-
-	/* Reset hwptr */
- 	channel->hwptr = channel->frag_sz;
-	channel->next_buf = 1;
-
-	DPRINTK ("%s: %s buffer @ %p (%p)\n", __FUNCTION__, channel->name, 
-		 channel->buf, channel->buf_handle);
-}
-
-
-/** 
- * forte_channel_drain:
- * @chip:	
- * @channel:	
- *
- * Locking:	Don't hold the lock.
- */
-
-static inline int
-forte_channel_drain (struct forte_channel *channel)
-{
-	DECLARE_WAITQUEUE (wait, current);
-	unsigned long flags;
-
-	DPRINTK ("%s\n", __FUNCTION__);
-
-	if (channel->mapped) {
-		spin_lock_irqsave (&forte->lock, flags);
-		forte_channel_stop (channel);
-		spin_unlock_irqrestore (&forte->lock, flags);
-		return 0;
-	}
-
-	spin_lock_irqsave (&forte->lock, flags);
-	add_wait_queue (&channel->wait, &wait);
-
-	for (;;) {
-		if (channel->active == 0 || channel->filled_frags == 1)
-			break;
-
-		spin_unlock_irqrestore (&forte->lock, flags);
-
-		__set_current_state (TASK_INTERRUPTIBLE);
-		schedule();
-
-		spin_lock_irqsave (&forte->lock, flags);
-	}
-
-	forte_channel_stop (channel);
-	forte_channel_reset (channel);
-	set_current_state (TASK_RUNNING);
-	remove_wait_queue (&channel->wait, &wait);
-	spin_unlock_irqrestore (&forte->lock, flags);
-
-	return 0;
-}
-
-
-/** 
- * forte_channel_init:
- * @chip: 	Forte chip instance the channel hangs off
- * @channel: 	Channel to initialize
- *
- * Description:
- *	        Initializes a channel, sets defaults, and allocates
- *	        buffers.
- *
- * Locking:	No lock held.
- */
-
-static int
-forte_channel_init (struct forte_chip *chip, struct forte_channel *channel)
-{
-	DPRINTK ("%s: chip iobase @ %p\n", __FUNCTION__, (void *)chip->iobase);
-
-	spin_lock_irq (&chip->lock);
-	memset (channel, 0x0, sizeof (*channel));
-
-	if (channel == &chip->play) {
-		channel->name = "PCM_OUT";
-		channel->iobase = chip->iobase;
-		DPRINTK ("%s: PCM-OUT iobase @ %p\n", __FUNCTION__,
-			 (void *) channel->iobase);
-	}
-	else if (channel == &chip->rec) {
-		channel->name = "PCM_IN";
-		channel->iobase = chip->iobase + FORTE_CAP_OFFSET;
-		channel->record = 1;
-		DPRINTK ("%s: PCM-IN iobase @ %p\n", __FUNCTION__, 
-			 (void *) channel->iobase);
-	}
-	else
-		BUG();
-
-	init_waitqueue_head (&channel->wait);
-
-	/* Defaults: 48kHz, 16-bit, stereo */
-	channel->ctrl = inw (channel->iobase + FORTE_PLY_CTRL);
-	forte_channel_reset (channel);
-	forte_channel_stereo (channel, 1);
-	forte_channel_format (channel, AFMT_S16_LE);
-	forte_channel_rate (channel, 48000);
-	channel->frag_sz = FORTE_DEF_FRAG_SIZE;
-	channel->frag_num = FORTE_DEF_FRAGMENTS;
-
-	chip->trigger = 0;
-	spin_unlock_irq (&chip->lock);
-
-	return 0;
-}
-
-
-/** 
- * forte_channel_free:
- * @chip:	Chip this channel hangs off
- * @channel:	Channel to nuke 
- *
- * Description:
- * 		Resets channel and frees buffers.
- *
- * Locking:	Hold your horses.
- */
-
-static void
-forte_channel_free (struct forte_chip *chip, struct forte_channel *channel)
-{
-	DPRINTK ("%s: %s\n", __FUNCTION__, channel->name);
-
-	if (!channel->buf_handle)
-		return;
-
-	pci_free_consistent (chip->pci_dev, channel->buf_pages * PAGE_SIZE, 
-			     channel->buf, channel->buf_handle);
-	
-	memset (channel, 0x0, sizeof (*channel));
-}
-
-
-/* DSP --------------------------------------------------------------------- */
-
-
-/**
- * forte_dsp_ioctl:
- */
-
-static int
-forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
-		 unsigned long arg)
-{
-	int ival=0, ret, rval=0, rd, wr, count;
-	struct forte_chip *chip;
-	struct audio_buf_info abi;
-	struct count_info cinfo;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	chip = file->private_data;
-	
-	if (file->f_mode & FMODE_WRITE)
-		wr = 1;
-	else 
-		wr = 0;
-
-	if (file->f_mode & FMODE_READ)
-		rd = 1;
-	else
-		rd = 0;
-
-	switch (cmd) {
-
-	case OSS_GETVERSION:
-		return put_user (SOUND_VERSION, p);
-
-	case SNDCTL_DSP_GETCAPS:
-		DPRINTK ("%s: GETCAPS\n", __FUNCTION__);
-
-		ival = FORTE_CAPS; /* DUPLEX */
-		return put_user (ival, p);
-
-	case SNDCTL_DSP_GETFMTS:
-		DPRINTK ("%s: GETFMTS\n", __FUNCTION__);
-
-		ival = FORTE_FMTS; /* U8, 16LE */
-		return put_user (ival, p);
-
-	case SNDCTL_DSP_SETFMT:	/* U8, 16LE */
-		DPRINTK ("%s: SETFMT\n", __FUNCTION__);
-
-		if (get_user (ival, p))
-			return -EFAULT;
-
-		spin_lock_irq (&chip->lock);
-
-		if (rd) {
-			forte_channel_stop (&chip->rec);
-			rval = forte_channel_format (&chip->rec, ival);
-		}
-
-		if (wr) {
-			forte_channel_stop (&chip->rec);
-			rval = forte_channel_format (&chip->play, ival);
-		}
-
-		spin_unlock_irq (&chip->lock);
-	
-		return put_user (rval, p);
-
-	case SNDCTL_DSP_STEREO:	/* 0 - mono, 1 - stereo */
-		DPRINTK ("%s: STEREO\n", __FUNCTION__);
-
-		if (get_user (ival, p))
-			return -EFAULT;
-
-		spin_lock_irq (&chip->lock);
-
-		if (rd) {
-			forte_channel_stop (&chip->rec);
-			rval = forte_channel_stereo (&chip->rec, ival);
-		}
-
-		if (wr) {
-			forte_channel_stop (&chip->rec);
-			rval = forte_channel_stereo (&chip->play, ival);
-		}
-
-		spin_unlock_irq (&chip->lock);
-
-                return put_user (rval, p);
-
-	case SNDCTL_DSP_CHANNELS: /* 1 - mono, 2 - stereo */
-		DPRINTK ("%s: CHANNELS\n", __FUNCTION__);
-
-		if (get_user (ival, p))
-			return -EFAULT;
-
-		spin_lock_irq (&chip->lock);
-
-		if (rd) {
-			forte_channel_stop (&chip->rec);
-			rval = forte_channel_stereo (&chip->rec, ival-1) + 1;
-		}
-
-		if (wr) {
-			forte_channel_stop (&chip->play);
-			rval = forte_channel_stereo (&chip->play, ival-1) + 1;
-		}
-
-		spin_unlock_irq (&chip->lock);
-
-                return put_user (rval, p);
-
-	case SNDCTL_DSP_SPEED:
-		DPRINTK ("%s: SPEED\n", __FUNCTION__);
-
-		if (get_user (ival, p))
-                        return -EFAULT;
-
-		spin_lock_irq (&chip->lock);
-
-		if (rd) {
-			forte_channel_stop (&chip->rec);
-			rval = forte_channel_rate (&chip->rec, ival);
-		}
-
-		if (wr) {
-			forte_channel_stop (&chip->play);
-			rval = forte_channel_rate (&chip->play, ival);
-		}
-
-		spin_unlock_irq (&chip->lock);
-
-                return put_user(rval, p);
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		DPRINTK ("%s: GETBLKSIZE\n", __FUNCTION__);
-
-		spin_lock_irq (&chip->lock);
-
-		if (rd)
-			ival = chip->rec.frag_sz;
-
-		if (wr)
-			ival = chip->play.frag_sz;
-
-		spin_unlock_irq (&chip->lock);
-
-                return put_user (ival, p);
-
-	case SNDCTL_DSP_RESET:
-		DPRINTK ("%s: RESET\n", __FUNCTION__);
-
-		spin_lock_irq (&chip->lock);
-
-		if (rd)
-			forte_channel_reset (&chip->rec);
-
-		if (wr)
-			forte_channel_reset (&chip->play);
-
-		spin_unlock_irq (&chip->lock);
-
-                return 0;
-
-	case SNDCTL_DSP_SYNC:
-		DPRINTK ("%s: SYNC\n", __FUNCTION__);
-
-		if (wr)
-			ret = forte_channel_drain (&chip->play);
-
-		return 0;
-
-	case SNDCTL_DSP_POST:
-		DPRINTK ("%s: POST\n", __FUNCTION__);
-
-		if (wr) {
-			spin_lock_irq (&chip->lock);
-
-			if (chip->play.filled_frags)
-				forte_channel_start (&chip->play);
-
-			spin_unlock_irq (&chip->lock);
-		}
-
-                return 0;
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		DPRINTK ("%s: SETFRAGMENT\n", __FUNCTION__);
-
-		if (get_user (ival, p))
-			return -EFAULT;
-
-		spin_lock_irq (&chip->lock);
-
-		if (rd) {
-			forte_channel_buffer (&chip->rec, ival & 0xffff, 
-					      (ival >> 16) & 0xffff);
-			ival = (chip->rec.frag_num << 16) + chip->rec.frag_sz;
-		}
-
-		if (wr) {
-			forte_channel_buffer (&chip->play, ival & 0xffff, 
-					      (ival >> 16) & 0xffff);
-			ival = (chip->play.frag_num << 16) +chip->play.frag_sz;
-		}
-
-		spin_unlock_irq (&chip->lock);
-
-		return put_user (ival, p);
-                
-        case SNDCTL_DSP_GETISPACE:
-		DPRINTK ("%s: GETISPACE\n", __FUNCTION__);
-
-		if (!rd)
-			return -EINVAL;
-
-		spin_lock_irq (&chip->lock);
-
-		abi.fragstotal = chip->rec.frag_num;
-		abi.fragsize = chip->rec.frag_sz;
-			
-		if (chip->rec.mapped) {
-			abi.fragments = chip->rec.frag_num - 2;
-			abi.bytes = abi.fragments * abi.fragsize;
-		}
-		else {
-			abi.fragments = chip->rec.filled_frags;
-			abi.bytes = abi.fragments * abi.fragsize;
-		}
-
-		spin_unlock_irq (&chip->lock);
-
-		return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETIPTR:
-		DPRINTK ("%s: GETIPTR\n", __FUNCTION__);
-
-		if (!rd)
-			return -EINVAL;
-
-		spin_lock_irq (&chip->lock);
-
-		if (chip->rec.active) 
-			cinfo.ptr = chip->rec.hwptr;
-		else
-			cinfo.ptr = 0;
-
-		cinfo.bytes = chip->rec.bytes;
-		cinfo.blocks = chip->rec.nr_irqs;
-		chip->rec.nr_irqs = 0;
-
-		spin_unlock_irq (&chip->lock);
-
-		return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETOSPACE:
-		if (!wr)
-			return -EINVAL;
-		
-		spin_lock_irq (&chip->lock);
-
-		abi.fragstotal = chip->play.frag_num;
-		abi.fragsize = chip->play.frag_sz;
-
-		if (chip->play.mapped) {
-			abi.fragments = chip->play.frag_num - 2;
-			abi.bytes = chip->play.buf_sz;
-		}
-		else {
-			abi.fragments = chip->play.frag_num - 
-				chip->play.filled_frags;
-
-			if (chip->play.residue)
-				abi.fragments--;
-
-			abi.bytes = abi.fragments * abi.fragsize +
-				chip->play.residue;
-		}
-
-		spin_unlock_irq (&chip->lock);
-		
-		return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETOPTR:
-		if (!wr)
-			return -EINVAL;
-
-		spin_lock_irq (&chip->lock);
-
-		if (chip->play.active) 
-			cinfo.ptr = chip->play.hwptr;
-		else
-			cinfo.ptr = 0;
-
-		cinfo.bytes = chip->play.bytes;
-		cinfo.blocks = chip->play.nr_irqs;
-		chip->play.nr_irqs = 0;
-
-		spin_unlock_irq (&chip->lock);
-
-		return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETODELAY:
-		if (!wr)
-			return -EINVAL;
-
-		spin_lock_irq (&chip->lock);
-
-		if (!chip->play.active) {
-			ival = 0;
-		}
-		else if (chip->play.mapped) {
-			count = inw (chip->play.iobase + FORTE_PLY_COUNT) + 1;
-			ival = chip->play.frag_sz - count;
-		}
-		else {
-			ival = chip->play.filled_frags * chip->play.frag_sz;
-
-			if (chip->play.residue)
-				ival += chip->play.frag_sz - chip->play.residue;
-		}
-
-		spin_unlock_irq (&chip->lock);
-
-		return put_user (ival, p);
-
-	case SNDCTL_DSP_SETDUPLEX:
-		DPRINTK ("%s: SETDUPLEX\n", __FUNCTION__);
-
-		return -EINVAL;
-
-	case SNDCTL_DSP_GETTRIGGER:
-		DPRINTK ("%s: GETTRIGGER\n", __FUNCTION__);
-		
-		return put_user (chip->trigger, p);
-		
-	case SNDCTL_DSP_SETTRIGGER:
-
-		if (get_user (ival, p))
-			return -EFAULT;
-
-		DPRINTK ("%s: SETTRIGGER %d\n", __FUNCTION__, ival);
-
-		if (wr) {
-			spin_lock_irq (&chip->lock);
-
-			if (ival & PCM_ENABLE_OUTPUT)
-				forte_channel_start (&chip->play);
-			else {		
-				chip->trigger = 1;
-				forte_channel_prep (&chip->play);
-				forte_channel_stop (&chip->play);
-			}
-
-			spin_unlock_irq (&chip->lock);
-		}
-		else if (rd) {
-			spin_lock_irq (&chip->lock);
-
-			if (ival & PCM_ENABLE_INPUT)
-				forte_channel_start (&chip->rec);
-			else {		
-				chip->trigger = 1;
-				forte_channel_prep (&chip->rec);
-				forte_channel_stop (&chip->rec);
-			}
-
-			spin_unlock_irq (&chip->lock);
-		}
-
-		return 0;
-		
-	case SOUND_PCM_READ_RATE:
-		DPRINTK ("%s: PCM_READ_RATE\n", __FUNCTION__);		
-		return put_user (chip->play.rate, p);
-
-	case SOUND_PCM_READ_CHANNELS:
-		DPRINTK ("%s: PCM_READ_CHANNELS\n", __FUNCTION__);
-		return put_user (chip->play.stereo, p);
-
-	case SOUND_PCM_READ_BITS:
-		DPRINTK ("%s: PCM_READ_BITS\n", __FUNCTION__);		
-		return put_user (chip->play.format, p);
-
-	case SNDCTL_DSP_NONBLOCK:
-		DPRINTK ("%s: DSP_NONBLOCK\n", __FUNCTION__);		
-                file->f_flags |= O_NONBLOCK;
-		return 0;
-
-	default:
-		DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, argp);
-		break;
-	}
-
-	return -EINVAL;
-}
-
-
-/**
- * forte_dsp_open:
- */
-
-static int 
-forte_dsp_open (struct inode *inode, struct file *file)
-{
-	struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */
-
-	if (file->f_flags & O_NONBLOCK) {
-		if (!mutex_trylock(&chip->open_mutex)) {
-			DPRINTK ("%s: returning -EAGAIN\n", __FUNCTION__);
-			return -EAGAIN;
-		}
-	}
-	else {
-		if (mutex_lock_interruptible(&chip->open_mutex)) {
-			DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__);
-			return -ERESTARTSYS;
-		}
-	}
-
-	file->private_data = forte;
-
-	DPRINTK ("%s: dsp opened by %d\n", __FUNCTION__, current->pid);
-
-	if (file->f_mode & FMODE_WRITE)
-		forte_channel_init (forte, &forte->play);
-
-	if (file->f_mode & FMODE_READ)
-		forte_channel_init (forte, &forte->rec);
-
-	return nonseekable_open(inode, file);
-}
-
-
-/**
- * forte_dsp_release:
- */
-
-static int 
-forte_dsp_release (struct inode *inode, struct file *file)
-{
-	struct forte_chip *chip = file->private_data;
-	int ret = 0;
-
-	DPRINTK ("%s: chip @ %p\n", __FUNCTION__, chip);
-
-	if (file->f_mode & FMODE_WRITE) {
-		forte_channel_drain (&chip->play);
-
-		spin_lock_irq (&chip->lock);
-
- 		forte_channel_free (chip, &chip->play);
-
-		spin_unlock_irq (&chip->lock);
-        }
-
-	if (file->f_mode & FMODE_READ) {
-		while (chip->rec.filled_frags > 0)
-			interruptible_sleep_on (&chip->rec.wait);
-
-		spin_lock_irq (&chip->lock);
-
-		forte_channel_stop (&chip->rec);
-		forte_channel_free (chip, &chip->rec);
-
-		spin_unlock_irq (&chip->lock);
-	}
-
-	mutex_unlock(&chip->open_mutex);
-
-	return ret;
-}
-
-
-/**
- * forte_dsp_poll:
- *
- */
-
-static unsigned int 
-forte_dsp_poll (struct file *file, struct poll_table_struct *wait)
-{
-	struct forte_chip *chip;
-	struct forte_channel *channel;
-	unsigned int mask = 0;
-
-	chip = file->private_data;
-
-	if (file->f_mode & FMODE_WRITE) {
-		channel = &chip->play;
-
-		if (channel->active)
-			poll_wait (file, &channel->wait, wait);
-
-		spin_lock_irq (&chip->lock);
-
-		if (channel->frag_num - channel->filled_frags > 0)
-			mask |= POLLOUT | POLLWRNORM;
-
-		spin_unlock_irq (&chip->lock);
-	}
-
-	if (file->f_mode & FMODE_READ) {
-		channel = &chip->rec;
-
-		if (channel->active)
-			poll_wait (file, &channel->wait, wait);
-
-		spin_lock_irq (&chip->lock);
-
-		if (channel->filled_frags > 0)
-			mask |= POLLIN | POLLRDNORM;
-
-		spin_unlock_irq (&chip->lock);
-	}
-
-	return mask;
-}
-
-
-/**
- * forte_dsp_mmap:
- */
-
-static int
-forte_dsp_mmap (struct file *file, struct vm_area_struct *vma)
-{
-	struct forte_chip *chip;
-	struct forte_channel *channel;
-	unsigned long size;
-	int ret;
-
-	chip = file->private_data;
-
-	DPRINTK ("%s: start %lXh, size %ld, pgoff %ld\n", __FUNCTION__,
-                 vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_pgoff);
-
-	spin_lock_irq (&chip->lock);
-
-	if (vma->vm_flags & VM_WRITE && chip->play.active) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-        if (vma->vm_flags & VM_READ && chip->rec.active) {
-		ret = -EBUSY;
-		goto out;
-        }
-
-	if (file->f_mode & FMODE_WRITE)
-		channel = &chip->play;
-	else if (file->f_mode & FMODE_READ)
-		channel = &chip->rec;
-	else {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	forte_channel_prep (channel);
-	channel->mapped = 1;
-
-        if (vma->vm_pgoff != 0) {
-		ret = -EINVAL;
-                goto out;
-	}
-
-        size = vma->vm_end - vma->vm_start;
-
-        if (size > channel->buf_pages * PAGE_SIZE) {
-		DPRINTK ("%s: size (%ld) > buf_sz (%d) \n", __FUNCTION__,
-			 size, channel->buf_sz);
-		ret = -EINVAL;
-                goto out;
-	}
-
-        if (remap_pfn_range(vma, vma->vm_start,
-			      virt_to_phys(channel->buf) >> PAGE_SHIFT,
-			      size, vma->vm_page_prot)) {
-		DPRINTK ("%s: remap el a no worko\n", __FUNCTION__);
-		ret = -EAGAIN;
-                goto out;
-	}
-
-        ret = 0;
-
- out:
-	spin_unlock_irq (&chip->lock);
-        return ret;
-}
-
-
-/**
- * forte_dsp_write:
- */
-
-static ssize_t 
-forte_dsp_write (struct file *file, const char __user *buffer, size_t bytes, 
-		 loff_t *ppos)
-{
-	struct forte_chip *chip;
-	struct forte_channel *channel;
-	unsigned int i = bytes, sz = 0;
-	unsigned long flags;
-
-	if (!access_ok (VERIFY_READ, buffer, bytes))
-		return -EFAULT;
-
-	chip = (struct forte_chip *) file->private_data;
-
-	if (!chip)
-		BUG();
-
-	channel = &chip->play;
-
-	if (!channel)
-		BUG();
-
-	spin_lock_irqsave (&chip->lock, flags);
-
-	/* Set up buffers with the right fragment size */
-	forte_channel_prep (channel);
-
-	while (i) {
-		/* All fragment buffers in use -> wait */
-		if (channel->frag_num - channel->filled_frags == 0) {
-			DECLARE_WAITQUEUE (wait, current);
-
-			/* For trigger or non-blocking operation, get out */
-			if (chip->trigger || file->f_flags & O_NONBLOCK) {
-				spin_unlock_irqrestore (&chip->lock, flags);
-				return -EAGAIN;
-			}
-
-			/* Otherwise wait for buffers */
-			add_wait_queue (&channel->wait, &wait);
-
-			for (;;) {
-				spin_unlock_irqrestore (&chip->lock, flags);
-
-				set_current_state (TASK_INTERRUPTIBLE);
-				schedule();
-
-				spin_lock_irqsave (&chip->lock, flags);
-
-				if (channel->frag_num - channel->filled_frags)
-					break;
-			}
-
-			remove_wait_queue (&channel->wait, &wait);
-			set_current_state (TASK_RUNNING);
-
-			if (signal_pending (current)) {
-				spin_unlock_irqrestore (&chip->lock, flags);
-				return -ERESTARTSYS;
-			}
-		}
-
-		if (channel->residue)
-			sz = channel->residue;
-		else if (i > channel->frag_sz)
-			sz = channel->frag_sz;
-		else
-			sz = i;
-
-		spin_unlock_irqrestore (&chip->lock, flags);
-
-		if (copy_from_user ((void *) channel->buf + channel->swptr, buffer, sz))
-			return -EFAULT;
-
-		spin_lock_irqsave (&chip->lock, flags);
-
-		/* Advance software pointer */
-		buffer += sz;
-		channel->swptr += sz;
-		channel->swptr %= channel->buf_sz;
-		i -= sz;
-
-		/* Only bump filled_frags if a full fragment has been written */
-		if (channel->swptr % channel->frag_sz == 0) {
-			channel->filled_frags++;
-			channel->residue = 0;
-		}
-		else
-			channel->residue = channel->frag_sz - sz;
-
-		/* If playback isn't active, start it */
-		if (channel->active == 0 && chip->trigger == 0)
-			forte_channel_start (channel);
-	}
-
-	spin_unlock_irqrestore (&chip->lock, flags);
-
-	return bytes - i;
-}
-
-
-/**
- * forte_dsp_read:
- */
-
-static ssize_t 
-forte_dsp_read (struct file *file, char __user *buffer, size_t bytes, 
-		loff_t *ppos)
-{
-	struct forte_chip *chip;
-	struct forte_channel *channel;
-	unsigned int i = bytes, sz;
-	unsigned long flags;
-
-	if (!access_ok (VERIFY_WRITE, buffer, bytes))
-		return -EFAULT;
-
-	chip = (struct forte_chip *) file->private_data;
-
-	if (!chip)
-		BUG();
-
-	channel = &chip->rec;
-
-	if (!channel)
-		BUG();
-
-	spin_lock_irqsave (&chip->lock, flags);
-
-	/* Set up buffers with the right fragment size */
-	forte_channel_prep (channel);
-
-	/* Start recording */
-	if (!chip->trigger)
-		forte_channel_start (channel);
-
-	while (i) {
-		/* No fragment buffers in use -> wait */
-		if (channel->filled_frags == 0) {
-			DECLARE_WAITQUEUE (wait, current);
-
-			/* For trigger mode operation, get out */
-			if (chip->trigger) {
-				spin_unlock_irqrestore (&chip->lock, flags);
-				return -EAGAIN;
-			}
-
-			add_wait_queue (&channel->wait, &wait);
-
-			for (;;) {
-				if (channel->active == 0)
-					break;
-
-				if (channel->filled_frags)
-					break;
-						
-				spin_unlock_irqrestore (&chip->lock, flags);
-
-				set_current_state (TASK_INTERRUPTIBLE);
-				schedule();
-
-				spin_lock_irqsave (&chip->lock, flags);
-			}
-
-			set_current_state (TASK_RUNNING);
-			remove_wait_queue (&channel->wait, &wait);
-		}
-
-		if (i > channel->frag_sz)
-			sz = channel->frag_sz;
-		else
-			sz = i;
-
-		spin_unlock_irqrestore (&chip->lock, flags);
-
-		if (copy_to_user (buffer, (void *)channel->buf+channel->swptr, sz)) {
-			DPRINTK ("%s: copy_to_user failed\n", __FUNCTION__);
-			return -EFAULT;
-		}
-
-		spin_lock_irqsave (&chip->lock, flags);
-
-		/* Advance software pointer */
-		buffer += sz;
-		if (channel->filled_frags > 0)
-			channel->filled_frags--;
-		channel->swptr += channel->frag_sz;
-		channel->swptr %= channel->buf_sz;
-		i -= sz;
-	}
-
-	spin_unlock_irqrestore (&chip->lock, flags);
-
-	return bytes - i;
-}
-
-
-static struct file_operations forte_dsp_fops = {
-	.owner			= THIS_MODULE,
-	.llseek     		= &no_llseek,
-	.read       		= &forte_dsp_read,
-	.write      		= &forte_dsp_write,
-	.poll       		= &forte_dsp_poll,
-	.ioctl      		= &forte_dsp_ioctl,
-	.open       		= &forte_dsp_open,
-	.release    		= &forte_dsp_release,
-	.mmap			= &forte_dsp_mmap,
-};
-
-
-/* Common ------------------------------------------------------------------ */
-
-
-/**
- * forte_interrupt:
- */
-
-static irqreturn_t
-forte_interrupt (int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct forte_chip *chip = dev_id;
-	struct forte_channel *channel = NULL;
-	u16 status, count; 
-
-	status = inw (chip->iobase + FORTE_IRQ_STATUS);
-
-	/* If this is not for us, get outta here ASAP */
-	if ((status & (FORTE_IRQ_PLAYBACK | FORTE_IRQ_CAPTURE)) == 0)
-		return IRQ_NONE;
-	
-	if (status & FORTE_IRQ_PLAYBACK) {
-		channel = &chip->play;
-
-		spin_lock (&chip->lock);
-
-		if (channel->frag_sz == 0)
-			goto pack;
-
-		/* Declare a fragment done */
-		if (channel->filled_frags > 0)
-			channel->filled_frags--;
-		channel->bytes += channel->frag_sz;
-		channel->nr_irqs++;
-		
-		/* Flip-flop between buffer I and II */
-		channel->next_buf ^= 1;
-
-		/* Advance hardware pointer by fragment size and wrap around */
-		channel->hwptr += channel->frag_sz;
-		channel->hwptr %= channel->buf_sz;
-
-		/* Buffer I or buffer II BAR */
-                outl (channel->buf_handle + channel->hwptr, 
-		      channel->next_buf == 0 ?
-		      channel->iobase + FORTE_PLY_BUF1 :
-		      channel->iobase + FORTE_PLY_BUF2);
-
-		/* If the currently playing fragment is last, schedule pause */
-		if (channel->filled_frags == 1) 
-			forte_channel_pause (channel);
-
-	pack:
-		/* Acknowledge interrupt */
-                outw (FORTE_IRQ_PLAYBACK, chip->iobase + FORTE_IRQ_STATUS);
-
-		if (waitqueue_active (&channel->wait)) 
-			wake_up_all (&channel->wait);
-
-		spin_unlock (&chip->lock);
-	}
-
-	if (status & FORTE_IRQ_CAPTURE) {
-		channel = &chip->rec;
-		spin_lock (&chip->lock);
-
-		/* One fragment filled */
-		channel->filled_frags++;
-
-		/* Get # of completed bytes */
-		count = inw (channel->iobase + FORTE_PLY_COUNT) + 1;
-
-		if (count == 0) {
-			DPRINTK ("%s: last, filled_frags = %d\n", __FUNCTION__,
-				 channel->filled_frags);
-			channel->filled_frags = 0;
-			goto rack;
-		}
-
-		/* Buffer I or buffer II BAR */
-                outl (channel->buf_handle + channel->hwptr, 
-		      channel->next_buf == 0 ?
-		      channel->iobase + FORTE_PLY_BUF1 :
-		      channel->iobase + FORTE_PLY_BUF2);
-
-		/* Flip-flop between buffer I and II */
-		channel->next_buf ^= 1;
-
-		/* Advance hardware pointer by fragment size and wrap around */
-		channel->hwptr += channel->frag_sz;
-		channel->hwptr %= channel->buf_sz;
-
-		/* Out of buffers */
-		if (channel->filled_frags == channel->frag_num - 1)
-			forte_channel_stop (channel);
-	rack:
-		/* Acknowledge interrupt */
-                outw (FORTE_IRQ_CAPTURE, chip->iobase + FORTE_IRQ_STATUS);
-
-		spin_unlock (&chip->lock);
-
-		if (waitqueue_active (&channel->wait))
-			wake_up_all (&channel->wait);		
-	}
-
-	return IRQ_HANDLED;
-}
-
-
-/**
- * forte_proc_read:
- */
-
-static int
-forte_proc_read (char *page, char **start, off_t off, int count, 
-		 int *eof, void *data)
-{
-	int i = 0, p_rate, p_chan, r_rate;
-	unsigned short p_reg, r_reg;
-
-	i += sprintf (page, "ForteMedia FM801 OSS Lite driver\n%s\n \n", 
-		      DRIVER_VERSION);
-
-	if (!forte->iobase)
-		return i;
-
-	p_rate = p_chan = -1;
-	p_reg  = inw (forte->iobase + FORTE_PLY_CTRL);
-	p_rate = (p_reg >> 8) & 15;
-	p_chan = (p_reg >> 12) & 3;
-
- 	if (p_rate >= 0 || p_rate <= 10)
-		p_rate = rates[p_rate];
-
-	if (p_chan >= 0 || p_chan <= 2)
-		p_chan = channels[p_chan];
-
-	r_rate = -1;
-	r_reg  = inw (forte->iobase + FORTE_CAP_CTRL);
-	r_rate = (r_reg >> 8) & 15;
-
- 	if (r_rate >= 0 || r_rate <= 10)
-		r_rate = rates[r_rate]; 
-
-	i += sprintf (page + i,
-		      "             Playback  Capture\n"
-		      "FIFO empty : %-3s       %-3s\n"
-		      "Buf1 Last  : %-3s       %-3s\n"
-		      "Buf2 Last  : %-3s       %-3s\n"
-		      "Started    : %-3s       %-3s\n"
-		      "Paused     : %-3s       %-3s\n"
-		      "Immed Stop : %-3s       %-3s\n"
-		      "Rate       : %-5d     %-5d\n"
-		      "Channels   : %-5d     -\n"
-		      "16-bit     : %-3s       %-3s\n"
-		      "Stereo     : %-3s       %-3s\n"
-		      " \n"
-		      "Buffer Sz  : %-6d    %-6d\n"
-		      "Frag Sz    : %-6d    %-6d\n"
-		      "Frag Num   : %-6d    %-6d\n"
-		      "Frag msecs : %-6d    %-6d\n"
-		      "Used Frags : %-6d    %-6d\n"
-		      "Mapped     : %-3s       %-3s\n",
-		      p_reg & 1<<0  ? "yes" : "no",
-		      r_reg & 1<<0  ? "yes" : "no",
-		      p_reg & 1<<1  ? "yes" : "no",
-		      r_reg & 1<<1  ? "yes" : "no",
-		      p_reg & 1<<2  ? "yes" : "no",
-		      r_reg & 1<<2  ? "yes" : "no",
-		      p_reg & 1<<5  ? "yes" : "no",
-		      r_reg & 1<<5  ? "yes" : "no",
-		      p_reg & 1<<6  ? "yes" : "no",
-		      r_reg & 1<<6  ? "yes" : "no",
-		      p_reg & 1<<7  ? "yes" : "no",
-		      r_reg & 1<<7  ? "yes" : "no",
-		      p_rate, r_rate,
-		      p_chan,
-		      p_reg & 1<<14 ? "yes" : "no",
-		      r_reg & 1<<14 ? "yes" : "no",
-		      p_reg & 1<<15 ? "yes" : "no",
-		      r_reg & 1<<15 ? "yes" : "no",
-		      forte->play.buf_sz,       forte->rec.buf_sz,
-		      forte->play.frag_sz,      forte->rec.frag_sz,
-		      forte->play.frag_num,     forte->rec.frag_num,
-		      forte->play.frag_msecs,   forte->rec.frag_msecs,
-		      forte->play.filled_frags, forte->rec.filled_frags,
-		      forte->play.mapped ? "yes" : "no",
-		      forte->rec.mapped ? "yes" : "no"
-		);
-
-	return i;
-}
-
-
-/**
- * forte_proc_init:
- *
- * Creates driver info entries in /proc
- */
-
-static int __init 
-forte_proc_init (void)
-{
-	if (!proc_mkdir ("driver/forte", NULL))
-		return -EIO;
-
-	if (!create_proc_read_entry ("driver/forte/chip", 0, NULL, forte_proc_read, forte)) {
-		remove_proc_entry ("driver/forte", NULL);
-		return -EIO;
-	}
-
-	if (!create_proc_read_entry("driver/forte/ac97", 0, NULL, ac97_read_proc, forte->ac97)) {
-		remove_proc_entry ("driver/forte/chip", NULL);
-		remove_proc_entry ("driver/forte", NULL);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-
-/**
- * forte_proc_remove:
- *
- * Removes driver info entries in /proc
- */
-
-static void
-forte_proc_remove (void)
-{
-	remove_proc_entry ("driver/forte/ac97", NULL);
-	remove_proc_entry ("driver/forte/chip", NULL);
-	remove_proc_entry ("driver/forte", NULL);	
-}
-
-
-/**
- * forte_chip_init:
- * @chip:	Chip instance to initialize
- *
- * Description:
- * 		Resets chip, configures codec and registers the driver with
- * 		the sound subsystem.
- *
- * 		Press and hold Start for 8 secs, then switch on Run
- * 		and hold for 4 seconds.  Let go of Start.  Numbers
- * 		assume a properly oiled TWG.
- */
-
-static int __devinit
-forte_chip_init (struct forte_chip *chip)
-{
-	u8 revision;
-	u16 cmdw;
-	struct ac97_codec *codec;
-
-	pci_read_config_byte (chip->pci_dev, PCI_REVISION_ID, &revision);
-
-	if (revision >= 0xB1) {
-		chip->multichannel = 1;
-		printk (KERN_INFO PFX "Multi-channel device detected.\n");
-	}
-
-	/* Reset chip */
-	outw (FORTE_CC_CODEC_RESET | FORTE_CC_AC97_RESET, 
-	      chip->iobase + FORTE_CODEC_CTRL);
-	udelay(100);
-	outw (0, chip->iobase + FORTE_CODEC_CTRL);
-
-	/* Request read from AC97 */
-	outw (FORTE_AC97_READ | (0 << FORTE_AC97_ADDR_SHIFT), 
-	      chip->iobase + FORTE_AC97_CMD);
-	mdelay(750);
-
-	if ((inw (chip->iobase + FORTE_AC97_CMD) & (3<<8)) != (1<<8)) {
-		printk (KERN_INFO PFX "AC97 codec not responding");
-		return -EIO;
-	}
-
-	/* Init volume */
-	outw (0x0808, chip->iobase + FORTE_PCM_VOL);
-	outw (0x9f1f, chip->iobase + FORTE_FM_VOL);
-	outw (0x8808, chip->iobase + FORTE_I2S_VOL);
-
-	/* I2S control - I2S mode */
-	outw (0x0003, chip->iobase + FORTE_I2S_MODE);
-
-	/* Interrupt setup - unmask PLAYBACK & CAPTURE */
-	cmdw = inw (chip->iobase + FORTE_IRQ_MASK);
-	cmdw &= ~0x0003;
-	outw (cmdw, chip->iobase + FORTE_IRQ_MASK);
-
-	/* Interrupt clear */
-	outw (FORTE_IRQ_PLAYBACK|FORTE_IRQ_CAPTURE, 
-	      chip->iobase + FORTE_IRQ_STATUS);
-
-	/* Set up the AC97 codec */
-	if ((codec = ac97_alloc_codec()) == NULL)
-		return -ENOMEM;
-	codec->private_data = chip;
-	codec->codec_read = forte_ac97_read;
-	codec->codec_write = forte_ac97_write;
-	codec->id = 0;
-
-	if (ac97_probe_codec (codec) == 0) {
-		printk (KERN_ERR PFX "codec probe failed\n");
-		ac97_release_codec(codec);
-		return -1;
-	}
-
-	/* Register mixer */
-	if ((codec->dev_mixer = 
-	     register_sound_mixer (&forte_mixer_fops, -1)) < 0) {
-		printk (KERN_ERR PFX "couldn't register mixer!\n");
-		ac97_release_codec(codec);
-		return -1;
-	}
-
-	chip->ac97 = codec;
-
-	/* Register DSP */
-	if ((chip->dsp = register_sound_dsp (&forte_dsp_fops, -1) ) < 0) {
-		printk (KERN_ERR PFX "couldn't register dsp!\n");
-		return -1;
-	}
-
-	/* Register with /proc */
-	if (forte_proc_init()) {
-		printk (KERN_ERR PFX "couldn't add entries to /proc!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-
-/**
- * forte_probe:
- * @pci_dev:	PCI struct for probed device
- * @pci_id:	
- *
- * Description:
- *		Allocates chip instance, I/O region, and IRQ
- */
-static int __init 
-forte_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
-{
-	struct forte_chip *chip;
-	int ret = 0;
-
-	/* FIXME: Support more than one chip */
-	if (found++)
-		return -EIO;
-
-	/* Ignition */
-	if (pci_enable_device (pci_dev))
-		return -EIO;
-
-	pci_set_master (pci_dev);
-
-	/* Allocate chip instance and configure */
-	forte = (struct forte_chip *) 
-		kmalloc (sizeof (struct forte_chip), GFP_KERNEL);
-	chip = forte;
-
-	if (chip == NULL) {
-		printk (KERN_WARNING PFX "Out of memory");
-		return -ENOMEM;
-	}
-
-	memset (chip, 0, sizeof (struct forte_chip));
-	chip->pci_dev = pci_dev;
-
-	mutex_init(&chip->open_mutex);
-	spin_lock_init (&chip->lock);
-	spin_lock_init (&chip->ac97_lock);
-
-	if (! request_region (pci_resource_start (pci_dev, 0),
-			      pci_resource_len (pci_dev, 0), DRIVER_NAME)) {
-		printk (KERN_WARNING PFX "Unable to reserve I/O space");
-		ret = -ENOMEM;
-		goto error;
-	}
-
-	chip->iobase = pci_resource_start (pci_dev, 0);
-	chip->irq = pci_dev->irq;
-
-	if (request_irq (chip->irq, forte_interrupt, IRQF_SHARED, DRIVER_NAME,
-			 chip)) {
-		printk (KERN_WARNING PFX "Unable to reserve IRQ");
-		ret = -EIO;
-		goto error;
-	}		
-	
-	pci_set_drvdata (pci_dev, chip);
-
-	printk (KERN_INFO PFX "FM801 chip found at 0x%04lX-0x%16llX IRQ %u\n",
-		chip->iobase, (unsigned long long)pci_resource_end (pci_dev, 0),
-		chip->irq);
-
-	/* Power it up */
-	if ((ret = forte_chip_init (chip)) == 0)
-		return 0;
-
- error:
-	if (chip->irq)
-		free_irq (chip->irq, chip);
-
-	if (chip->iobase) 
-		release_region (pci_resource_start (pci_dev, 0),
-				pci_resource_len (pci_dev, 0));
-		
-	kfree (chip);
-
-	return ret;
-}
-
-
-/**
- * forte_remove:
- * @pci_dev:	PCI device to unclaim
- *
- */
-
-static void 
-forte_remove (struct pci_dev *pci_dev)
-{
-	struct forte_chip *chip = pci_get_drvdata (pci_dev);
-
-	if (chip == NULL)
-		return;
-
-	/* Turn volume down to avoid popping */
-	outw (0x1f1f, chip->iobase + FORTE_PCM_VOL);
-	outw (0x1f1f, chip->iobase + FORTE_FM_VOL);
-	outw (0x1f1f, chip->iobase + FORTE_I2S_VOL);
-
-	forte_proc_remove();
-	free_irq (chip->irq, chip);
-	release_region (chip->iobase, pci_resource_len (pci_dev, 0));
-
-	unregister_sound_dsp (chip->dsp);
-	unregister_sound_mixer (chip->ac97->dev_mixer);
-	ac97_release_codec(chip->ac97);
-	kfree (chip);
-
-	printk (KERN_INFO PFX "driver released\n");
-}
-
-
-static struct pci_device_id forte_pci_ids[] = {
-	{ 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-	{ 0, }
-};
-
-
-static struct pci_driver forte_pci_driver = {
-	.name			= DRIVER_NAME,
-	.id_table		= forte_pci_ids,
-	.probe	 		= forte_probe,
-	.remove			= forte_remove,
-
-};
-
-
-/**
- * forte_init_module:
- *
- */
-
-static int __init
-forte_init_module (void)
-{
-	printk (KERN_INFO PFX DRIVER_VERSION "\n");
-
-	return pci_register_driver (&forte_pci_driver);
-}
-
-
-/**
- * forte_cleanup_module:
- *
- */
-
-static void __exit 
-forte_cleanup_module (void)
-{
-	pci_unregister_driver (&forte_pci_driver);
-}
-
-
-module_init(forte_init_module);
-module_exit(forte_cleanup_module);
-
-MODULE_AUTHOR("Martin K. Petersen <mkp@mkp.net>");
-MODULE_DESCRIPTION("ForteMedia FM801 OSS Driver");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE (pci, forte_pci_ids);
diff --git a/sound/oss/gus.h b/sound/oss/gus.h
deleted file mode 100644
index 3d5271b..0000000
--- a/sound/oss/gus.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#include "ad1848.h"
-
-/*	From gus_card.c */
-int gus_set_midi_irq(int num);
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs * dummy);
-
-/*	From gus_wave.c */
-int gus_wave_detect(int baseaddr);
-void gus_wave_init(struct address_info *hw_config);
-void gus_wave_unload (struct address_info *hw_config);
-void gus_voice_irq(void);
-void gus_write8(int reg, unsigned int data);
-void guswave_dma_irq(void);
-void gus_delay(void);
-int gus_default_mixer_ioctl (int dev, unsigned int cmd, void __user *arg);
-void gus_timer_command (unsigned int addr, unsigned int val);
-
-/*	From gus_midi.c */
-void gus_midi_init(struct address_info *hw_config);
-void gus_midi_interrupt(int dummy);
-
-/*	From ics2101.c */
-int ics2101_mixer_init(void);
diff --git a/sound/oss/gus_card.c b/sound/oss/gus_card.c
deleted file mode 100644
index dbb2977..0000000
--- a/sound/oss/gus_card.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * sound/gus_card.c
- *
- * Detection routine for the Gravis Ultrasound.
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- *
- * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
- *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
- * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups.
- *
- * Status:
- *              Tested... 
- */
-      
- 
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_hw.h"
-
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy);
-
-int             gus_base = 0, gus_irq = 0, gus_dma = 0;
-int             gus_no_wave_dma = 0; 
-extern int      gus_wave_volume;
-extern int      gus_pcm_volume;
-extern int      have_gus_max;
-int             gus_pnp_flag = 0;
-#ifdef CONFIG_SOUND_GUS16
-static int      db16;	/* Has a Gus16 AD1848 on it */
-#endif
-
-static void __init attach_gus(struct address_info *hw_config)
-{
-	gus_wave_init(hw_config);
-
-	if (sound_alloc_dma(hw_config->dma, "GUS"))
-		printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma);
-	if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
-		if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))
-			printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);
-	gus_midi_init(hw_config);
-	if(request_irq(hw_config->irq, gusintr, 0,  "Gravis Ultrasound", hw_config)<0)
-		printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
-
-	return;
-}
-
-static int __init probe_gus(struct address_info *hw_config)
-{
-	int             irq;
-	int             io_addr;
-
-	if (hw_config->card_subtype == 1)
-		gus_pnp_flag = 1;
-
-	irq = hw_config->irq;
-
-	if (hw_config->card_subtype == 0)	/* GUS/MAX/ACE */
-		if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
-		    irq != 11 && irq != 12 && irq != 15)
-		  {
-			  printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);
-			  return 0;
-		  }
-	if (gus_wave_detect(hw_config->io_base))
-		return 1;
-
-#ifndef EXCLUDE_GUS_IODETECT
-
-	/*
-	 * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
-	 */
-
-	for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10) {
-		if (io_addr == hw_config->io_base)	/* Already tested */
-			continue;
-		if (gus_wave_detect(io_addr)) {
-			hw_config->io_base = io_addr;
-			return 1;
-		}
-	}
-#endif
-
-	printk("NO GUS card found !\n");
-	return 0;
-}
-
-static void __exit unload_gus(struct address_info *hw_config)
-{
-	DDB(printk("unload_gus(%x)\n", hw_config->io_base));
-
-	gus_wave_unload(hw_config);
-
-	release_region(hw_config->io_base, 16);
-	release_region(hw_config->io_base + 0x100, 12);		/* 0x10c-> is MAX */
-	free_irq(hw_config->irq, hw_config);
-
-	sound_free_dma(hw_config->dma);
-
-	if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
-		sound_free_dma(hw_config->dma2);
-}
-
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-	unsigned char src;
-	extern int gus_timer_enabled;
-	int handled = 0;
-
-#ifdef CONFIG_SOUND_GUSMAX
-	if (have_gus_max) {
-		struct address_info *hw_config = dev_id;
-		adintr(irq, (void *)hw_config->slots[1], NULL);
-	}
-#endif
-#ifdef CONFIG_SOUND_GUS16
-	if (db16) {
-		struct address_info *hw_config = dev_id;
-		adintr(irq, (void *)hw_config->slots[3], NULL);
-	}
-#endif
-
-	while (1)
-	{
-		if (!(src = inb(u_IrqStatus)))
-			break;
-		handled = 1;
-		if (src & DMA_TC_IRQ)
-		{
-			guswave_dma_irq();
-		}
-		if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
-		{
-			gus_midi_interrupt(0);
-		}
-		if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
-		{
-			if (gus_timer_enabled)
-				sound_timer_interrupt();
-			gus_write8(0x45, 0);	/* Ack IRQ */
-			gus_timer_command(4, 0x80);		/* Reset IRQ flags */
-		}
-		if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
-			gus_voice_irq();
-	}
-	return IRQ_RETVAL(handled);
-}
-
-/*
- *	Some extra code for the 16 bit sampling option
- */
-
-#ifdef CONFIG_SOUND_GUS16
-
-static int __init init_gus_db16(struct address_info *hw_config)
-{
-	struct resource *ports;
-
-	ports = request_region(hw_config->io_base, 4, "ad1848");
-	if (!ports)
-		return 0;
-
-	if (!ad1848_detect(ports, NULL, hw_config->osp)) {
-		release_region(hw_config->io_base, 4);
-		return 0;
-	}
-
-	gus_pcm_volume = 100;
-	gus_wave_volume = 90;
-
-	hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", ports,
-					  hw_config->irq,
-					  hw_config->dma,
-					  hw_config->dma, 0,
-					  hw_config->osp,
-					  THIS_MODULE);
-	return 1;
-}
-
-static void __exit unload_gus_db16(struct address_info *hw_config)
-{
-
-	ad1848_unload(hw_config->io_base,
-		      hw_config->irq,
-		      hw_config->dma,
-		      hw_config->dma, 0);
-	sound_unload_audiodev(hw_config->slots[3]);
-}
-#endif
-
-#ifdef CONFIG_SOUND_GUS16
-static int gus16;
-#endif
-#ifdef CONFIG_SOUND_GUSMAX
-static int no_wave_dma;   /* Set if no dma is to be used for the
-                                   wave table (GF1 chip) */
-#endif
-
-
-/*
- *    Note DMA2 of -1 has the right meaning in the GUS driver as well
- *      as here. 
- */
-
-static struct address_info cfg;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1;	/* Set this for modules that need it */
-static int __initdata type = 0;		/* 1 for PnP */
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma16, int, 0);
-module_param(type, int, 0);
-#ifdef CONFIG_SOUND_GUSMAX
-module_param(no_wave_dma, int, 0);
-#endif
-#ifdef CONFIG_SOUND_GUS16
-module_param(db16, int, 0);
-module_param(gus16, int, 0);
-#endif
-MODULE_LICENSE("GPL");
-
-static int __init init_gus(void)
-{
-	printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-	cfg.io_base = io;
-	cfg.irq = irq;
-	cfg.dma = dma;
-	cfg.dma2 = dma16;
-	cfg.card_subtype = type;
-#ifdef CONFIG_SOUND_GUSMAX
-	gus_no_wave_dma = no_wave_dma;
-#endif
-
-	if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
-		printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
-		return -EINVAL;
-	}
-
-#ifdef CONFIG_SOUND_GUS16
-	if (gus16 && init_gus_db16(&cfg))
-		db16 = 1;
-#endif
-	if (!probe_gus(&cfg))
-		return -ENODEV;
-	attach_gus(&cfg);
-
-	return 0;
-}
-
-static void __exit cleanup_gus(void)
-{
-#ifdef CONFIG_SOUND_GUS16
-	if (db16)
-		unload_gus_db16(&cfg);
-#endif
-	unload_gus(&cfg);
-}
-
-module_init(init_gus);
-module_exit(cleanup_gus);
-
-#ifndef MODULE
-static int __init setup_gus(char *str)
-{
-	/* io, irq, dma, dma2 */
-	int ints[5];
-	
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-	
-	io	= ints[1];
-	irq	= ints[2];
-	dma	= ints[3];
-	dma16	= ints[4];
-
-	return 1;
-}
-
-__setup("gus=", setup_gus);
-#endif
diff --git a/sound/oss/gus_hw.h b/sound/oss/gus_hw.h
deleted file mode 100644
index f97a0b8..0000000
--- a/sound/oss/gus_hw.h
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * I/O addresses
- */
-
-#define u_Base			(gus_base + 0x000)
-#define u_Mixer			u_Base
-#define u_Status		(gus_base + 0x006)
-#define u_TimerControl		(gus_base + 0x008)
-#define u_TimerData		(gus_base + 0x009)
-#define u_IRQDMAControl		(gus_base + 0x00b)
-#define u_MidiControl		(gus_base + 0x100)
-#define 	MIDI_RESET		0x03
-#define		MIDI_ENABLE_XMIT	0x20
-#define		MIDI_ENABLE_RCV		0x80
-#define u_MidiStatus		u_MidiControl
-#define		MIDI_RCV_FULL		0x01
-#define 	MIDI_XMIT_EMPTY		0x02
-#define 	MIDI_FRAME_ERR		0x10
-#define 	MIDI_OVERRUN		0x20
-#define 	MIDI_IRQ_PEND		0x80
-#define u_MidiData		(gus_base + 0x101)
-#define u_Voice			(gus_base + 0x102)
-#define u_Command		(gus_base + 0x103)
-#define u_DataLo		(gus_base + 0x104)
-#define u_DataHi		(gus_base + 0x105)
-#define u_MixData               (gus_base + 0x106)   /* Rev. 3.7+ mixing */
-#define u_MixSelect             (gus_base + 0x506)   /* registers.       */
-#define u_IrqStatus		u_Status
-#	define MIDI_TX_IRQ		0x01	/* pending MIDI xmit IRQ */
-#	define MIDI_RX_IRQ		0x02	/* pending MIDI recv IRQ */
-#	define GF1_TIMER1_IRQ		0x04	/* general purpose timer */
-#	define GF1_TIMER2_IRQ		0x08	/* general purpose timer */
-#	define WAVETABLE_IRQ		0x20	/* pending wavetable IRQ */
-#	define ENVELOPE_IRQ		0x40	/* pending volume envelope IRQ */
-#	define DMA_TC_IRQ		0x80	/* pending dma tc IRQ */
-
-#define ICS2101		1
-#	define ICS_MIXDEVS	6
-#	define DEV_MIC		0
-#	define DEV_LINE		1
-#	define DEV_CD		2
-#	define DEV_GF1		3
-#	define DEV_UNUSED	4
-#	define DEV_VOL		5
-
-#	define CHN_LEFT		0
-#	define CHN_RIGHT	1
-#define CS4231		2
-#define u_DRAMIO		(gus_base + 0x107)
diff --git a/sound/oss/gus_linearvol.h b/sound/oss/gus_linearvol.h
deleted file mode 100644
index 7ad0c30..0000000
--- a/sound/oss/gus_linearvol.h
+++ /dev/null
@@ -1,18 +0,0 @@
-static unsigned short gus_linearvol[128] = {
- 0x0000, 0x08ff, 0x09ff, 0x0a80, 0x0aff, 0x0b40, 0x0b80, 0x0bc0,
- 0x0bff, 0x0c20, 0x0c40, 0x0c60, 0x0c80, 0x0ca0, 0x0cc0, 0x0ce0,
- 0x0cff, 0x0d10, 0x0d20, 0x0d30, 0x0d40, 0x0d50, 0x0d60, 0x0d70,
- 0x0d80, 0x0d90, 0x0da0, 0x0db0, 0x0dc0, 0x0dd0, 0x0de0, 0x0df0,
- 0x0dff, 0x0e08, 0x0e10, 0x0e18, 0x0e20, 0x0e28, 0x0e30, 0x0e38,
- 0x0e40, 0x0e48, 0x0e50, 0x0e58, 0x0e60, 0x0e68, 0x0e70, 0x0e78,
- 0x0e80, 0x0e88, 0x0e90, 0x0e98, 0x0ea0, 0x0ea8, 0x0eb0, 0x0eb8,
- 0x0ec0, 0x0ec8, 0x0ed0, 0x0ed8, 0x0ee0, 0x0ee8, 0x0ef0, 0x0ef8,
- 0x0eff, 0x0f04, 0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c,
- 0x0f20, 0x0f24, 0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3c,
- 0x0f40, 0x0f44, 0x0f48, 0x0f4c, 0x0f50, 0x0f54, 0x0f58, 0x0f5c,
- 0x0f60, 0x0f64, 0x0f68, 0x0f6c, 0x0f70, 0x0f74, 0x0f78, 0x0f7c,
- 0x0f80, 0x0f84, 0x0f88, 0x0f8c, 0x0f90, 0x0f94, 0x0f98, 0x0f9c,
- 0x0fa0, 0x0fa4, 0x0fa8, 0x0fac, 0x0fb0, 0x0fb4, 0x0fb8, 0x0fbc,
- 0x0fc0, 0x0fc4, 0x0fc8, 0x0fcc, 0x0fd0, 0x0fd4, 0x0fd8, 0x0fdc,
- 0x0fe0, 0x0fe4, 0x0fe8, 0x0fec, 0x0ff0, 0x0ff4, 0x0ff8, 0x0ffc
-};
diff --git a/sound/oss/gus_midi.c b/sound/oss/gus_midi.c
deleted file mode 100644
index b48f57c..0000000
--- a/sound/oss/gus_midi.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * sound/gus2_midi.c
- *
- * The low level driver for the GUS Midi Interface.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000	Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *		Added __init to gus_midi_init()
- */
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_hw.h"
-
-static int      midi_busy, input_opened;
-static int      my_dev;
-static int      output_used;
-static volatile unsigned char gus_midi_control;
-static void     (*midi_input_intr) (int dev, unsigned char data);
-
-static unsigned char tmp_queue[256];
-extern int      gus_pnp_flag;
-static volatile int qlen;
-static volatile unsigned char qhead, qtail;
-extern int      gus_base, gus_irq, gus_dma;
-extern int     *gus_osp;
-extern spinlock_t gus_lock;
-
-static int GUS_MIDI_STATUS(void)
-{
-	return inb(u_MidiStatus);
-}
-
-static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
-{
-	if (midi_busy)
-	{
-/*		printk("GUS: Midi busy\n");*/
-		return -EBUSY;
-	}
-	outb((MIDI_RESET), u_MidiControl);
-	gus_delay();
-
-	gus_midi_control = 0;
-	input_opened = 0;
-
-	if (mode == OPEN_READ || mode == OPEN_READWRITE)
-		if (!gus_pnp_flag)
-		{
-			gus_midi_control |= MIDI_ENABLE_RCV;
-			input_opened = 1;
-		}
-	outb((gus_midi_control), u_MidiControl);	/* Enable */
-
-	midi_busy = 1;
-	qlen = qhead = qtail = output_used = 0;
-	midi_input_intr = input;
-
-	return 0;
-}
-
-static int dump_to_midi(unsigned char midi_byte)
-{
-	unsigned long   flags;
-	int             ok = 0;
-
-	output_used = 1;
-
-	spin_lock_irqsave(&gus_lock, flags);
-
-	if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
-	{
-		ok = 1;
-		outb((midi_byte), u_MidiData);
-	}
-	else
-	{
-		/*
-		 * Enable Midi xmit interrupts (again)
-		 */
-		gus_midi_control |= MIDI_ENABLE_XMIT;
-		outb((gus_midi_control), u_MidiControl);
-	}
-
-	spin_unlock_irqrestore(&gus_lock,flags);
-	return ok;
-}
-
-static void gus_midi_close(int dev)
-{
-	/*
-	 * Reset FIFO pointers, disable intrs
-	 */
-
-	outb((MIDI_RESET), u_MidiControl);
-	midi_busy = 0;
-}
-
-static int gus_midi_out(int dev, unsigned char midi_byte)
-{
-	unsigned long   flags;
-
-	/*
-	 * Drain the local queue first
-	 */
-	spin_lock_irqsave(&gus_lock, flags);
-
-	while (qlen && dump_to_midi(tmp_queue[qhead]))
-	{
-		qlen--;
-		qhead++;
-	}
-	spin_unlock_irqrestore(&gus_lock,flags);
-
-	/*
-	 *	Output the byte if the local queue is empty.
-	 */
-
-	if (!qlen)
-		if (dump_to_midi(midi_byte))
-			return 1;	/*
-					 * OK
-					 */
-
-	/*
-	 *	Put to the local queue
-	 */
-
-	if (qlen >= 256)
-		return 0;	/*
-				 * Local queue full
-				 */
-	spin_lock_irqsave(&gus_lock, flags);
-
-	tmp_queue[qtail] = midi_byte;
-	qlen++;
-	qtail++;
-
-	spin_unlock_irqrestore(&gus_lock,flags);
-	return 1;
-}
-
-static int gus_midi_start_read(int dev)
-{
-	return 0;
-}
-
-static int gus_midi_end_read(int dev)
-{
-	return 0;
-}
-
-static void gus_midi_kick(int dev)
-{
-}
-
-static int gus_midi_buffer_status(int dev)
-{
-	unsigned long   flags;
-
-	if (!output_used)
-		return 0;
-
-	spin_lock_irqsave(&gus_lock, flags);
-
-	if (qlen && dump_to_midi(tmp_queue[qhead]))
-	{
-		qlen--;
-		qhead++;
-	}
-	spin_unlock_irqrestore(&gus_lock,flags);
-	return (qlen > 0) || !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
-}
-
-#define MIDI_SYNTH_NAME	"Gravis Ultrasound Midi"
-#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct midi_operations gus_midi_operations =
-{
-	.owner		= THIS_MODULE,
-	.info		= {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
-	.converter	= &std_midi_synth,
-	.in_info	= {0},
-	.open		= gus_midi_open,
-	.close		= gus_midi_close,
-	.outputc	= gus_midi_out,
-	.start_read	= gus_midi_start_read,
-	.end_read	= gus_midi_end_read,
-	.kick		= gus_midi_kick,
-	.buffer_status	= gus_midi_buffer_status,
-};
-
-void __init gus_midi_init(struct address_info *hw_config)
-{
-	int dev = sound_alloc_mididev();
-
-	if (dev == -1)
-	{
-		printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
-		return;
-	}
-	outb((MIDI_RESET), u_MidiControl);
-
-	std_midi_synth.midi_dev = my_dev = dev;
-	hw_config->slots[2] = dev;
-	midi_devs[dev] = &gus_midi_operations;
-	sequencer_init();
-	return;
-}
-
-void gus_midi_interrupt(int dummy)
-{
-	volatile unsigned char stat, data;
-	int timeout = 10;
-
-	spin_lock(&gus_lock);
-
-	while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
-	{
-		if (stat & MIDI_RCV_FULL)
-		{
-			data = inb(u_MidiData);
-			if (input_opened)
-				midi_input_intr(my_dev, data);
-		}
-		if (stat & MIDI_XMIT_EMPTY)
-		{
-			while (qlen && dump_to_midi(tmp_queue[qhead]))
-			{
-				qlen--;
-				qhead++;
-			}
-			if (!qlen)
-			{
-			      /*
-			       * Disable Midi output interrupts, since no data in the buffer
-			       */
-			      gus_midi_control &= ~MIDI_ENABLE_XMIT;
-			      outb((gus_midi_control), u_MidiControl);
-			      outb((gus_midi_control), u_MidiControl);
-			}
-		}
-	}
-	spin_unlock(&gus_lock);
-}
diff --git a/sound/oss/gus_vol.c b/sound/oss/gus_vol.c
deleted file mode 100644
index 6ae6924..0000000
--- a/sound/oss/gus_vol.c
+++ /dev/null
@@ -1,153 +0,0 @@
-
-/*
- * gus_vol.c - Compute volume for GUS.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_linearvol.h"
-
-#define GUS_VOLUME	gus_wave_volume
-
-
-extern int      gus_wave_volume;
-
-/*
- * Calculate gus volume from note velocity, main volume, expression, and
- * intrinsic patch volume given in patch library.  Expression is multiplied
- * in, so it emphasizes differences in note velocity, while main volume is
- * added in -- I don't know whether this is right, but it seems reasonable to
- * me.  (In the previous stage, main volume controller messages were changed
- * to expression controller messages, if they were found to be used for
- * dynamic volume adjustments, so here, main volume can be assumed to be
- * constant throughout a song.)
- *
- * Intrinsic patch volume is added in, but if over 64 is also multiplied in, so
- * we can give a big boost to very weak voices like nylon guitar and the
- * basses.  The normal value is 64.  Strings are assigned lower values.
- */
-
-unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
-{
-	int i, m, n, x;
-
-
-	/*
-	 * A voice volume of 64 is considered neutral, so adjust the main volume if
-	 * something other than this neutral value was assigned in the patch
-	 * library.
-	 */
-	x = 256 + 6 * (voicev - 64);
-
-	/*
-	 * Boost expression by voice volume above neutral.
-	 */
-	 
-	if (voicev > 65)
-		xpn += voicev - 64;
-	xpn += (voicev - 64) / 2;
-
-	/*
-	 * Combine multiplicative and level components.
-	 */
-	x = vel * xpn * 6 + (voicev / 4) * x;
-
-#ifdef GUS_VOLUME
-	/*
-	 * Further adjustment by installation-specific master volume control
-	 * (default 60).
-	 */
-	x = (x * GUS_VOLUME * GUS_VOLUME) / 10000;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
-	/*
-	 * Experimental support for the channel main volume
-	 */
-
-	mainv = (mainv / 2) + 64;	/* Scale to 64 to 127 */
-	x = (x * mainv * mainv) / 16384;
-#endif
-
-	if (x < 2)
-		return (0);
-	else if (x >= 65535)
-		return ((15 << 8) | 255);
-
-	/*
-	 * Convert to GUS's logarithmic form with 4 bit exponent i and 8 bit
-	 * mantissa m.
-	 */
-	 
-	n = x;
-	i = 7;
-	if (n < 128)
-	{
-		  while (i > 0 && n < (1 << i))
-			  i--;
-	}
-	else
-	{
-		while (n > 255)
-		{
-			  n >>= 1;
-			  i++;
-		}
-	}
-	/*
-	 * Mantissa is part of linear volume not expressed in exponent.  (This is
-	 * not quite like real logs -- I wonder if it's right.)
-	 */
-	m = x - (1 << i);
-
-	/*
-	 * Adjust mantissa to 8 bits.
-	 */
-	if (m > 0)
-	{
-		if (i > 8)
-			m >>= i - 8;
-		else if (i < 8)
-			m <<= 8 - i;
-	}
-	return ((i << 8) + m);
-}
-
-/*
- * Volume-values are interpreted as linear values. Volume is based on the
- * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
- * and the volume set by the mixer-device (default 60%).
- */
-
-unsigned short gus_linear_vol(int vol, int mainvol)
-{
-	int mixer_mainvol;
-
-	if (vol <= 0)
-		vol = 0;
-	else if (vol >= 127)
-		vol = 127;
-
-#ifdef GUS_VOLUME
-	mixer_mainvol = GUS_VOLUME;
-#else
-	mixer_mainvol = 100;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
-	if (mainvol <= 0)
-		mainvol = 0;
-	else if (mainvol >= 127)
-		mainvol = 127;
-#else
-	mainvol = 127;
-#endif
-	return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
-}
diff --git a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
deleted file mode 100644
index 942d518..0000000
--- a/sound/oss/gus_wave.c
+++ /dev/null
@@ -1,3464 +0,0 @@
-/*
- * sound/gus_wave.c
- *
- * Driver for the Gravis UltraSound wave table synth.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer    : ioctl code reworked (vmalloc/vfree removed)
- * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious
- *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
- * Bartlomiej Zolnierkiewicz : added some __init/__exit
- */
- 
-#include <linux/init.h> 
-#include <linux/config.h>
-#include <linux/spinlock.h>
-
-#define GUSPNP_AUTODETECT
-
-#include "sound_config.h"
-#include <linux/ultrasound.h>
-
-#include "gus.h"
-#include "gus_hw.h"
-
-#define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
-
-#define MAX_SAMPLE	150
-#define MAX_PATCH	256
-
-#define NOT_SAMPLE	0xffff
-
-struct voice_info
-{
-	unsigned long   orig_freq;
-	unsigned long   current_freq;
-	unsigned long   mode;
-	int             fixed_pitch;
-	int             bender;
-	int             bender_range;
-	int             panning;
-	int             midi_volume;
-	unsigned int    initial_volume;
-	unsigned int    current_volume;
-	int             loop_irq_mode, loop_irq_parm;
-#define LMODE_FINISH		1
-#define LMODE_PCM		2
-#define LMODE_PCM_STOP		3
-	int             volume_irq_mode, volume_irq_parm;
-#define VMODE_HALT		1
-#define VMODE_ENVELOPE		2
-#define VMODE_START_NOTE	3
-
-	int             env_phase;
-	unsigned char   env_rate[6];
-	unsigned char   env_offset[6];
-
-	/*
-	 * Volume computation parameters for gus_adagio_vol()
-	 */
-	int		main_vol, expression_vol, patch_vol;
-
-	/* Variables for "Ultraclick" removal */
-	int             dev_pending, note_pending, volume_pending,
-	                sample_pending;
-	char            kill_pending;
-	long            offset_pending;
-
-};
-
-static struct voice_alloc_info *voice_alloc;
-static struct address_info *gus_hw_config;
-extern int      gus_base;
-extern int      gus_irq, gus_dma;
-extern int      gus_pnp_flag;
-extern int      gus_no_wave_dma;
-static int      gus_dma2 = -1;
-static int      dual_dma_mode;
-static long     gus_mem_size;
-static long     free_mem_ptr;
-static int      gus_busy;
-static int      gus_no_dma;
-static int      nr_voices;
-static int      gus_devnum;
-static int      volume_base, volume_scale, volume_method;
-static int      gus_recmask = SOUND_MASK_MIC;
-static int      recording_active;
-static int      only_read_access;
-static int      only_8_bits;
-
-static int      iw_mode = 0;
-int             gus_wave_volume = 60;
-int             gus_pcm_volume = 80;
-int             have_gus_max = 0;
-static int      gus_line_vol = 100, gus_mic_vol;
-static unsigned char mix_image = 0x00;
-
-int             gus_timer_enabled = 0;
-
-/*
- * Current version of this driver doesn't allow synth and PCM functions
- * at the same time. The active_device specifies the active driver
- */
-
-static int      active_device;
-
-#define GUS_DEV_WAVE		1	/* Wave table synth */
-#define GUS_DEV_PCM_DONE	2	/* PCM device, transfer done */
-#define GUS_DEV_PCM_CONTINUE	3	/* PCM device, transfer done ch. 1/2 */
-
-static int      gus_audio_speed;
-static int      gus_audio_channels;
-static int      gus_audio_bits;
-static int      gus_audio_bsize;
-static char     bounce_buf[8 * 1024];	/* Must match value set to max_fragment */
-
-static DECLARE_WAIT_QUEUE_HEAD(dram_sleeper);
-
-/*
- * Variables and buffers for PCM output
- */
-
-#define MAX_PCM_BUFFERS		(128*MAX_REALTIME_FACTOR)	/* Don't change */
-
-static int      pcm_bsize, pcm_nblk, pcm_banksize;
-static int      pcm_datasize[MAX_PCM_BUFFERS];
-static volatile int pcm_head, pcm_tail, pcm_qlen;
-static volatile int pcm_active;
-static volatile int dma_active;
-static int      pcm_opened;
-static int      pcm_current_dev;
-static int      pcm_current_block;
-static unsigned long pcm_current_buf;
-static int      pcm_current_count;
-static int      pcm_current_intrflag;
-DEFINE_SPINLOCK(gus_lock);
-
-extern int     *gus_osp;
-
-static struct voice_info voices[32];
-
-static int      freq_div_table[] =
-{
-	44100,			/* 14 */
-	41160,			/* 15 */
-	38587,			/* 16 */
-	36317,			/* 17 */
-	34300,			/* 18 */
-	32494,			/* 19 */
-	30870,			/* 20 */
-	29400,			/* 21 */
-	28063,			/* 22 */
-	26843,			/* 23 */
-	25725,			/* 24 */
-	24696,			/* 25 */
-	23746,			/* 26 */
-	22866,			/* 27 */
-	22050,			/* 28 */
-	21289,			/* 29 */
-	20580,			/* 30 */
-	19916,			/* 31 */
-	19293			/* 32 */
-};
-
-static struct patch_info *samples;
-static long     sample_ptrs[MAX_SAMPLE + 1];
-static int      sample_map[32];
-static int      free_sample;
-static int      mixer_type;
-
-
-static int      patch_table[MAX_PATCH];
-static int      patch_map[32];
-
-static struct synth_info gus_info = {
-	"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 
-	0, 16, 0, MAX_PATCH
-};
-
-static void     gus_poke(long addr, unsigned char data);
-static void     compute_and_set_volume(int voice, int volume, int ramp_time);
-extern unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev);
-extern unsigned short gus_linear_vol(int vol, int mainvol);
-static void     compute_volume(int voice, int volume);
-static void     do_volume_irq(int voice);
-static void     set_input_volumes(void);
-static void     gus_tmr_install(int io_base);
-
-#define	INSTANT_RAMP		-1	/* Instant change. No ramping */
-#define FAST_RAMP		0	/* Fastest possible ramp */
-
-static void reset_sample_memory(void)
-{
-	int i;
-
-	for (i = 0; i <= MAX_SAMPLE; i++)
-		sample_ptrs[i] = -1;
-	for (i = 0; i < 32; i++)
-		sample_map[i] = -1;
-	for (i = 0; i < 32; i++)
-		patch_map[i] = -1;
-
-	gus_poke(0, 0);		/* Put a silent sample to the beginning */
-	gus_poke(1, 0);
-	free_mem_ptr = 2;
-
-	free_sample = 0;
-
-	for (i = 0; i < MAX_PATCH; i++)
-		patch_table[i] = NOT_SAMPLE;
-}
-
-void gus_delay(void)
-{
-	int i;
-
-	for (i = 0; i < 7; i++)
-		inb(u_DRAMIO);
-}
-
-static void gus_poke(long addr, unsigned char data)
-{				/* Writes a byte to the DRAM */
-	outb((0x43), u_Command);
-	outb((addr & 0xff), u_DataLo);
-	outb(((addr >> 8) & 0xff), u_DataHi);
-
-	outb((0x44), u_Command);
-	outb(((addr >> 16) & 0xff), u_DataHi);
-	outb((data), u_DRAMIO);
-}
-
-static unsigned char gus_peek(long addr)
-{				/* Reads a byte from the DRAM */
-	unsigned char   tmp;
-
-	outb((0x43), u_Command);
-	outb((addr & 0xff), u_DataLo);
-	outb(((addr >> 8) & 0xff), u_DataHi);
-
-	outb((0x44), u_Command);
-	outb(((addr >> 16) & 0xff), u_DataHi);
-	tmp = inb(u_DRAMIO);
-
-	return tmp;
-}
-
-void gus_write8(int reg, unsigned int data)
-{				/* Writes to an indirect register (8 bit) */
-	outb((reg), u_Command);
-	outb(((unsigned char) (data & 0xff)), u_DataHi);
-}
-
-static unsigned char gus_read8(int reg)
-{				
-	/* Reads from an indirect register (8 bit). Offset 0x80. */
-	unsigned char   val;
-
-	outb((reg | 0x80), u_Command);
-	val = inb(u_DataHi);
-
-	return val;
-}
-
-static unsigned char gus_look8(int reg)
-{
-	/* Reads from an indirect register (8 bit). No additional offset. */
-	unsigned char   val;
-
-	outb((reg), u_Command);
-	val = inb(u_DataHi);
-
-	return val;
-}
-
-static void gus_write16(int reg, unsigned int data)
-{
-	/* Writes to an indirect register (16 bit) */
-	outb((reg), u_Command);
-
-	outb(((unsigned char) (data & 0xff)), u_DataLo);
-	outb(((unsigned char) ((data >> 8) & 0xff)), u_DataHi);
-}
-
-static unsigned short gus_read16(int reg)
-{
-	/* Reads from an indirect register (16 bit). Offset 0x80. */
-	unsigned char   hi, lo;
-
-	outb((reg | 0x80), u_Command);
-
-	lo = inb(u_DataLo);
-	hi = inb(u_DataHi);
-
-	return ((hi << 8) & 0xff00) | lo;
-}
-
-static unsigned short gus_look16(int reg)
-{		
-	/* Reads from an indirect register (16 bit). No additional offset. */
-	unsigned char   hi, lo;
-
-	outb((reg), u_Command);
-
-	lo = inb(u_DataLo);
-	hi = inb(u_DataHi);
-
-	return ((hi << 8) & 0xff00) | lo;
-}
-
-static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
-{
-	/* Writes an 24 bit memory address */
-	unsigned long   hold_address;
-
-	if (is16bit)
-	{
-		if (iw_mode)
-		{
-			/* Interwave spesific address translations */
-			address >>= 1;
-		}
-		else
-		{
-			/*
-			 * Special processing required for 16 bit patches
-			 */
-
-			hold_address = address;
-			address = address >> 1;
-			address &= 0x0001ffffL;
-			address |= (hold_address & 0x000c0000L);
-		}
-	}
-	gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
-	gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
-		    + (frac << 5));
-	/* Could writing twice fix problems with GUS_VOICE_POS()? Let's try. */
-	gus_delay();
-	gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
-	gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
-		    + (frac << 5));
-}
-
-static void gus_select_voice(int voice)
-{
-	if (voice < 0 || voice > 31)
-		return;
-	outb((voice), u_Voice);
-}
-
-static void gus_select_max_voices(int nvoices)
-{
-	if (iw_mode)
-		nvoices = 32;
-	if (nvoices < 14)
-		nvoices = 14;
-	if (nvoices > 32)
-		nvoices = 32;
-
-	voice_alloc->max_voice = nr_voices = nvoices;
-	gus_write8(0x0e, (nvoices - 1) | 0xc0);
-}
-
-static void gus_voice_on(unsigned int mode)
-{
-	gus_write8(0x00, (unsigned char) (mode & 0xfc));
-	gus_delay();
-	gus_write8(0x00, (unsigned char) (mode & 0xfc));
-}
-
-static void gus_voice_off(void)
-{
-	gus_write8(0x00, gus_read8(0x00) | 0x03);
-}
-
-static void gus_voice_mode(unsigned int m)
-{
-	unsigned char   mode = (unsigned char) (m & 0xff);
-
-	gus_write8(0x00, (gus_read8(0x00) & 0x03) |
-		   (mode & 0xfc));	/* Don't touch last two bits */
-	gus_delay();
-	gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_voice_freq(unsigned long freq)
-{
-	unsigned long   divisor = freq_div_table[nr_voices - 14];
-	unsigned short  fc;
-
-	/* Interwave plays at 44100 Hz with any number of voices */
-	if (iw_mode)
-		fc = (unsigned short) (((freq << 9) + (44100 >> 1)) / 44100);
-	else
-		fc = (unsigned short) (((freq << 9) + (divisor >> 1)) / divisor);
-	fc = fc << 1;
-
-	gus_write16(0x01, fc);
-}
-
-static void gus_voice_volume(unsigned int vol)
-{
-	gus_write8(0x0d, 0x03);	/* Stop ramp before setting volume */
-	gus_write16(0x09, (unsigned short) (vol << 4));
-}
-
-static void gus_voice_balance(unsigned int balance)
-{
-	gus_write8(0x0c, (unsigned char) (balance & 0xff));
-}
-
-static void gus_ramp_range(unsigned int low, unsigned int high)
-{
-	gus_write8(0x07, (unsigned char) ((low >> 4) & 0xff));
-	gus_write8(0x08, (unsigned char) ((high >> 4) & 0xff));
-}
-
-static void gus_ramp_rate(unsigned int scale, unsigned int rate)
-{
-	gus_write8(0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
-}
-
-static void gus_rampon(unsigned int m)
-{
-	unsigned char   mode = (unsigned char) (m & 0xff);
-
-	gus_write8(0x0d, mode & 0xfc);
-	gus_delay();
-	gus_write8(0x0d, mode & 0xfc);
-}
-
-static void gus_ramp_mode(unsigned int m)
-{
-	unsigned char mode = (unsigned char) (m & 0xff);
-
-	gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
-		   (mode & 0xfc));	/* Leave the last 2 bits alone */
-	gus_delay();
-	gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_rampoff(void)
-{
-	gus_write8(0x0d, 0x03);
-}
-
-static void gus_set_voice_pos(int voice, long position)
-{
-	int sample_no;
-
-	if ((sample_no = sample_map[voice]) != -1) {
-		if (position < samples[sample_no].len) {
-			if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-				voices[voice].offset_pending = position;
-			else
-				gus_write_addr(0x0a, sample_ptrs[sample_no] + position, 0,
-				 samples[sample_no].mode & WAVE_16_BITS);
-		}
-	}
-}
-
-static void gus_voice_init(int voice)
-{
-	unsigned long   flags;
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-	gus_voice_volume(0);
-	gus_voice_off();
-	gus_write_addr(0x0a, 0, 0, 0);	/* Set current position to 0 */
-	gus_write8(0x00, 0x03);	/* Voice off */
-	gus_write8(0x0d, 0x03);	/* Ramping off */
-	voice_alloc->map[voice] = 0;
-	voice_alloc->alloc_times[voice] = 0;
-	spin_unlock_irqrestore(&gus_lock,flags);
-
-}
-
-static void gus_voice_init2(int voice)
-{
-	voices[voice].panning = 0;
-	voices[voice].mode = 0;
-	voices[voice].orig_freq = 20000;
-	voices[voice].current_freq = 20000;
-	voices[voice].bender = 0;
-	voices[voice].bender_range = 200;
-	voices[voice].initial_volume = 0;
-	voices[voice].current_volume = 0;
-	voices[voice].loop_irq_mode = 0;
-	voices[voice].loop_irq_parm = 0;
-	voices[voice].volume_irq_mode = 0;
-	voices[voice].volume_irq_parm = 0;
-	voices[voice].env_phase = 0;
-	voices[voice].main_vol = 127;
-	voices[voice].patch_vol = 127;
-	voices[voice].expression_vol = 127;
-	voices[voice].sample_pending = -1;
-	voices[voice].fixed_pitch = 0;
-}
-
-static void step_envelope(int voice)
-{
-	unsigned        vol, prev_vol, phase;
-	unsigned char   rate;
-	unsigned long flags;
-
-	if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
-	{
-		spin_lock_irqsave(&gus_lock,flags);
-		gus_select_voice(voice);
-		gus_rampoff();
-		spin_unlock_irqrestore(&gus_lock,flags);
-		return;
-		/*
-		 * Sustain phase begins. Continue envelope after receiving note off.
-		 */
-	}
-	if (voices[voice].env_phase >= 5)
-	{
-		/* Envelope finished. Shoot the voice down */
-		gus_voice_init(voice);
-		return;
-	}
-	prev_vol = voices[voice].current_volume;
-	phase = ++voices[voice].env_phase;
-	compute_volume(voice, voices[voice].midi_volume);
-	vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
-	rate = voices[voice].env_rate[phase];
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-
-	gus_voice_volume(prev_vol);
-
-
-	gus_write8(0x06, rate);	/* Ramping rate */
-
-	voices[voice].volume_irq_mode = VMODE_ENVELOPE;
-
-	if (((vol - prev_vol) / 64) == 0)	/* No significant volume change */
-	{
-		spin_unlock_irqrestore(&gus_lock,flags);
-		step_envelope(voice);		/* Continue the envelope on the next step */
-		return;
-	}
-	if (vol > prev_vol)
-	{
-		if (vol >= (4096 - 64))
-			vol = 4096 - 65;
-		gus_ramp_range(0, vol);
-		gus_rampon(0x20);	/* Increasing volume, with IRQ */
-	}
-	else
-	{
-		if (vol <= 64)
-			vol = 65;
-		gus_ramp_range(vol, 4030);
-		gus_rampon(0x60);	/* Decreasing volume, with IRQ */
-	}
-	voices[voice].current_volume = vol;
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void init_envelope(int voice)
-{
-	voices[voice].env_phase = -1;
-	voices[voice].current_volume = 64;
-
-	step_envelope(voice);
-}
-
-static void start_release(int voice)
-{
-	if (gus_read8(0x00) & 0x03)
-		return;		/* Voice already stopped */
-
-	voices[voice].env_phase = 2;	/* Will be incremented by step_envelope */
-
-	voices[voice].current_volume = voices[voice].initial_volume =
-						gus_read16(0x09) >> 4;	/* Get current volume */
-
-	voices[voice].mode &= ~WAVE_SUSTAIN_ON;
-	gus_rampoff();
-	step_envelope(voice);
-}
-
-static void gus_voice_fade(int voice)
-{
-	int instr_no = sample_map[voice], is16bits;
-	unsigned long flags;
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-
-	if (instr_no < 0 || instr_no > MAX_SAMPLE)
-	{
-		gus_write8(0x00, 0x03);	/* Hard stop */
-		voice_alloc->map[voice] = 0;
-		spin_unlock_irqrestore(&gus_lock,flags);
-		return;
-	}
-	is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0;	/* 8 or 16 bits */
-
-	if (voices[voice].mode & WAVE_ENVELOPES)
-	{
-		start_release(voice);
-		spin_unlock_irqrestore(&gus_lock,flags);
-		return;
-	}
-	/*
-	 * Ramp the volume down but not too quickly.
-	 */
-	if ((int) (gus_read16(0x09) >> 4) < 100)	/* Get current volume */
-	{
-		gus_voice_off();
-		gus_rampoff();
-		gus_voice_init(voice);
-		spin_unlock_irqrestore(&gus_lock,flags);
-		return;
-	}
-	gus_ramp_range(65, 4030);
-	gus_ramp_rate(2, 4);
-	gus_rampon(0x40 | 0x20);	/* Down, once, with IRQ */
-	voices[voice].volume_irq_mode = VMODE_HALT;
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void gus_reset(void)
-{
-	int i;
-
-	gus_select_max_voices(24);
-	volume_base = 3071;
-	volume_scale = 4;
-	volume_method = VOL_METHOD_ADAGIO;
-
-	for (i = 0; i < 32; i++)
-	{
-		gus_voice_init(i);	/* Turn voice off */
-		gus_voice_init2(i);
-	}
-}
-
-static void gus_initialize(void)
-{
-	unsigned long flags;
-	unsigned char dma_image, irq_image, tmp;
-
-	static unsigned char gus_irq_map[16] = 	{
-		0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7
-	};
-
-	static unsigned char gus_dma_map[8] = {
-		0, 1, 0, 2, 0, 3, 4, 5
-	};
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_write8(0x4c, 0);	/* Reset GF1 */
-	gus_delay();
-	gus_delay();
-
-	gus_write8(0x4c, 1);	/* Release Reset */
-	gus_delay();
-	gus_delay();
-
-	/*
-	 * Clear all interrupts
-	 */
-
-	gus_write8(0x41, 0);	/* DMA control */
-	gus_write8(0x45, 0);	/* Timer control */
-	gus_write8(0x49, 0);	/* Sample control */
-
-	gus_select_max_voices(24);
-
-	inb(u_Status);		/* Touch the status register */
-
-	gus_look8(0x41);	/* Clear any pending DMA IRQs */
-	gus_look8(0x49);	/* Clear any pending sample IRQs */
-	gus_read8(0x0f);	/* Clear pending IRQs */
-
-	gus_reset();		/* Resets all voices */
-
-	gus_look8(0x41);	/* Clear any pending DMA IRQs */
-	gus_look8(0x49);	/* Clear any pending sample IRQs */
-	gus_read8(0x0f);	/* Clear pending IRQs */
-
-	gus_write8(0x4c, 7);	/* Master reset | DAC enable | IRQ enable */
-
-	/*
-	 * Set up for Digital ASIC
-	 */
-
-	outb((0x05), gus_base + 0x0f);
-
-	mix_image |= 0x02;	/* Disable line out (for a moment) */
-	outb((mix_image), u_Mixer);
-
-	outb((0x00), u_IRQDMAControl);
-
-	outb((0x00), gus_base + 0x0f);
-
-	/*
-	 * Now set up the DMA and IRQ interface
-	 *
-	 * The GUS supports two IRQs and two DMAs.
-	 *
-	 * Just one DMA channel is used. This prevents simultaneous ADC and DAC.
-	 * Adding this support requires significant changes to the dmabuf.c, dsp.c
-	 * and audio.c also.
-	 */
-
-	irq_image = 0;
-	tmp = gus_irq_map[gus_irq];
-	if (!gus_pnp_flag && !tmp)
-		printk(KERN_WARNING "Warning! GUS IRQ not selected\n");
-	irq_image |= tmp;
-	irq_image |= 0x40;	/* Combine IRQ1 (GF1) and IRQ2 (Midi) */
-
-	dual_dma_mode = 1;
-	if (gus_dma2 == gus_dma || gus_dma2 == -1)
-	{
-		dual_dma_mode = 0;
-		dma_image = 0x40;	/* Combine DMA1 (DRAM) and IRQ2 (ADC) */
-
-		tmp = gus_dma_map[gus_dma];
-		if (!tmp)
-			printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
-		dma_image |= tmp;
-	}
-	else
-	{
-		/* Setup dual DMA channel mode for GUS MAX */
-
-		dma_image = gus_dma_map[gus_dma];
-		if (!dma_image)
-			printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
-		tmp = gus_dma_map[gus_dma2] << 3;
-		if (!tmp)
-		{
-			printk(KERN_WARNING "Warning! Invalid GUS MAX DMA\n");
-			tmp = 0x40;		/* Combine DMA channels */
-			    dual_dma_mode = 0;
-		}
-		dma_image |= tmp;
-	}
-
-	/*
-	 * For some reason the IRQ and DMA addresses must be written twice
-	 */
-
-	/*
-	 * Doing it first time
-	 */
-
-	outb((mix_image), u_Mixer);	/* Select DMA control */
-	outb((dma_image | 0x80), u_IRQDMAControl);	/* Set DMA address */
-
-	outb((mix_image | 0x40), u_Mixer);	/* Select IRQ control */
-	outb((irq_image), u_IRQDMAControl);	/* Set IRQ address */
-
-	/*
-	 * Doing it second time
-	 */
-
-	outb((mix_image), u_Mixer);	/* Select DMA control */
-	outb((dma_image), u_IRQDMAControl);	/* Set DMA address */
-
-	outb((mix_image | 0x40), u_Mixer);	/* Select IRQ control */
-	outb((irq_image), u_IRQDMAControl);	/* Set IRQ address */
-
-	gus_select_voice(0);	/* This disables writes to IRQ/DMA reg */
-
-	mix_image &= ~0x02;	/* Enable line out */
-	mix_image |= 0x08;	/* Enable IRQ */
-	outb((mix_image), u_Mixer);	/*
-					 * Turn mixer channels on
-					 * Note! Mic in is left off.
-					 */
-
-	gus_select_voice(0);	/* This disables writes to IRQ/DMA reg */
-
-	gusintr(gus_irq, (void *)gus_hw_config, NULL);	/* Serve pending interrupts */
-
-	inb(u_Status);		/* Touch the status register */
-
-	gus_look8(0x41);	/* Clear any pending DMA IRQs */
-	gus_look8(0x49);	/* Clear any pending sample IRQs */
-
-	gus_read8(0x0f);	/* Clear pending IRQs */
-
-	if (iw_mode)
-		gus_write8(0x19, gus_read8(0x19) | 0x01);
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-
-static void __init pnp_mem_init(void)
-{
-#include "iwmem.h"
-#define CHUNK_SIZE (256*1024)
-#define BANK_SIZE (4*1024*1024)
-#define CHUNKS_PER_BANK (BANK_SIZE/CHUNK_SIZE)
-
-	int bank, chunk, addr, total = 0;
-	int bank_sizes[4];
-	int i, j, bits = -1, testbits = -1, nbanks = 0;
-
-	/*
-	 * This routine determines what kind of RAM is installed in each of the four
-	 * SIMM banks and configures the DRAM address decode logic accordingly.
-	 */
-
-	/*
-	 *    Place the chip into enhanced mode
-	 */
-	gus_write8(0x19, gus_read8(0x19) | 0x01);
-	gus_write8(0x53, gus_look8(0x53) & ~0x02);	/* Select DRAM I/O access */
-
-	/*
-	 * Set memory configuration to 4 DRAM banks of 4M in each (16M total).
-	 */
-
-	gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | 0x000c);
-
-	/*
-	 * Perform the DRAM size detection for each bank individually.
-	 */
-	for (bank = 0; bank < 4; bank++)
-	{
-		int size = 0;
-
-		addr = bank * BANK_SIZE;
-
-		/* Clean check points of each chunk */
-		for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-		{
-			gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-			gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-		}
-
-		/* Write a value to each chunk point and verify the result */
-		for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-		{
-			gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
-			gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
-
-			if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
-				gus_peek(addr + chunk * CHUNK_SIZE + 1L) == 0xAA)
-			{
-				/* OK. There is RAM. Now check for possible shadows */
-				int ok = 1, chunk2;
-
-				for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
-					if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
-							gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
-						ok = 0;	/* Addressing wraps */
-
-				if (ok)
-					size = (chunk + 1) * CHUNK_SIZE;
-			}
-			gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-			gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-		}
-		bank_sizes[bank] = size;
-		if (size)
-			nbanks = bank + 1;
-		DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
-	}
-
-	if (nbanks == 0)	/* No RAM - Give up */
-	{
-		printk(KERN_ERR "Sound: An Interwave audio chip detected but no DRAM\n");
-		printk(KERN_ERR "Sound: Unable to work with this card.\n");
-		gus_write8(0x19, gus_read8(0x19) & ~0x01);
-		gus_mem_size = 0;
-		return;
-	}
-
-	/*
-	 * Now we know how much DRAM there is in each bank. The next step is
-	 * to find a DRAM size encoding (0 to 12) which is best for the combination
-	 * we have.
-	 *
-	 * First try if any of the possible alternatives matches exactly the amount
-	 * of memory we have.
-	 */
-
-	for (i = 0; bits == -1 && i < 13; i++)
-	{
-		bits = i;
-
-		for (j = 0; bits != -1 && j < 4; j++)
-			if (mem_decode[i][j] != bank_sizes[j])
-				bits = -1;	/* No hit */
-	}
-
-	/*
-	 * If necessary, try to find a combination where other than the last
-	 * bank matches our configuration and the last bank is left oversized.
-	 * In this way we don't leave holes in the middle of memory.
-	 */
-
-	if (bits == -1)		/* No luck yet */
-	{
-		for (i = 0; bits == -1 && i < 13; i++)
-		{
-			bits = i;
-
-			for (j = 0; bits != -1 && j < nbanks - 1; j++)
-				if (mem_decode[i][j] != bank_sizes[j])
-					bits = -1;	/* No hit */
-			if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
-				bits = -1;	/* The last bank is too small */
-		}
-	}
-	/*
- 	 * The last resort is to search for a combination where the banks are
- 	 * smaller than the actual SIMMs. This leaves some memory in the banks
- 	 * unused but doesn't leave holes in the DRAM address space.
- 	 */
- 	if (bits == -1)		/* No luck yet */
- 	{
- 		for (i = 0; i < 13; i++)
- 		{
- 			testbits = i;
- 			for (j = 0; testbits != -1 && j < nbanks - 1; j++)
- 				if (mem_decode[i][j] > bank_sizes[j]) {
- 					testbits = -1;
- 				}
- 			if(testbits > bits) bits = testbits;
- 		}
- 		if (bits != -1)
- 		{
-			printk(KERN_INFO "Interwave: Can't use all installed RAM.\n");
-			printk(KERN_INFO "Interwave: Try reordering SIMMS.\n");
-		}
-		printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n");
-		printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
-		bits = 0;
-	}
-	DDB(printk("Interwave: Selecting DRAM addressing mode %d\n", bits));
-
-	for (bank = 0; bank < 4; bank++)
-	{
-		DDB(printk("  Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
-
-		if (bank_sizes[bank] > mem_decode[bits][bank])
-			total += mem_decode[bits][bank];
-		else
-			total += bank_sizes[bank];
-	}
-
-	DDB(printk("Total %dk of DRAM (enhanced mode)\n", total / 1024));
-
-	/*
-	 *    Set the memory addressing mode.
-	 */
-	gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | bits);
-
-/*      Leave the chip into enhanced mode. Disable LFO  */
-	gus_mem_size = total;
-	iw_mode = 1;
-	gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02);
-}
-
-int __init gus_wave_detect(int baseaddr)
-{
-	unsigned long   i, max_mem = 1024L;
-	unsigned long   loc;
-	unsigned char   val;
-
-	if (!request_region(baseaddr, 16, "GUS"))
-		return 0;
-	if (!request_region(baseaddr + 0x100, 12, "GUS")) { /* 0x10c-> is MAX */
-		release_region(baseaddr, 16);
-		return 0;
-	}
-
-	gus_base = baseaddr;
-
-	gus_write8(0x4c, 0);	/* Reset GF1 */
-	gus_delay();
-	gus_delay();
-
-	gus_write8(0x4c, 1);	/* Release Reset */
-	gus_delay();
-	gus_delay();
-
-#ifdef GUSPNP_AUTODETECT
-	val = gus_look8(0x5b);	/* Version number register */
-	gus_write8(0x5b, ~val);	/* Invert all bits */
-
-	if ((gus_look8(0x5b) & 0xf0) == (val & 0xf0))	/* No change */
-	{
-		if ((gus_look8(0x5b) & 0x0f) == ((~val) & 0x0f))	/* Change */
-		{
-			DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
-			gus_pnp_flag = 1;
-		}
-		else
-		{
-			DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
-			gus_pnp_flag = 0;
-		}
-	}
-	gus_write8(0x5b, val);	/* Restore all bits */
-#endif
-
-	if (gus_pnp_flag)
-		pnp_mem_init();
-	if (iw_mode)
-		return 1;
-
-	/* See if there is first block there.... */
-	gus_poke(0L, 0xaa);
-	if (gus_peek(0L) != 0xaa) {
-		release_region(baseaddr + 0x100, 12);
-		release_region(baseaddr, 16);
-		return 0;
-	}
-
-	/* Now zero it out so that I can check for mirroring .. */
-	gus_poke(0L, 0x00);
-	for (i = 1L; i < max_mem; i++)
-	{
-		int n, failed;
-
-		/* check for mirroring ... */
-		if (gus_peek(0L) != 0)
-			break;
-		loc = i << 10;
-
-		for (n = loc - 1, failed = 0; n <= loc; n++)
-		{
-			gus_poke(loc, 0xaa);
-			if (gus_peek(loc) != 0xaa)
-				failed = 1;
-			gus_poke(loc, 0x55);
-			if (gus_peek(loc) != 0x55)
-				failed = 1;
-		}
-		if (failed)
-			break;
-	}
-	gus_mem_size = i << 10;
-	return 1;
-}
-
-static int guswave_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-
-	switch (cmd) 
-	{
-		case SNDCTL_SYNTH_INFO:
-			gus_info.nr_voices = nr_voices;
-			if (copy_to_user(arg, &gus_info, sizeof(gus_info)))
-				return -EFAULT;
-			return 0;
-
-		case SNDCTL_SEQ_RESETSAMPLES:
-			reset_sample_memory();
-			return 0;
-
-		case SNDCTL_SEQ_PERCMODE:
-			return 0;
-
-		case SNDCTL_SYNTH_MEMAVL:
-			return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
-
-		default:
-			return -EINVAL;
-	}
-}
-
-static int guswave_set_instr(int dev, int voice, int instr_no)
-{
-	int sample_no;
-
-	if (instr_no < 0 || instr_no > MAX_PATCH)
-		instr_no = 0;	/* Default to acoustic piano */
-
-	if (voice < 0 || voice > 31)
-		return -EINVAL;
-
-	if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-	{
-		voices[voice].sample_pending = instr_no;
-		return 0;
-	}
-	sample_no = patch_table[instr_no];
-	patch_map[voice] = -1;
-
-	if (sample_no == NOT_SAMPLE)
-	{
-/*		printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);*/
-		return -EINVAL;	/* Patch not defined */
-	}
-	if (sample_ptrs[sample_no] == -1)	/* Sample not loaded */
-	{
-/*		printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);*/
-		return -EINVAL;
-	}
-	sample_map[voice] = sample_no;
-	patch_map[voice] = instr_no;
-	return 0;
-}
-
-static int guswave_kill_note(int dev, int voice, int note, int velocity)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&gus_lock,flags);
-	/* voice_alloc->map[voice] = 0xffff; */
-	if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-	{
-		voices[voice].kill_pending = 1;
-		spin_unlock_irqrestore(&gus_lock,flags);
-	}
-	else
-	{
-		spin_unlock_irqrestore(&gus_lock,flags);
-		gus_voice_fade(voice);
-	}
-
-	return 0;
-}
-
-static void guswave_aftertouch(int dev, int voice, int pressure)
-{
-}
-
-static void guswave_panning(int dev, int voice, int value)
-{
-	if (voice >= 0 || voice < 32)
-		voices[voice].panning = value;
-}
-
-static void guswave_volume_method(int dev, int mode)
-{
-	if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
-		volume_method = mode;
-}
-
-static void compute_volume(int voice, int volume)
-{
-	if (volume < 128)
-		voices[voice].midi_volume = volume;
-
-	switch (volume_method)
-	{
-		case VOL_METHOD_ADAGIO:
-			voices[voice].initial_volume =
-				gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
-					voices[voice].expression_vol,
-					voices[voice].patch_vol);
-			break;
-
-		case VOL_METHOD_LINEAR:	/* Totally ignores patch-volume and expression */
-			voices[voice].initial_volume = gus_linear_vol(volume, voices[voice].main_vol);
-			break;
-
-		default:
-			voices[voice].initial_volume = volume_base +
-				(voices[voice].midi_volume * volume_scale);
-	}
-
-	if (voices[voice].initial_volume > 4030)
-		voices[voice].initial_volume = 4030;
-}
-
-static void compute_and_set_volume(int voice, int volume, int ramp_time)
-{
-	int curr, target, rate;
-	unsigned long flags;
-
-	compute_volume(voice, volume);
-	voices[voice].current_volume = voices[voice].initial_volume;
-
-	spin_lock_irqsave(&gus_lock,flags);
-	/*
-	 * CAUTION! Interrupts disabled. Enable them before returning
-	 */
-
-	gus_select_voice(voice);
-
-	curr = gus_read16(0x09) >> 4;
-	target = voices[voice].initial_volume;
-
-	if (ramp_time == INSTANT_RAMP)
-	{
-		gus_rampoff();
-		gus_voice_volume(target);
-		spin_unlock_irqrestore(&gus_lock,flags);
-		return;
-	}
-	if (ramp_time == FAST_RAMP)
-		rate = 63;
-	else
-		rate = 16;
-	gus_ramp_rate(0, rate);
-
-	if ((target - curr) / 64 == 0)	/* Close enough to target. */
-	{
-		gus_rampoff();
-		gus_voice_volume(target);
-		spin_unlock_irqrestore(&gus_lock,flags);
-		return;
-	}
-	if (target > curr)
-	{
-		if (target > (4095 - 65))
-			target = 4095 - 65;
-		gus_ramp_range(curr, target);
-		gus_rampon(0x00);	/* Ramp up, once, no IRQ */
-	}
-	else
-	{
-		if (target < 65)
-			target = 65;
-
-		gus_ramp_range(target, curr);
-		gus_rampon(0x40);	/* Ramp down, once, no irq */
-	}
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void dynamic_volume_change(int voice)
-{
-	unsigned char status;
-	unsigned long flags;
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-	status = gus_read8(0x00);	/* Get voice status */
-	spin_unlock_irqrestore(&gus_lock,flags);
-
-	if (status & 0x03)
-		return;		/* Voice was not running */
-
-	if (!(voices[voice].mode & WAVE_ENVELOPES))
-	{
-		compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-		return;
-	}
-	
-	/*
-	 * Voice is running and has envelopes.
-	 */
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-	status = gus_read8(0x0d);	/* Ramping status */
-	spin_unlock_irqrestore(&gus_lock,flags);
-
-	if (status & 0x03)	/* Sustain phase? */
-	{
-		compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-		return;
-	}
-	if (voices[voice].env_phase < 0)
-		return;
-
-	compute_volume(voice, voices[voice].midi_volume);
-
-}
-
-static void guswave_controller(int dev, int voice, int ctrl_num, int value)
-{
-	unsigned long   flags;
-	unsigned long   freq;
-
-	if (voice < 0 || voice > 31)
-		return;
-
-	switch (ctrl_num)
-	{
-		case CTRL_PITCH_BENDER:
-			voices[voice].bender = value;
-
-			if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-			{
-				freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0);
-				voices[voice].current_freq = freq;
-
-				spin_lock_irqsave(&gus_lock,flags);
-				gus_select_voice(voice);
-				gus_voice_freq(freq);
-				spin_unlock_irqrestore(&gus_lock,flags);
-			}
-			break;
-
-		case CTRL_PITCH_BENDER_RANGE:
-			voices[voice].bender_range = value;
-			break;
-		case CTL_EXPRESSION:
-			value /= 128;
-		case CTRL_EXPRESSION:
-			if (volume_method == VOL_METHOD_ADAGIO)
-			{
-				voices[voice].expression_vol = value;
-				if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-					dynamic_volume_change(voice);
-			}
-			break;
-
-		case CTL_PAN:
-			voices[voice].panning = (value * 2) - 128;
-			break;
-
-		case CTL_MAIN_VOLUME:
-			value = (value * 100) / 16383;
-
-		case CTRL_MAIN_VOLUME:
-			voices[voice].main_vol = value;
-			if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-				dynamic_volume_change(voice);
-			break;
-
-		default:
-			break;
-	}
-}
-
-static int guswave_start_note2(int dev, int voice, int note_num, int volume)
-{
-	int sample, best_sample, best_delta, delta_freq;
-	int is16bits, samplep, patch, pan;
-	unsigned long   note_freq, base_note, freq, flags;
-	unsigned char   mode = 0;
-
-	if (voice < 0 || voice > 31)
-	{
-/*		printk("GUS: Invalid voice\n");*/
-		return -EINVAL;
-	}
-	if (note_num == 255)
-	{
-		if (voices[voice].mode & WAVE_ENVELOPES)
-		{
-			voices[voice].midi_volume = volume;
-			dynamic_volume_change(voice);
-			return 0;
-		}
-		compute_and_set_volume(voice, volume, 1);
-		return 0;
-	}
-	if ((patch = patch_map[voice]) == -1)
-		return -EINVAL;
-	if ((samplep = patch_table[patch]) == NOT_SAMPLE)
-	{
-		return -EINVAL;
-	}
-	note_freq = note_to_freq(note_num);
-
-	/*
-	 * Find a sample within a patch so that the note_freq is between low_note
-	 * and high_note.
-	 */
-	sample = -1;
-
-	best_sample = samplep;
-	best_delta = 1000000;
-	while (samplep != 0 && samplep != NOT_SAMPLE && sample == -1)
-	{
-		delta_freq = note_freq - samples[samplep].base_note;
-		if (delta_freq < 0)
-			delta_freq = -delta_freq;
-		if (delta_freq < best_delta)
-		{
-			best_sample = samplep;
-			best_delta = delta_freq;
-		}
-		if (samples[samplep].low_note <= note_freq &&
-			note_freq <= samples[samplep].high_note)
-		{
-			sample = samplep;
-		}
-		else
-			samplep = samples[samplep].key;	/* Link to next sample */
-	  }
-	if (sample == -1)
-		sample = best_sample;
-
-	if (sample == -1)
-	{
-/*		printk("GUS: Patch %d not defined for note %d\n", patch, note_num);*/
-		return 0;	/* Should play default patch ??? */
-	}
-	is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
-	voices[voice].mode = samples[sample].mode;
-	voices[voice].patch_vol = samples[sample].volume;
-
-	if (iw_mode)
-		gus_write8(0x15, 0x00);		/* RAM, Reset voice deactivate bit of SMSI */
-
-	if (voices[voice].mode & WAVE_ENVELOPES)
-	{
-		int i;
-
-		for (i = 0; i < 6; i++)
-		{
-			voices[voice].env_rate[i] = samples[sample].env_rate[i];
-			voices[voice].env_offset[i] = samples[sample].env_offset[i];
-		}
-	}
-	sample_map[voice] = sample;
-
-	if (voices[voice].fixed_pitch)	/* Fixed pitch */
-	{
-		  freq = samples[sample].base_freq;
-	}
-	else
-	{
-		base_note = samples[sample].base_note / 100;
-		note_freq /= 100;
-
-		freq = samples[sample].base_freq * note_freq / base_note;
-	}
-
-	voices[voice].orig_freq = freq;
-
-	/*
-	 * Since the pitch bender may have been set before playing the note, we
-	 * have to calculate the bending now.
-	 */
-
-	freq = compute_finetune(voices[voice].orig_freq, voices[voice].bender,
-				voices[voice].bender_range, 0);
-	voices[voice].current_freq = freq;
-
-	pan = (samples[sample].panning + voices[voice].panning) / 32;
-	pan += 7;
-	if (pan < 0)
-		pan = 0;
-	if (pan > 15)
-		pan = 15;
-
-	if (samples[sample].mode & WAVE_16_BITS)
-	{
-		mode |= 0x04;	/* 16 bits */
-		if ((sample_ptrs[sample] / GUS_BANK_SIZE) !=
-			((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
-				printk(KERN_ERR "GUS: Sample address error\n");
-	}
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-	gus_voice_off();
-	gus_rampoff();
-
-	spin_unlock_irqrestore(&gus_lock,flags);
-
-	if (voices[voice].mode & WAVE_ENVELOPES)
-	{
-		compute_volume(voice, volume);
-		init_envelope(voice);
-	}
-	else
-	{
-		compute_and_set_volume(voice, volume, 0);
-	}
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-
-	if (samples[sample].mode & WAVE_LOOP_BACK)
-		gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len -
-			voices[voice].offset_pending, 0, is16bits);	/* start=end */
-	else
-		gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending, 0, is16bits);	/* Sample start=begin */
-
-	if (samples[sample].mode & WAVE_LOOPING)
-	{
-		mode |= 0x08;
-
-		if (samples[sample].mode & WAVE_BIDIR_LOOP)
-			mode |= 0x10;
-
-		if (samples[sample].mode & WAVE_LOOP_BACK)
-		{
-			gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].loop_end -
-					   voices[voice].offset_pending,
-					   (samples[sample].fractions >> 4) & 0x0f, is16bits);
-			mode |= 0x40;
-		}
-		gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
-			samples[sample].fractions & 0x0f, is16bits);	/* Loop start location */
-		gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
-			(samples[sample].fractions >> 4) & 0x0f, is16bits);	/* Loop end location */
-	}
-	else
-	{
-		mode |= 0x20;	/* Loop IRQ at the end */
-		voices[voice].loop_irq_mode = LMODE_FINISH;	/* Ramp down at the end */
-		voices[voice].loop_irq_parm = 1;
-		gus_write_addr(0x02, sample_ptrs[sample], 0, is16bits);	/* Loop start location */
-		gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
-			(samples[sample].fractions >> 4) & 0x0f, is16bits);	/* Loop end location */
-	}
-	gus_voice_freq(freq);
-	gus_voice_balance(pan);
-	gus_voice_on(mode);
-	spin_unlock_irqrestore(&gus_lock,flags);
-
-	return 0;
-}
-
-/*
- * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking
- * when the note playing on the voice is changed.  It uses volume
- * ramping.
- */
-
-static int guswave_start_note(int dev, int voice, int note_num, int volume)
-{
-	unsigned long flags;
-	int mode;
-	int ret_val = 0;
-
-	spin_lock_irqsave(&gus_lock,flags);
-	if (note_num == 255)
-	{
-		if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-		{
-			voices[voice].volume_pending = volume;
-		}
-		else
-		{
-			ret_val = guswave_start_note2(dev, voice, note_num, volume);
-		}
-	}
-	else
-	{
-		gus_select_voice(voice);
-		mode = gus_read8(0x00);
-		if (mode & 0x20)
-			gus_write8(0x00, mode & 0xdf);	/* No interrupt! */
-
-		voices[voice].offset_pending = 0;
-		voices[voice].kill_pending = 0;
-		voices[voice].volume_irq_mode = 0;
-		voices[voice].loop_irq_mode = 0;
-
-		if (voices[voice].sample_pending >= 0)
-		{
-			spin_unlock_irqrestore(&gus_lock,flags);	/* Run temporarily with interrupts enabled */
-			guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending);
-			voices[voice].sample_pending = -1;
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);	/* Reselect the voice (just to be sure) */
-		}
-		if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
-		{
-			ret_val = guswave_start_note2(dev, voice, note_num, volume);
-		}
-		else
-		{
-			voices[voice].dev_pending = dev;
-			voices[voice].note_pending = note_num;
-			voices[voice].volume_pending = volume;
-			voices[voice].volume_irq_mode = VMODE_START_NOTE;
-
-			gus_rampoff();
-			gus_ramp_range(2000, 4065);
-			gus_ramp_rate(0, 63);	/* Fastest possible rate */
-			gus_rampon(0x20 | 0x40);	/* Ramp down, once, irq */
-		}
-	}
-	spin_unlock_irqrestore(&gus_lock,flags);
-	return ret_val;
-}
-
-static void guswave_reset(int dev)
-{
-	int i;
-
-	for (i = 0; i < 32; i++)
-	{
-		gus_voice_init(i);
-		gus_voice_init2(i);
-	}
-}
-
-static int guswave_open(int dev, int mode)
-{
-	int err;
-
-	if (gus_busy)
-		return -EBUSY;
-
-	voice_alloc->timestamp = 0;
-
-	if (gus_no_wave_dma) {
-		gus_no_dma = 1;
-	} else {
-		if ((err = DMAbuf_open_dma(gus_devnum)) < 0)
-		{
-			/* printk( "GUS: Loading samples without DMA\n"); */
-			gus_no_dma = 1;	/* Upload samples using PIO */
-		}
-		else
-			gus_no_dma = 0;
-	}
-
-	init_waitqueue_head(&dram_sleeper);
-	gus_busy = 1;
-	active_device = GUS_DEV_WAVE;
-
-	gusintr(gus_irq, (void *)gus_hw_config, NULL);	/* Serve pending interrupts */
-	gus_initialize();
-	gus_reset();
-	gusintr(gus_irq, (void *)gus_hw_config, NULL);	/* Serve pending interrupts */
-
-	return 0;
-}
-
-static void guswave_close(int dev)
-{
-	gus_busy = 0;
-	active_device = 0;
-	gus_reset();
-
-	if (!gus_no_dma)
-		DMAbuf_close_dma(gus_devnum);
-}
-
-static int guswave_load_patch(int dev, int format, const char __user *addr,
-		   int offs, int count, int pmgr_flag)
-{
-	struct patch_info patch;
-	int instr;
-	long sizeof_patch;
-
-	unsigned long blk_sz, blk_end, left, src_offs, target;
-
-	sizeof_patch = (long) &patch.data[0] - (long) &patch;	/* Header size */
-
-	if (format != GUS_PATCH)
-	{
-/*		printk("GUS Error: Invalid patch format (key) 0x%x\n", format);*/
-		return -EINVAL;
-	}
-	if (count < sizeof_patch)
-	{
-/*		  printk("GUS Error: Patch header too short\n");*/
-		  return -EINVAL;
-	}
-	count -= sizeof_patch;
-
-	if (free_sample >= MAX_SAMPLE)
-	{
-/*		  printk("GUS: Sample table full\n");*/
-		  return -ENOSPC;
-	}
-	/*
-	 * Copy the header from user space but ignore the first bytes which have
-	 * been transferred already.
-	 */
-
-	if (copy_from_user(&((char *) &patch)[offs], &(addr)[offs],
-			   sizeof_patch - offs))
-		return -EFAULT;
-
-	if (patch.mode & WAVE_ROM)
-		return -EINVAL;
-	if (gus_mem_size == 0)
-		return -ENOSPC;
-
-	instr = patch.instr_no;
-
-	if (instr < 0 || instr > MAX_PATCH)
-	{
-/*		printk(KERN_ERR "GUS: Invalid patch number %d\n", instr);*/
-		return -EINVAL;
-	}
-	if (count < patch.len)
-	{
-/*		printk(KERN_ERR "GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);*/
-		patch.len = count;
-	}
-	if (patch.len <= 0 || patch.len > gus_mem_size)
-	{
-/*		printk(KERN_ERR "GUS: Invalid sample length %d\n", (int) patch.len);*/
-		return -EINVAL;
-	}
-	if (patch.mode & WAVE_LOOPING)
-	{
-		if (patch.loop_start < 0 || patch.loop_start >= patch.len)
-		{
-/*			printk(KERN_ERR "GUS: Invalid loop start\n");*/
-			return -EINVAL;
-		}
-		if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
-		{
-/*			printk(KERN_ERR "GUS: Invalid loop end\n");*/
-			return -EINVAL;
-		}
-	}
-	free_mem_ptr = (free_mem_ptr + 31) & ~31;	/* 32 byte alignment */
-
-	if (patch.mode & WAVE_16_BITS)
-	{
-		/*
-		 * 16 bit samples must fit one 256k bank.
-		 */
-		if (patch.len >= GUS_BANK_SIZE)
-		{
-/*			 printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);*/
-			return -ENOSPC;
-		}
-		if ((free_mem_ptr / GUS_BANK_SIZE) !=
-			((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
-		{
-			unsigned long   tmp_mem =	
-				/* Align to 256K */
-					((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
-
-			if ((tmp_mem + patch.len) > gus_mem_size)
-				return -ENOSPC;
-
-			free_mem_ptr = tmp_mem;		/* This leaves unusable memory */
-		}
-	}
-	if ((free_mem_ptr + patch.len) > gus_mem_size)
-		return -ENOSPC;
-
-	sample_ptrs[free_sample] = free_mem_ptr;
-
-	/*
-	 * Tremolo is not possible with envelopes
-	 */
-
-	if (patch.mode & WAVE_ENVELOPES)
-		patch.mode &= ~WAVE_TREMOLO;
-
-	if (!(patch.mode & WAVE_FRACTIONS))
-	{
-		  patch.fractions = 0;
-	}
-	memcpy((char *) &samples[free_sample], &patch, sizeof_patch);
-
-	/*
-	 * Link this_one sample to the list of samples for patch 'instr'.
-	 */
-
-	samples[free_sample].key = patch_table[instr];
-	patch_table[instr] = free_sample;
-
-	/*
-	 * Use DMA to transfer the wave data to the DRAM
-	 */
-
-	left = patch.len;
-	src_offs = 0;
-	target = free_mem_ptr;
-
-	while (left)		/* Not completely transferred yet */
-	{
-		blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
-		if (blk_sz > left)
-			blk_sz = left;
-
-		/*
-		 * DMA cannot cross bank (256k) boundaries. Check for that.
-		 */
-		 
-		blk_end = target + blk_sz;
-
-		if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE))
-		{
-			/* Split the block */
-			blk_end &= ~(GUS_BANK_SIZE - 1);
-			blk_sz = blk_end - target;
-		}
-		if (gus_no_dma)
-		{
-			/*
-			 * For some reason the DMA is not possible. We have to use PIO.
-			 */
-			long i;
-			unsigned char data;
-
-			for (i = 0; i < blk_sz; i++)
-			{
-				get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[sizeof_patch + i]));
-				if (patch.mode & WAVE_UNSIGNED)
-					if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
-						data ^= 0x80;	/* Convert to signed */
-				gus_poke(target + i, data);
-			}
-		}
-		else
-		{
-			unsigned long address, hold_address;
-			unsigned char dma_command;
-			unsigned long flags;
-
-			if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL)
-			{
-				printk(KERN_ERR "GUS: DMA buffer == NULL\n");
-				return -ENOSPC;
-			}
-			/*
-			 * OK, move now. First in and then out.
-			 */
-
-			if (copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf,
-					   &(addr)[sizeof_patch + src_offs],
-					   blk_sz))
-				return -EFAULT;
-
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_write8(0x41, 0);	/* Disable GF1 DMA */
-			DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
-				blk_sz, DMA_MODE_WRITE);
-
-			/*
-			 * Set the DRAM address for the wave data
-			 */
-
-			if (iw_mode)
-			{
-				/* Different address translation in enhanced mode */
-
-				unsigned char   hi;
-
-				if (gus_dma > 4)
-					address = target >> 1;	/* Convert to 16 bit word address */
-				else
-					address = target;
-
-				hi = (unsigned char) ((address >> 16) & 0xf0);
-				hi += (unsigned char) (address & 0x0f);
-
-				gus_write16(0x42, (address >> 4) & 0xffff);	/* DMA address (low) */
-				gus_write8(0x50, hi);
-			}
-			else
-			{
-				address = target;
-				if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-				{
-					hold_address = address;
-					address = address >> 1;
-					address &= 0x0001ffffL;
-					address |= (hold_address & 0x000c0000L);
-				}
-				gus_write16(0x42, (address >> 4) & 0xffff);	/* DRAM DMA address */
-			}
-
-			/*
-			 * Start the DMA transfer
-			 */
-
-			dma_command = 0x21;		/* IRQ enable, DMA start */
-			if (patch.mode & WAVE_UNSIGNED)
-				dma_command |= 0x80;	/* Invert MSB */
-			if (patch.mode & WAVE_16_BITS)
-				dma_command |= 0x40;	/* 16 bit _DATA_ */
-			if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-				dma_command |= 0x04;	/* 16 bit DMA _channel_ */
-			
-			/*
-			 * Sleep here until the DRAM DMA done interrupt is served
-			 */
-			active_device = GUS_DEV_WAVE;
-			gus_write8(0x41, dma_command);	/* Lets go luteet (=bugs) */
-
-			spin_unlock_irqrestore(&gus_lock,flags); /* opens a race */
-			if (!interruptible_sleep_on_timeout(&dram_sleeper, HZ))
-				printk("GUS: DMA Transfer timed out\n");
-		}
-
-		/*
-		 * Now the next part
-		 */
-
-		left -= blk_sz;
-		src_offs += blk_sz;
-		target += blk_sz;
-
-		gus_write8(0x41, 0);	/* Stop DMA */
-	}
-
-	free_mem_ptr += patch.len;
-	free_sample++;
-	return 0;
-}
-
-static void guswave_hw_control(int dev, unsigned char *event_rec)
-{
-	int voice, cmd;
-	unsigned short p1, p2;
-	unsigned int plong;
-	unsigned long flags;
-
-	cmd = event_rec[2];
-	voice = event_rec[3];
-	p1 = *(unsigned short *) &event_rec[4];
-	p2 = *(unsigned short *) &event_rec[6];
-	plong = *(unsigned int *) &event_rec[4];
-
-	if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
-		(cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
-		do_volume_irq(voice);
-
-	switch (cmd)
-	{
-		case _GUS_NUMVOICES:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_select_max_voices(p1);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOICESAMPLE:
-			guswave_set_instr(dev, voice, p1);
-			break;
-
-		case _GUS_VOICEON:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			p1 &= ~0x20;	/* Don't allow interrupts */
-			gus_voice_on(p1);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOICEOFF:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_voice_off();
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOICEFADE:
-			gus_voice_fade(voice);
-			break;
-
-		case _GUS_VOICEMODE:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			p1 &= ~0x20;	/* Don't allow interrupts */
-			gus_voice_mode(p1);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOICEBALA:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_voice_balance(p1);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOICEFREQ:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_voice_freq(plong);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOICEVOL:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_voice_volume(p1);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOICEVOL2:	/* Just update the software voice level */
-			voices[voice].initial_volume = voices[voice].current_volume = p1;
-			break;
-
-		case _GUS_RAMPRANGE:
-			if (voices[voice].mode & WAVE_ENVELOPES)
-				break;	/* NO-NO */
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_ramp_range(p1, p2);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_RAMPRATE:
-			if (voices[voice].mode & WAVE_ENVELOPES)
-				break;	/* NJET-NJET */
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_ramp_rate(p1, p2);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_RAMPMODE:
-			if (voices[voice].mode & WAVE_ENVELOPES)
-				break;	/* NO-NO */
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			p1 &= ~0x20;	/* Don't allow interrupts */
-			gus_ramp_mode(p1);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_RAMPON:
-			if (voices[voice].mode & WAVE_ENVELOPES)
-				break;	/* EI-EI */
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			p1 &= ~0x20;	/* Don't allow interrupts */
-			gus_rampon(p1);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_RAMPOFF:
-			if (voices[voice].mode & WAVE_ENVELOPES)
-				break;	/* NEJ-NEJ */
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_rampoff();
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		case _GUS_VOLUME_SCALE:
-			volume_base = p1;
-			volume_scale = p2;
-			break;
-
-		case _GUS_VOICE_POS:
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_set_voice_pos(voice, plong);
-			spin_unlock_irqrestore(&gus_lock,flags);
-			break;
-
-		default:
-			break;
-	}
-}
-
-static int gus_audio_set_speed(int speed)
-{
-	if (speed <= 0)
-		speed = gus_audio_speed;
-
-	if (speed < 4000)
-		speed = 4000;
-
-	if (speed > 44100)
-		speed = 44100;
-
-	gus_audio_speed = speed;
-
-	if (only_read_access)
-	{
-		/* Compute nearest valid recording speed  and return it */
-
-		/* speed = (9878400 / (gus_audio_speed + 2)) / 16; */
-		speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
-		speed = (9878400 / (speed * 16)) - 2;
-	}
-	return speed;
-}
-
-static int gus_audio_set_channels(int channels)
-{
-	if (!channels)
-		return gus_audio_channels;
-	if (channels > 2)
-		channels = 2;
-	if (channels < 1)
-		channels = 1;
-	gus_audio_channels = channels;
-	return channels;
-}
-
-static int gus_audio_set_bits(int bits)
-{
-	if (!bits)
-		return gus_audio_bits;
-
-	if (bits != 8 && bits != 16)
-		bits = 8;
-
-	if (only_8_bits)
-		bits = 8;
-
-	gus_audio_bits = bits;
-	return bits;
-}
-
-static int gus_audio_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-	int val;
-
-	switch (cmd) 
-	{
-		case SOUND_PCM_WRITE_RATE:
-			if (get_user(val, (int __user*)arg))
-				return -EFAULT;
-			val = gus_audio_set_speed(val);
-			break;
-
-		case SOUND_PCM_READ_RATE:
-			val = gus_audio_speed;
-			break;
-
-		case SNDCTL_DSP_STEREO:
-			if (get_user(val, (int __user *)arg))
-				return -EFAULT;
-			val = gus_audio_set_channels(val + 1) - 1;
-			break;
-
-		case SOUND_PCM_WRITE_CHANNELS:
-			if (get_user(val, (int __user *)arg))
-				return -EFAULT;
-			val = gus_audio_set_channels(val);
-			break;
-
-		case SOUND_PCM_READ_CHANNELS:
-			val = gus_audio_channels;
-			break;
-		
-		case SNDCTL_DSP_SETFMT:
-			if (get_user(val, (int __user *)arg))
-				return -EFAULT;
-			val = gus_audio_set_bits(val);
-			break;
-		
-		case SOUND_PCM_READ_BITS:
-			val = gus_audio_bits;
-			break;
-		
-		case SOUND_PCM_WRITE_FILTER:		/* NOT POSSIBLE */
-		case SOUND_PCM_READ_FILTER:
-			val = -EINVAL;
-			break;
-		default:
-			return -EINVAL;
-	}
-	return put_user(val, (int __user *)arg);
-}
-
-static void gus_audio_reset(int dev)
-{
-	if (recording_active)
-	{
-		gus_write8(0x49, 0x00);	/* Halt recording */
-		set_input_volumes();
-	}
-}
-
-static int saved_iw_mode;	/* A hack hack hack */
-
-static int gus_audio_open(int dev, int mode)
-{
-	if (gus_busy)
-		return -EBUSY;
-
-	if (gus_pnp_flag && mode & OPEN_READ)
-	{
-/*		printk(KERN_ERR "GUS: Audio device #%d is playback only.\n", dev);*/
-		return -EIO;
-	}
-	gus_initialize();
-
-	gus_busy = 1;
-	active_device = 0;
-
-	saved_iw_mode = iw_mode;
-	if (iw_mode)
-	{
-		/* There are some problems with audio in enhanced mode so disable it */
-		gus_write8(0x19, gus_read8(0x19) & ~0x01);	/* Disable enhanced mode */
-		iw_mode = 0;
-	}
-
-	gus_reset();
-	reset_sample_memory();
-	gus_select_max_voices(14);
-
-	pcm_active = 0;
-	dma_active = 0;
-	pcm_opened = 1;
-	if (mode & OPEN_READ)
-	{
-		recording_active = 1;
-		set_input_volumes();
-	}
-	only_read_access = !(mode & OPEN_WRITE);
-	only_8_bits = mode & OPEN_READ;
-	if (only_8_bits)
-		audio_devs[dev]->format_mask = AFMT_U8;
-	else
-		audio_devs[dev]->format_mask = AFMT_U8 | AFMT_S16_LE;
-
-	return 0;
-}
-
-static void gus_audio_close(int dev)
-{
-	iw_mode = saved_iw_mode;
-	gus_reset();
-	gus_busy = 0;
-	pcm_opened = 0;
-	active_device = 0;
-
-	if (recording_active)
-	{
-		gus_write8(0x49, 0x00);	/* Halt recording */
-		set_input_volumes();
-	}
-	recording_active = 0;
-}
-
-static void gus_audio_update_volume(void)
-{
-	unsigned long flags;
-	int voice;
-
-	if (pcm_active && pcm_opened)
-		for (voice = 0; voice < gus_audio_channels; voice++)
-		{
-			spin_lock_irqsave(&gus_lock,flags);
-			gus_select_voice(voice);
-			gus_rampoff();
-			gus_voice_volume(1530 + (25 * gus_pcm_volume));
-			gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-			spin_unlock_irqrestore(&gus_lock,flags);
-		}
-}
-
-static void play_next_pcm_block(void)
-{
-	unsigned long flags;
-	int speed = gus_audio_speed;
-	int this_one, is16bits, chn;
-	unsigned long dram_loc;
-	unsigned char mode[2], ramp_mode[2];
-
-	if (!pcm_qlen)
-		return;
-
-	this_one = pcm_head;
-
-	for (chn = 0; chn < gus_audio_channels; chn++)
-	{
-		mode[chn] = 0x00;
-		ramp_mode[chn] = 0x03;	/* Ramping and rollover off */
-
-		if (chn == 0)
-		{
-			mode[chn] |= 0x20;	/* Loop IRQ */
-			voices[chn].loop_irq_mode = LMODE_PCM;
-		}
-		if (gus_audio_bits != 8)
-		{
-			is16bits = 1;
-			mode[chn] |= 0x04;	/* 16 bit data */
-		}
-		else
-			is16bits = 0;
-
-		dram_loc = this_one * pcm_bsize;
-		dram_loc += chn * pcm_banksize;
-
-		if (this_one == (pcm_nblk - 1))	/* Last fragment of the DRAM buffer */
-		{
-			mode[chn] |= 0x08;	/* Enable loop */
-			ramp_mode[chn] = 0x03;	/* Disable rollover bit */
-		}
-		else
-		{
-			if (chn == 0)
-				ramp_mode[chn] = 0x04;	/* Enable rollover bit */
-		}
-		spin_lock_irqsave(&gus_lock,flags);
-		gus_select_voice(chn);
-		gus_voice_freq(speed);
-
-		if (gus_audio_channels == 1)
-			gus_voice_balance(7);		/* mono */
-		else if (chn == 0)
-			gus_voice_balance(0);		/* left */
-		else
-			gus_voice_balance(15);		/* right */
-
-		if (!pcm_active)	/* Playback not already active */
-		{
-			/*
-			 * The playback was not started yet (or there has been a pause).
-			 * Start the voice (again) and ask for a rollover irq at the end of
-			 * this_one block. If this_one one is last of the buffers, use just
-			 * the normal loop with irq.
-			 */
-
-			gus_voice_off();
-			gus_rampoff();
-			gus_voice_volume(1530 + (25 * gus_pcm_volume));
-			gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-
-			gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits);	/* Starting position */
-			gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits);	/* Loop start */
-
-			if (chn != 0)
-				gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
-						   0, is16bits);	/* Loop end location */
-		}
-		if (chn == 0)
-			gus_write_addr(0x04, dram_loc + pcm_bsize - 1,
-					 0, is16bits);	/* Loop end location */
-		else
-			mode[chn] |= 0x08;	/* Enable looping */
-		spin_unlock_irqrestore(&gus_lock,flags);
-	}
-	for (chn = 0; chn < gus_audio_channels; chn++)
-	{
-		spin_lock_irqsave(&gus_lock,flags);
-		gus_select_voice(chn);
-		gus_write8(0x0d, ramp_mode[chn]);
-		if (iw_mode)
-			gus_write8(0x15, 0x00);	/* Reset voice deactivate bit of SMSI */
-		gus_voice_on(mode[chn]);
-		spin_unlock_irqrestore(&gus_lock,flags);
-	}
-	pcm_active = 1;
-}
-
-static void gus_transfer_output_block(int dev, unsigned long buf,
-			  int total_count, int intrflag, int chn)
-{
-	/*
-	 * This routine transfers one block of audio data to the DRAM. In mono mode
-	 * it's called just once. When in stereo mode, this_one routine is called
-	 * once for both channels.
-	 *
-	 * The left/mono channel data is transferred to the beginning of dram and the
-	 * right data to the area pointed by gus_page_size.
-	 */
-
-	int this_one, count;
-	unsigned long flags;
-	unsigned char dma_command;
-	unsigned long address, hold_address;
-
-	spin_lock_irqsave(&gus_lock,flags);
-
-	count = total_count / gus_audio_channels;
-
-	if (chn == 0)
-	{
-		if (pcm_qlen >= pcm_nblk)
-			printk(KERN_WARNING "GUS Warning: PCM buffers out of sync\n");
-
-		this_one = pcm_current_block = pcm_tail;
-		pcm_qlen++;
-		pcm_tail = (pcm_tail + 1) % pcm_nblk;
-		pcm_datasize[this_one] = count;
-	}
-	else
-		this_one = pcm_current_block;
-
-	gus_write8(0x41, 0);	/* Disable GF1 DMA */
-	DMAbuf_start_dma(dev, buf + (chn * count), count, DMA_MODE_WRITE);
-
-	address = this_one * pcm_bsize;
-	address += chn * pcm_banksize;
-
-	if (audio_devs[dev]->dmap_out->dma > 3)
-	{
-		hold_address = address;
-		address = address >> 1;
-		address &= 0x0001ffffL;
-		address |= (hold_address & 0x000c0000L);
-	}
-	gus_write16(0x42, (address >> 4) & 0xffff);	/* DRAM DMA address */
-
-	dma_command = 0x21;	/* IRQ enable, DMA start */
-
-	if (gus_audio_bits != 8)
-		dma_command |= 0x40;	/* 16 bit _DATA_ */
-	else
-		dma_command |= 0x80;	/* Invert MSB */
-
-	if (audio_devs[dev]->dmap_out->dma > 3)
-		dma_command |= 0x04;	/* 16 bit DMA channel */
-
-	gus_write8(0x41, dma_command);	/* Kick start */
-
-	if (chn == (gus_audio_channels - 1))	/* Last channel */
-	{
-		/*
-		 * Last (right or mono) channel data
-		 */
-		dma_active = 1;	/* DMA started. There is a unacknowledged buffer */
-		active_device = GUS_DEV_PCM_DONE;
-		if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize))
-		{
-			play_next_pcm_block();
-		}
-	}
-	else
-	{
-		/*
-		 * Left channel data. The right channel
-		 * is transferred after DMA interrupt
-		 */
-		active_device = GUS_DEV_PCM_CONTINUE;
-	}
-
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void gus_uninterleave8(char *buf, int l)
-{
-/* This routine uninterleaves 8 bit stereo output (LRLRLR->LLLRRR) */
-	int i, p = 0, halfsize = l / 2;
-	char *buf2 = buf + halfsize, *src = bounce_buf;
-
-	memcpy(bounce_buf, buf, l);
-
-	for (i = 0; i < halfsize; i++)
-	{
-		buf[i] = src[p++];	/* Left channel */
-		buf2[i] = src[p++];	/* Right channel */
-	}
-}
-
-static void gus_uninterleave16(short *buf, int l)
-{
-/* This routine uninterleaves 16 bit stereo output (LRLRLR->LLLRRR) */
-	int i, p = 0, halfsize = l / 2;
-	short *buf2 = buf + halfsize, *src = (short *) bounce_buf;
-
-	memcpy(bounce_buf, (char *) buf, l * 2);
-
-	for (i = 0; i < halfsize; i++)
-	{
-		buf[i] = src[p++];	/* Left channel */
-		buf2[i] = src[p++];	/* Right channel */
-	}
-}
-
-static void gus_audio_output_block(int dev, unsigned long buf, int total_count,
-		       int intrflag)
-{
-	struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
-
-	dmap->flags |= DMA_NODMA | DMA_NOTIMEOUT;
-
-	pcm_current_buf = buf;
-	pcm_current_count = total_count;
-	pcm_current_intrflag = intrflag;
-	pcm_current_dev = dev;
-	if (gus_audio_channels == 2)
-	{
-		char *b = dmap->raw_buf + (buf - dmap->raw_buf_phys);
-
-		if (gus_audio_bits == 8)
-			gus_uninterleave8(b, total_count);
-		else
-			gus_uninterleave16((short *) b, total_count / 2);
-	}
-	gus_transfer_output_block(dev, buf, total_count, intrflag, 0);
-}
-
-static void gus_audio_start_input(int dev, unsigned long buf, int count,
-		      int intrflag)
-{
-	unsigned long flags;
-	unsigned char mode;
-
-	spin_lock_irqsave(&gus_lock,flags);
-
-	DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ);
-	mode = 0xa0;		/* DMA IRQ enabled, invert MSB */
-
-	if (audio_devs[dev]->dmap_in->dma > 3)
-		mode |= 0x04;	/* 16 bit DMA channel */
-	if (gus_audio_channels > 1)
-		mode |= 0x02;	/* Stereo */
-	mode |= 0x01;		/* DMA enable */
-
-	gus_write8(0x49, mode);
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int gus_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
-	unsigned int rate;
-
-	gus_audio_bsize = bsize;
-	audio_devs[dev]->dmap_in->flags |= DMA_NODMA;
-	rate = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
-
-	gus_write8(0x48, rate & 0xff);	/* Set sampling rate */
-
-	if (gus_audio_bits != 8)
-	{
-/*		printk("GUS Error: 16 bit recording not supported\n");*/
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int gus_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
-	int i;
-
-	long mem_ptr, mem_size;
-
-	audio_devs[dev]->dmap_out->flags |= DMA_NODMA | DMA_NOTIMEOUT;
-	mem_ptr = 0;
-	mem_size = gus_mem_size / gus_audio_channels;
-
-	if (mem_size > (256 * 1024))
-		mem_size = 256 * 1024;
-
-	pcm_bsize = bsize / gus_audio_channels;
-	pcm_head = pcm_tail = pcm_qlen = 0;
-
-	pcm_nblk = 2;		/* MAX_PCM_BUFFERS; */
-	if ((pcm_bsize * pcm_nblk) > mem_size)
-		pcm_nblk = mem_size / pcm_bsize;
-
-	for (i = 0; i < pcm_nblk; i++)
-		pcm_datasize[i] = 0;
-
-	pcm_banksize = pcm_nblk * pcm_bsize;
-
-	if (gus_audio_bits != 8 && pcm_banksize == (256 * 1024))
-		pcm_nblk--;
-	gus_write8(0x41, 0);	/* Disable GF1 DMA */
-	return 0;
-}
-
-static int gus_local_qlen(int dev)
-{
-	return pcm_qlen;
-}
-
-
-static struct audio_driver gus_audio_driver =
-{
-	.owner			= THIS_MODULE,
-	.open			= gus_audio_open,
-	.close			= gus_audio_close,
-	.output_block		= gus_audio_output_block,
-	.start_input		= gus_audio_start_input,
-	.ioctl			= gus_audio_ioctl,
-	.prepare_for_input	= gus_audio_prepare_for_input,
-	.prepare_for_output	= gus_audio_prepare_for_output,
-	.halt_io		= gus_audio_reset,
-	.local_qlen		= gus_local_qlen,
-};
-
-static void guswave_setup_voice(int dev, int voice, int chn)
-{
-	struct channel_info *info = &synth_devs[dev]->chn_info[chn];
-
-	guswave_set_instr(dev, voice, info->pgm_num);
-	voices[voice].expression_vol = info->controllers[CTL_EXPRESSION];	/* Just MSB */
-	voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
-	voices[voice].panning = (info->controllers[CTL_PAN] * 2) - 128;
-	voices[voice].bender = 0;
-	voices[voice].bender_range = info->bender_range;
-
-	if (chn == 9)
-		voices[voice].fixed_pitch = 1;
-}
-
-static void guswave_bender(int dev, int voice, int value)
-{
-	int freq;
-	unsigned long   flags;
-
-	voices[voice].bender = value - 8192;
-	freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0);
-	voices[voice].current_freq = freq;
-
-	spin_lock_irqsave(&gus_lock,flags);
-	gus_select_voice(voice);
-	gus_voice_freq(freq);
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
-	int i, p, best = -1, best_time = 0x7fffffff;
-
-	p = alloc->ptr;
-	/*
-	 * First look for a completely stopped voice
-	 */
-
-	for (i = 0; i < alloc->max_voice; i++)
-	{
-		if (alloc->map[p] == 0)
-		{
-			alloc->ptr = p;
-			return p;
-		}
-		if (alloc->alloc_times[p] < best_time)
-		{
-			best = p;
-			best_time = alloc->alloc_times[p];
-		}
-		p = (p + 1) % alloc->max_voice;
-	}
-
-	/*
-	 * Then look for a releasing voice
-	 */
-
-	for (i = 0; i < alloc->max_voice; i++)
-	{
-		if (alloc->map[p] == 0xffff)
-		{
-			alloc->ptr = p;
-			return p;
-		}
-		p = (p + 1) % alloc->max_voice;
-	}
-	if (best >= 0)
-		p = best;
-
-	alloc->ptr = p;
-	return p;
-}
-
-static struct synth_operations guswave_operations =
-{
-	.owner		= THIS_MODULE,
-	.id		= "GUS",
-	.info		= &gus_info,
-	.midi_dev	= 0,
-	.synth_type	= SYNTH_TYPE_SAMPLE,
-	.synth_subtype	= SAMPLE_TYPE_GUS,
-	.open		= guswave_open,
-	.close		= guswave_close,
-	.ioctl		= guswave_ioctl,
-	.kill_note	= guswave_kill_note,
-	.start_note	= guswave_start_note,
-	.set_instr	= guswave_set_instr,
-	.reset		= guswave_reset,
-	.hw_control	= guswave_hw_control,
-	.load_patch	= guswave_load_patch,
-	.aftertouch	= guswave_aftertouch,
-	.controller	= guswave_controller,
-	.panning	= guswave_panning,
-	.volume_method	= guswave_volume_method,
-	.bender		= guswave_bender,
-	.alloc_voice	= guswave_alloc,
-	.setup_voice	= guswave_setup_voice
-};
-
-static void set_input_volumes(void)
-{
-	unsigned long flags;
-	unsigned char mask = 0xff & ~0x06;	/* Just line out enabled */
-
-	if (have_gus_max)	/* Don't disturb GUS MAX */
-		return;
-
-	spin_lock_irqsave(&gus_lock,flags);
-
-	/*
-	 *    Enable channels having vol > 10%
-	 *      Note! bit 0x01 means the line in DISABLED while 0x04 means
-	 *            the mic in ENABLED.
-	 */
-	if (gus_line_vol > 10)
-		mask &= ~0x01;
-	if (gus_mic_vol > 10)
-		mask |= 0x04;
-
-	if (recording_active)
-	{
-		/*
-		 *    Disable channel, if not selected for recording
-		 */
-		if (!(gus_recmask & SOUND_MASK_LINE))
-			mask |= 0x01;
-		if (!(gus_recmask & SOUND_MASK_MIC))
-			mask &= ~0x04;
-	}
-	mix_image &= ~0x07;
-	mix_image |= mask & 0x07;
-	outb((mix_image), u_Mixer);
-
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-#define MIX_DEVS	(SOUND_MASK_MIC|SOUND_MASK_LINE| \
-			 SOUND_MASK_SYNTH|SOUND_MASK_PCM)
-
-int gus_default_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-	int vol, val;
-
-	if (((cmd >> 8) & 0xff) != 'M')
-		return -EINVAL;
-
-	if (!access_ok(VERIFY_WRITE, arg, sizeof(int)))
-		return -EFAULT;
-
-	if (_SIOC_DIR(cmd) & _SIOC_WRITE) 
-	{
-		if (__get_user(val, (int __user *) arg))
-			return -EFAULT;
-
-		switch (cmd & 0xff) 
-		{
-			case SOUND_MIXER_RECSRC:
-				gus_recmask = val & MIX_DEVS;
-				if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
-					gus_recmask = SOUND_MASK_MIC;
-				/* Note! Input volumes are updated during next open for recording */
-				val = gus_recmask;
-				break;
-
-			case SOUND_MIXER_MIC:
-				vol = val & 0xff;
-				if (vol < 0)
-					vol = 0;
-				if (vol > 100)
-					vol = 100;
-				gus_mic_vol = vol;
-				set_input_volumes();
-				val = vol | (vol << 8);
-				break;
-				
-			case SOUND_MIXER_LINE:
-				vol = val & 0xff;
-				if (vol < 0)
-					vol = 0;
-				if (vol > 100)
-					vol = 100;
-				gus_line_vol = vol;
-				set_input_volumes();
-				val = vol | (vol << 8);
-				break;
-
-			case SOUND_MIXER_PCM:
-				gus_pcm_volume = val & 0xff;
-				if (gus_pcm_volume < 0)
-					gus_pcm_volume = 0;
-				if (gus_pcm_volume > 100)
-					gus_pcm_volume = 100;
-				gus_audio_update_volume();
-				val = gus_pcm_volume | (gus_pcm_volume << 8);
-				break;
-
-			case SOUND_MIXER_SYNTH:
-				gus_wave_volume = val & 0xff;
-				if (gus_wave_volume < 0)
-					gus_wave_volume = 0;
-				if (gus_wave_volume > 100)
-					gus_wave_volume = 100;
-				if (active_device == GUS_DEV_WAVE) 
-				{
-					int voice;
-					for (voice = 0; voice < nr_voices; voice++)
-					dynamic_volume_change(voice);	/* Apply the new vol */
-				}
-				val = gus_wave_volume | (gus_wave_volume << 8);
-				break;
-
-			default:
-				return -EINVAL;
-		}
-	}
-	else
-	{
-		switch (cmd & 0xff) 
-		{
-			/*
-			 * Return parameters
-			 */
-			case SOUND_MIXER_RECSRC:
-				val = gus_recmask;
-				break;
-					
-			case SOUND_MIXER_DEVMASK:
-				val = MIX_DEVS;
-				break;
-
-			case SOUND_MIXER_STEREODEVS:
-				val = 0;
-				break;
-
-			case SOUND_MIXER_RECMASK:
-				val = SOUND_MASK_MIC | SOUND_MASK_LINE;
-				break;
-
-			case SOUND_MIXER_CAPS:
-				val = 0;
-				break;
-
-			case SOUND_MIXER_MIC:
-				val = gus_mic_vol | (gus_mic_vol << 8);
-				break;
-
-			case SOUND_MIXER_LINE:
-				val = gus_line_vol | (gus_line_vol << 8);
-				break;
-
-			case SOUND_MIXER_PCM:
-				val = gus_pcm_volume | (gus_pcm_volume << 8);
-				break;
-
-			case SOUND_MIXER_SYNTH:
-				val = gus_wave_volume | (gus_wave_volume << 8);
-				break;
-
-			default:
-				return -EINVAL;
-		}
-	}
-	return __put_user(val, (int __user *)arg);
-}
-
-static struct mixer_operations gus_mixer_operations =
-{
-	.owner	= THIS_MODULE,
-	.id	= "GUS",
-	.name	= "Gravis Ultrasound",
-	.ioctl	= gus_default_mixer_ioctl
-};
-
-static int __init gus_default_mixer_init(void)
-{
-	int n;
-
-	if ((n = sound_alloc_mixerdev()) != -1)
-	{	
-		/*
-		 * Don't install if there is another
-		 * mixer
-		 */
-		mixer_devs[n] = &gus_mixer_operations;
-	}
-	if (have_gus_max)
-	{
-		/*
-		 *  Enable all mixer channels on the GF1 side. Otherwise recording will
-		 *  not be possible using GUS MAX.
-		 */
-		mix_image &= ~0x07;
-		mix_image |= 0x04;	/* All channels enabled */
-		outb((mix_image), u_Mixer);
-	}
-	return n;
-}
-
-void __init gus_wave_init(struct address_info *hw_config)
-{
-	unsigned long flags;
-	unsigned char val;
-	char *model_num = "2.4";
-	char tmp[64];
-	int gus_type = 0x24;	/* 2.4 */
-
-	int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
-	int sdev;
-
-	hw_config->slots[0] = -1;	/* No wave */
-	hw_config->slots[1] = -1;	/* No ad1848 */
-	hw_config->slots[4] = -1;	/* No audio */
-	hw_config->slots[5] = -1;	/* No mixer */
-
-	if (!gus_pnp_flag)
-	{
-		if (irq < 0 || irq > 15)
-		{
-			printk(KERN_ERR "ERROR! Invalid IRQ#%d. GUS Disabled", irq);
-			return;
-		}
-	}
-	
-	if (dma < 0 || dma > 7 || dma == 4)
-	{
-		printk(KERN_ERR "ERROR! Invalid DMA#%d. GUS Disabled", dma);
-		return;
-	}
-	gus_irq = irq;
-	gus_dma = dma;
-	gus_dma2 = dma2;
-	gus_hw_config = hw_config;
-
-	if (gus_dma2 == -1)
-		gus_dma2 = dma;
-
-	/*
-	 * Try to identify the GUS model.
-	 *
-	 *  Versions < 3.6 don't have the digital ASIC. Try to probe it first.
-	 */
-
-	spin_lock_irqsave(&gus_lock,flags);
-	outb((0x20), gus_base + 0x0f);
-	val = inb(gus_base + 0x0f);
-	spin_unlock_irqrestore(&gus_lock,flags);
-
-	if (gus_pnp_flag || (val != 0xff && (val & 0x06)))	/* Should be 0x02?? */
-	{
-		int             ad_flags = 0;
-
-		if (gus_pnp_flag)
-			ad_flags = 0x12345678;	/* Interwave "magic" */
-		/*
-		 * It has the digital ASIC so the card is at least v3.4.
-		 * Next try to detect the true model.
-		 */
-
-		if (gus_pnp_flag)	/* Hack hack hack */
-			val = 10;
-		else
-			val = inb(u_MixSelect);
-
-		/*
-		 * Value 255 means pre-3.7 which don't have mixer.
-		 * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer.
-		 * 10 and above is GUS MAX which has the CS4231 codec/mixer.
-		 *
-		 */
-
-		if (val == 255 || val < 5)
-		{
-			model_num = "3.4";
-			gus_type = 0x34;
-		}
-		else if (val < 10)
-		{
-			model_num = "3.7";
-			gus_type = 0x37;
-			mixer_type = ICS2101;
-			request_region(u_MixSelect, 1, "GUS mixer");
-		}
-		else
-		{
-			struct resource *ports;
-			ports = request_region(gus_base + 0x10c, 4, "ad1848");
-			model_num = "MAX";
-			gus_type = 0x40;
-			mixer_type = CS4231;
-#ifdef CONFIG_SOUND_GUSMAX
-			{
-				unsigned char   max_config = 0x40;	/* Codec enable */
-
-				if (gus_dma2 == -1)
-					gus_dma2 = gus_dma;
-
-				if (gus_dma > 3)
-					max_config |= 0x10;		/* 16 bit capture DMA */
-
-				if (gus_dma2 > 3)
-					max_config |= 0x20;		/* 16 bit playback DMA */
-
-				max_config |= (gus_base >> 4) & 0x0f;	/* Extract the X from 2X0 */
-
-				outb((max_config), gus_base + 0x106);	/* UltraMax control */
-			}
-
-			if (!ports)
-				goto no_cs4231;
-
-			if (ad1848_detect(ports, &ad_flags, hw_config->osp))
-			{
-				char           *name = "GUS MAX";
-				int             old_num_mixers = num_mixers;
-
-				if (gus_pnp_flag)
-					name = "GUS PnP";
-
-				gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
-				gus_wave_volume = 90;
-				have_gus_max = 1;
-				if (hw_config->name)
-					name = hw_config->name;
-
-				hw_config->slots[1] = ad1848_init(name, ports,
-							-irq, gus_dma2,	/* Playback DMA */
-							gus_dma,	/* Capture DMA */
-							1,		/* Share DMA channels with GF1 */
-							hw_config->osp,
-							THIS_MODULE);
-
-				if (num_mixers > old_num_mixers)
-				{
-					/* GUS has it's own mixer map */
-					AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_SYNTH);
-					AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
-					AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
-				}
-			}
-			else {
-				release_region(gus_base + 0x10c, 4);
-			no_cs4231:
-				printk(KERN_WARNING "GUS: No CS4231 ??");
-			}
-#else
-			printk(KERN_ERR "GUS MAX found, but not compiled in\n");
-#endif
-		}
-	}
-	else
-	{
-		/*
-		 * ASIC not detected so the card must be 2.2 or 2.4.
-		 * There could still be the 16-bit/mixer daughter card.
-		 */
-	}
-
-	if (hw_config->name)
-		snprintf(tmp, sizeof(tmp), "%s (%dk)", hw_config->name,
-			 (int) gus_mem_size / 1024);
-	else if (gus_pnp_flag)
-		snprintf(tmp, sizeof(tmp), "Gravis UltraSound PnP (%dk)",
-			 (int) gus_mem_size / 1024);
-	else
-		snprintf(tmp, sizeof(tmp), "Gravis UltraSound %s (%dk)", model_num,
-			 (int) gus_mem_size / 1024);
-
-
-	samples = (struct patch_info *)vmalloc((MAX_SAMPLE + 1) * sizeof(*samples));
-	if (samples == NULL)
-	{
-		printk(KERN_WARNING "gus_init: Cant allocate memory for instrument tables\n");
-		return;
-	}
-	conf_printf(tmp, hw_config);
-	strlcpy(gus_info.name, tmp, sizeof(gus_info.name));
-
-	if ((sdev = sound_alloc_synthdev()) == -1)
-		printk(KERN_WARNING "gus_init: Too many synthesizers\n");
-	else
-	{
-		voice_alloc = &guswave_operations.alloc;
-		if (iw_mode)
-			guswave_operations.id = "IWAVE";
-		hw_config->slots[0] = sdev;
-		synth_devs[sdev] = &guswave_operations;
-		sequencer_init();
-		gus_tmr_install(gus_base + 8);
-	}
-
-	reset_sample_memory();
-
-	gus_initialize();
-	
-	if ((gus_mem_size > 0) && !gus_no_wave_dma)
-	{
-		hw_config->slots[4] = -1;
-		if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
-					"Ultrasound",
-					&gus_audio_driver,
-					sizeof(struct audio_driver),
-					NEEDS_RESTART |
-		                   	((!iw_mode && dma2 != dma && dma2 != -1) ?
-						DMA_DUPLEX : 0),
-					AFMT_U8 | AFMT_S16_LE,
-					NULL, dma, dma2)) < 0)
-		{
-			return;
-		}
-
-		hw_config->slots[4] = gus_devnum;
-		audio_devs[gus_devnum]->min_fragment = 9;	/* 512k */
-		audio_devs[gus_devnum]->max_fragment = 11;	/* 8k (must match size of bounce_buf */
-		audio_devs[gus_devnum]->mixer_dev = -1;	/* Next mixer# */
-		audio_devs[gus_devnum]->flags |= DMA_HARDSTOP;
-	}
-	
-	/*
-	 *  Mixer dependent initialization.
-	 */
-
-	switch (mixer_type)
-	{
-		case ICS2101:
-			gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
-			gus_wave_volume = 90;
-			request_region(u_MixSelect, 1, "GUS mixer");
-			hw_config->slots[5] = ics2101_mixer_init();
-			audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5];	/* Next mixer# */
-			return;
-
-		case CS4231:
-			/* Initialized elsewhere (ad1848.c) */
-		default:
-			hw_config->slots[5] = gus_default_mixer_init();
-			audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5];	/* Next mixer# */
-			return;
-	}
-}
-
-void __exit gus_wave_unload(struct address_info *hw_config)
-{
-#ifdef CONFIG_SOUND_GUSMAX
-	if (have_gus_max)
-	{
-		ad1848_unload(gus_base + 0x10c,
-				-gus_irq,
-				gus_dma2,	/* Playback DMA */
-				gus_dma,	/* Capture DMA */
-				1);	/* Share DMA channels with GF1 */
-	}
-#endif
-
-	if (mixer_type == ICS2101)
-	{
-		release_region(u_MixSelect, 1);
-	}
-	if (hw_config->slots[0] != -1)
-		sound_unload_synthdev(hw_config->slots[0]);
-	if (hw_config->slots[1] != -1)
-		sound_unload_audiodev(hw_config->slots[1]);
-	if (hw_config->slots[2] != -1)
-		sound_unload_mididev(hw_config->slots[2]);
-	if (hw_config->slots[4] != -1)
-		sound_unload_audiodev(hw_config->slots[4]);
-	if (hw_config->slots[5] != -1)
-		sound_unload_mixerdev(hw_config->slots[5]);
-	
-	vfree(samples);
-	samples=NULL;
-}
-/* called in interrupt context */
-static void do_loop_irq(int voice)
-{
-	unsigned char   tmp;
-	int             mode, parm;
-
-	spin_lock(&gus_lock);
-	gus_select_voice(voice);
-
-	tmp = gus_read8(0x00);
-	tmp &= ~0x20;		/*
-				 * Disable wave IRQ for this_one voice
-				 */
-	gus_write8(0x00, tmp);
-
-	if (tmp & 0x03)		/* Voice stopped */
-		voice_alloc->map[voice] = 0;
-
-	mode = voices[voice].loop_irq_mode;
-	voices[voice].loop_irq_mode = 0;
-	parm = voices[voice].loop_irq_parm;
-
-	switch (mode)
-	{
-		case LMODE_FINISH:	/*
-					 * Final loop finished, shoot volume down
-					 */
-
-			if ((int) (gus_read16(0x09) >> 4) < 100)	/*
-									 * Get current volume
-									 */
-			{
-				gus_voice_off();
-				gus_rampoff();
-				gus_voice_init(voice);
-				break;
-			}
-			gus_ramp_range(65, 4065);
-			gus_ramp_rate(0, 63);		/*
-							 * Fastest possible rate
-							 */
-			gus_rampon(0x20 | 0x40);	/*
-							 * Ramp down, once, irq
-							 */
-			voices[voice].volume_irq_mode = VMODE_HALT;
-			break;
-
-		case LMODE_PCM_STOP:
-			pcm_active = 0;	/* Signal to the play_next_pcm_block routine */
-		case LMODE_PCM:
-		{
-			pcm_qlen--;
-			pcm_head = (pcm_head + 1) % pcm_nblk;
-			if (pcm_qlen && pcm_active)
-			{
-				play_next_pcm_block();
-			}
-			else
-			{
-				/* Underrun. Just stop the voice */
-				gus_select_voice(0);	/* Left channel */
-				gus_voice_off();
-				gus_rampoff();
-				gus_select_voice(1);	/* Right channel */
-				gus_voice_off();
-				gus_rampoff();
-				pcm_active = 0;
-			}
-
-			/*
-			 * If the queue was full before this interrupt, the DMA transfer was
-			 * suspended. Let it continue now.
-			 */
-			
-			if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-				DMAbuf_outputintr(gus_devnum, 0);
-		}
-		break;
-
-		default:
-			break;
-	}
-	spin_unlock(&gus_lock);
-}
-
-static void do_volume_irq(int voice)
-{
-	unsigned char tmp;
-	int mode, parm;
-	unsigned long flags;
-
-	spin_lock_irqsave(&gus_lock,flags);
-
-	gus_select_voice(voice);
-	tmp = gus_read8(0x0d);
-	tmp &= ~0x20;		/*
-				 * Disable volume ramp IRQ
-				 */
-	gus_write8(0x0d, tmp);
-
-	mode = voices[voice].volume_irq_mode;
-	voices[voice].volume_irq_mode = 0;
-	parm = voices[voice].volume_irq_parm;
-
-	switch (mode)
-	{
-		case VMODE_HALT:	/* Decay phase finished */
-			if (iw_mode)
-				gus_write8(0x15, 0x02);	/* Set voice deactivate bit of SMSI */
-			spin_unlock_irqrestore(&gus_lock,flags);
-			gus_voice_init(voice);
-			break;
-
-		case VMODE_ENVELOPE:
-			gus_rampoff();
-			spin_unlock_irqrestore(&gus_lock,flags);
-			step_envelope(voice);
-			break;
-
-		case VMODE_START_NOTE:
-			spin_unlock_irqrestore(&gus_lock,flags);
-			guswave_start_note2(voices[voice].dev_pending, voice,
-				      voices[voice].note_pending, voices[voice].volume_pending);
-			if (voices[voice].kill_pending)
-				guswave_kill_note(voices[voice].dev_pending, voice,
-					  voices[voice].note_pending, 0);
-
-			if (voices[voice].sample_pending >= 0)
-			{
-				guswave_set_instr(voices[voice].dev_pending, voice,
-					voices[voice].sample_pending);
-				voices[voice].sample_pending = -1;
-			}
-			break;
-
-		default:
-			spin_unlock_irqrestore(&gus_lock,flags);
-	}
-}
-/* called in irq context */
-void gus_voice_irq(void)
-{
-	unsigned long wave_ignore = 0, volume_ignore = 0;
-	unsigned long voice_bit;
-
-	unsigned char src, voice;
-
-	while (1)
-	{
-		src = gus_read8(0x0f);	/*
-					 * Get source info
-					 */
-		voice = src & 0x1f;
-		src &= 0xc0;
-
-		if (src == (0x80 | 0x40))
-			return;	/*
-				 * No interrupt
-				 */
-
-		voice_bit = 1 << voice;
-
-		if (!(src & 0x80))	/*
-					 * Wave IRQ pending
-					 */
-			if (!(wave_ignore & voice_bit) && (int) voice < nr_voices)	/*
-											 * Not done
-											 * yet
-											 */
-			{
-				wave_ignore |= voice_bit;
-				do_loop_irq(voice);
-			}
-		if (!(src & 0x40))	/*
-					 * Volume IRQ pending
-					 */
-			if (!(volume_ignore & voice_bit) && (int) voice < nr_voices)	/*
-											   * Not done
-											   * yet
-											 */
-			{
-				volume_ignore |= voice_bit;
-				do_volume_irq(voice);
-			}
-	}
-}
-
-void guswave_dma_irq(void)
-{
-	unsigned char   status;
-
-	status = gus_look8(0x41);	/* Get DMA IRQ Status */
-	if (status & 0x40)	/* DMA interrupt pending */
-		switch (active_device)
-		{
-			case GUS_DEV_WAVE:
-				wake_up(&dram_sleeper);
-				break;
-
-			case GUS_DEV_PCM_CONTINUE:	/* Left channel data transferred */
-				gus_write8(0x41, 0);	/* Disable GF1 DMA */
-				gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
-						pcm_current_count,
-						pcm_current_intrflag, 1);
-				break;
-
-			case GUS_DEV_PCM_DONE:	/* Right or mono channel data transferred */
-				gus_write8(0x41, 0);	/* Disable GF1 DMA */
-				if (pcm_qlen < pcm_nblk)
-				{
-					dma_active = 0;
-					if (gus_busy)
-					{
-						if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-							DMAbuf_outputintr(gus_devnum, 0);
-					}
-				}
-				break;
-
-			default:
-				break;
-	}
-	status = gus_look8(0x49);	/*
-					 * Get Sampling IRQ Status
-					 */
-	if (status & 0x40)	/*
-				 * Sampling Irq pending
-				 */
-	{
-		DMAbuf_inputintr(gus_devnum);
-	}
-}
-
-/*
- * Timer stuff
- */
-
-static volatile int select_addr, data_addr;
-static volatile int curr_timer;
-
-void gus_timer_command(unsigned int addr, unsigned int val)
-{
-	int i;
-
-	outb(((unsigned char) (addr & 0xff)), select_addr);
-
-	for (i = 0; i < 2; i++)
-		inb(select_addr);
-
-	outb(((unsigned char) (val & 0xff)), data_addr);
-
-	for (i = 0; i < 2; i++)
-		inb(select_addr);
-}
-
-static void arm_timer(int timer, unsigned int interval)
-{
-	curr_timer = timer;
-
-	if (timer == 1)
-	{
-		gus_write8(0x46, 256 - interval);	/* Set counter for timer 1 */
-		gus_write8(0x45, 0x04);			/* Enable timer 1 IRQ */
-		gus_timer_command(0x04, 0x01);		/* Start timer 1 */
-	}
-	else
-	{
-		gus_write8(0x47, 256 - interval);	/* Set counter for timer 2 */
-		gus_write8(0x45, 0x08);			/* Enable timer 2 IRQ */
-		gus_timer_command(0x04, 0x02);		/* Start timer 2 */
-	}
-
-	gus_timer_enabled = 1;
-}
-
-static unsigned int gus_tmr_start(int dev, unsigned int usecs_per_tick)
-{
-	int timer_no, resolution;
-	int divisor;
-
-	if (usecs_per_tick > (256 * 80))
-	{
-		timer_no = 2;
-		resolution = 320;	/* usec */
-	}
-	else
-	{
-		timer_no = 1;
-		resolution = 80;	/* usec */
-	}
-	divisor = (usecs_per_tick + (resolution / 2)) / resolution;
-	arm_timer(timer_no, divisor);
-
-	return divisor * resolution;
-}
-
-static void gus_tmr_disable(int dev)
-{
-	gus_write8(0x45, 0);	/* Disable both timers */
-	gus_timer_enabled = 0;
-}
-
-static void gus_tmr_restart(int dev)
-{
-	if (curr_timer == 1)
-		gus_write8(0x45, 0x04);		/* Start timer 1 again */
-	else
-		gus_write8(0x45, 0x08);		/* Start timer 2 again */
-	gus_timer_enabled = 1;
-}
-
-static struct sound_lowlev_timer gus_tmr =
-{
-	0,
-	1,
-	gus_tmr_start,
-	gus_tmr_disable,
-	gus_tmr_restart
-};
-
-static void gus_tmr_install(int io_base)
-{
-	struct sound_lowlev_timer *tmr;
-
-	select_addr = io_base;
-	data_addr = io_base + 1;
-
-	tmr = &gus_tmr;
-
-#ifdef THIS_GETS_FIXED
-	sound_timer_init(&gus_tmr, "GUS");
-#endif
-}
diff --git a/sound/oss/harmony.c b/sound/oss/harmony.c
deleted file mode 100644
index 591683c..0000000
--- a/sound/oss/harmony.c
+++ /dev/null
@@ -1,1330 +0,0 @@
-/*
- 	drivers/sound/harmony.c 
-
-	This is a sound driver for ASP's and Lasi's Harmony sound chip
-	and is unlikely to be used for anything other than on a HP PA-RISC.
-
-	Harmony is found in HP 712s, 715/new and many other GSC based machines.
-	On older 715 machines you'll find the technically identical chip 
-	called 'Vivace'. Both Harmony and Vicace are supported by this driver.
-
-	Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@onefishtwo.ca>
-	Copyright 2000-2003 (c) Helge Deller <deller@gmx.de>
-	Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr>
-	Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr>
-	Copyright 2004 (c) Stuart Brady <sdbrady@ntlworld.com>
-
-				
-TODO:
-	- fix SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE ioctls to
-		return the real values
-	- add private ioctl for selecting line- or microphone input
-		(only one of them is available at the same time)
-	- add module parameters
-	- implement mmap functionality
-	- implement gain meter ?
-	- ...
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-
-#include <asm/parisc-device.h>
-#include <asm/io.h>
-
-#include "sound_config.h"
-
-
-#define PFX "harmony: "
-#define HARMONY_VERSION "V0.9a"
-
-#undef DEBUG
-#ifdef DEBUG
-# define DPRINTK printk 
-#else
-# define DPRINTK(x,...)
-#endif
-
-
-#define MAX_BUFS 10		/* maximum number of rotating buffers */
-#define HARMONY_BUF_SIZE 4096	/* needs to be a multiple of PAGE_SIZE (4096)! */
-
-#define CNTL_C		0x80000000
-#define	CNTL_ST		0x00000020
-#define CNTL_44100	0x00000015	/* HARMONY_SR_44KHZ */
-#define CNTL_8000	0x00000008	/* HARMONY_SR_8KHZ */
-
-#define GAINCTL_HE	0x08000000
-#define GAINCTL_LE	0x04000000
-#define GAINCTL_SE	0x02000000
-
-#define DSTATUS_PN	0x00000200
-#define DSTATUS_RN	0x00000002
-
-#define DSTATUS_IE	0x80000000
-
-#define HARMONY_DF_16BIT_LINEAR	0
-#define HARMONY_DF_8BIT_ULAW	1
-#define HARMONY_DF_8BIT_ALAW	2
-
-#define HARMONY_SS_MONO		0
-#define HARMONY_SS_STEREO	1
-
-#define HARMONY_SR_8KHZ		0x08
-#define HARMONY_SR_16KHZ	0x09
-#define HARMONY_SR_27KHZ	0x0A
-#define HARMONY_SR_32KHZ	0x0B
-#define HARMONY_SR_48KHZ	0x0E
-#define HARMONY_SR_9KHZ		0x0F
-#define HARMONY_SR_5KHZ		0x10
-#define HARMONY_SR_11KHZ	0x11
-#define HARMONY_SR_18KHZ	0x12
-#define HARMONY_SR_22KHZ	0x13
-#define HARMONY_SR_37KHZ	0x14
-#define HARMONY_SR_44KHZ	0x15
-#define HARMONY_SR_33KHZ	0x16
-#define HARMONY_SR_6KHZ		0x17
-
-/*
- * Some magics numbers used to auto-detect file formats
- */
-
-#define HARMONY_MAGIC_8B_ULAW	1
-#define HARMONY_MAGIC_8B_ALAW	27
-#define HARMONY_MAGIC_16B_LINEAR 3
-#define HARMONY_MAGIC_MONO	1
-#define HARMONY_MAGIC_STEREO	2
-
-/*
- * Channels Positions in mixer register
- */
-
-#define GAIN_HE_SHIFT   27
-#define GAIN_HE_MASK    ( 1 << GAIN_HE_SHIFT) 
-#define GAIN_LE_SHIFT   26
-#define GAIN_LE_MASK    ( 1 << GAIN_LE_SHIFT) 
-#define GAIN_SE_SHIFT   25
-#define GAIN_SE_MASK    ( 1 << GAIN_SE_SHIFT) 
-#define GAIN_IS_SHIFT   24
-#define GAIN_IS_MASK    ( 1 << GAIN_IS_SHIFT) 
-#define GAIN_MA_SHIFT   20
-#define GAIN_MA_MASK    ( 0x0f << GAIN_MA_SHIFT) 
-#define GAIN_LI_SHIFT   16
-#define GAIN_LI_MASK    ( 0x0f << GAIN_LI_SHIFT) 
-#define GAIN_RI_SHIFT   12
-#define GAIN_RI_MASK    ( 0x0f << GAIN_RI_SHIFT) 
-#define GAIN_LO_SHIFT   6
-#define GAIN_LO_MASK    ( 0x3f << GAIN_LO_SHIFT) 
-#define GAIN_RO_SHIFT   0
-#define GAIN_RO_MASK    ( 0x3f << GAIN_RO_SHIFT) 
-
-
-#define MAX_OUTPUT_LEVEL  (GAIN_RO_MASK >> GAIN_RO_SHIFT)
-#define MAX_INPUT_LEVEL   (GAIN_RI_MASK >> GAIN_RI_SHIFT)
-#define MAX_MONITOR_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT)
-
-#define MIXER_INTERNAL   SOUND_MIXER_LINE1
-#define MIXER_LINEOUT    SOUND_MIXER_LINE2
-#define MIXER_HEADPHONES SOUND_MIXER_LINE3
-
-#define MASK_INTERNAL   SOUND_MASK_LINE1
-#define MASK_LINEOUT    SOUND_MASK_LINE2
-#define MASK_HEADPHONES SOUND_MASK_LINE3
-
-/*
- * Channels Mask in mixer register
- */
-
-#define GAIN_TOTAL_SILENCE 0x00F00FFF
-#define GAIN_DEFAULT       0x0FF00000
-
-
-struct harmony_hpa {
-	u8	unused000;
-	u8	id;
-	u8	teleshare_id;
-	u8	unused003;
-	u32	reset;
-	u32	cntl;
-	u32	gainctl;
-	u32	pnxtadd;
-	u32	pcuradd;
-	u32	rnxtadd;
-	u32	rcuradd;
-	u32	dstatus;
-	u32	ov;
-	u32	pio;
-	u32	unused02c;
-	u32	unused030[3];
-	u32	diag;
-};
-
-struct harmony_dev {
-	struct harmony_hpa *hpa;
-	struct parisc_device *dev;
-	u32 current_gain;
-	u32 dac_rate;		/* 8000 ... 48000 (Hz) */
-	u8 data_format;		/* HARMONY_DF_xx_BIT_xxx */
-	u8 sample_rate;		/* HARMONY_SR_xx_KHZ */
-	u8 stereo_select;	/* HARMONY_SS_MONO or HARMONY_SS_STEREO */
-	int format_initialized  :1;
-	int suspended_playing   :1;
-	int suspended_recording :1;
-	
-	int blocked_playing     :1;
-	int blocked_recording   :1;
-	int audio_open		:1;
-	int mixer_open		:1;
-	
-	wait_queue_head_t wq_play, wq_record;
-	int first_filled_play;	/* first buffer containing data (next to play) */
-	int nb_filled_play; 
-	int play_offset;
-	int first_filled_record;
-	int nb_filled_record;
-		
-	int dsp_unit, mixer_unit;
-};
-
-
-static struct harmony_dev harmony;
-
-
-/*
- * Dynamic sound buffer allocation and DMA memory
- */
-
-struct harmony_buffer {
-	unsigned char *addr;
-	dma_addr_t dma_handle;
-	int dma_coherent;	/* Zero if dma_alloc_coherent() fails */
-	unsigned int len;
-};
-
-/*
- * Harmony memory buffers
- */
-
-static struct harmony_buffer played_buf, recorded_buf, silent, graveyard;
-
-
-#define CHECK_WBACK_INV_OFFSET(b,offset,len) \
-        do { if (!b.dma_coherent) \
-		dma_cache_wback_inv((unsigned long)b.addr+offset,len); \
-	} while (0) 
-
-	
-static int __init harmony_alloc_buffer(struct harmony_buffer *b, 
-		unsigned int buffer_count)
-{
-	b->len = buffer_count * HARMONY_BUF_SIZE;
-	b->addr = dma_alloc_coherent(&harmony.dev->dev, 
-			  b->len, &b->dma_handle, GFP_KERNEL|GFP_DMA);
-	if (b->addr && b->dma_handle) {
-		b->dma_coherent = 1;
-		DPRINTK(KERN_INFO PFX "coherent memory: 0x%lx, played_buf: 0x%lx\n",
-				(unsigned long)b->dma_handle, (unsigned long)b->addr);
-	} else {
-		b->dma_coherent = 0;
-		/* kmalloc()ed memory will HPMC on ccio machines ! */
-		b->addr = kmalloc(b->len, GFP_KERNEL);
-		if (!b->addr) {
-			printk(KERN_ERR PFX "couldn't allocate memory\n");
-			return -EBUSY;
-		}
-		b->dma_handle = __pa(b->addr);
-	}
-	return 0;
-}
-
-static void __exit harmony_free_buffer(struct harmony_buffer *b)
-{
-	if (!b->addr)
-		return;
-
-	if (b->dma_coherent)
-		dma_free_coherent(&harmony.dev->dev,
-				b->len, b->addr, b->dma_handle);
-	else
-		kfree(b->addr);
-
-	memset(b, 0, sizeof(*b));
-}
-
-
-
-/*
- * Low-Level sound-chip programming
- */
-
-static void __inline__ harmony_wait_CNTL(void)
-{
-	/* Wait until we're out of control mode */
-	while (gsc_readl(&harmony.hpa->cntl) & CNTL_C)
-		/* wait */ ;
-}
-
-
-static void harmony_update_control(void) 
-{
-	u32 default_cntl;
-	
-	/* Set CNTL */
-	default_cntl = (CNTL_C |  		/* The C bit */
-		(harmony.data_format << 6) |	/* Set the data format */
-		(harmony.stereo_select << 5) |	/* Stereo select */
-		(harmony.sample_rate));		/* Set sample rate */
-	harmony.format_initialized = 1;
-	
-	/* initialize CNTL */
-	gsc_writel(default_cntl, &harmony.hpa->cntl);
-}
-
-static void harmony_set_control(u8 data_format, u8 sample_rate, u8 stereo_select) 
-{
-	harmony.sample_rate = sample_rate;
-	harmony.data_format = data_format;
-	harmony.stereo_select = stereo_select;
-	harmony_update_control();
-}
-
-static void harmony_set_rate(u8 data_rate) 
-{
-	harmony.sample_rate = data_rate;
-	harmony_update_control();
-}
-
-static int harmony_detect_rate(int *freq)
-{
-	int newrate;
-	switch (*freq) {
-	case 8000:	newrate = HARMONY_SR_8KHZ;	break;
-	case 16000:	newrate = HARMONY_SR_16KHZ;	break; 
-	case 27428:	newrate = HARMONY_SR_27KHZ;	break; 
-	case 32000:	newrate = HARMONY_SR_32KHZ;	break; 
-	case 48000:	newrate = HARMONY_SR_48KHZ;	break; 
-	case 9600:	newrate = HARMONY_SR_9KHZ;	break; 
-	case 5512:	newrate = HARMONY_SR_5KHZ;	break; 
-	case 11025:	newrate = HARMONY_SR_11KHZ;	break; 
-	case 18900:	newrate = HARMONY_SR_18KHZ;	break; 
-	case 22050:	newrate = HARMONY_SR_22KHZ;	break; 
-	case 37800:	newrate = HARMONY_SR_37KHZ;	break; 
-	case 44100:	newrate = HARMONY_SR_44KHZ;	break; 
-	case 33075:	newrate = HARMONY_SR_33KHZ;	break; 
-	case 6615:	newrate = HARMONY_SR_6KHZ;	break; 
-	default:	newrate = HARMONY_SR_8KHZ; 
-			*freq = 8000;			break;
-	}
-	return newrate;
-}
-
-static void harmony_set_format(u8 data_format) 
-{
-	harmony.data_format = data_format;
-	harmony_update_control();
-}
-
-static void harmony_set_stereo(u8 stereo_select) 
-{
-	harmony.stereo_select = stereo_select;
-	harmony_update_control();
-}
-
-static void harmony_disable_interrupts(void) 
-{
-	harmony_wait_CNTL();
-	gsc_writel(0, &harmony.hpa->dstatus); 
-}
-
-static void harmony_enable_interrupts(void) 
-{
-	harmony_wait_CNTL();
-	gsc_writel(DSTATUS_IE, &harmony.hpa->dstatus); 
-}
-
-/*
- * harmony_silence()
- *
- * This subroutine fills in a buffer starting at location start and
- * silences for length bytes.  This references the current
- * configuration of the audio format.
- *
- */
-
-static void harmony_silence(struct harmony_buffer *buffer, int start, int length) 
-{
-	u8 silence_char;
-
-	/* Despite what you hear, silence is different in
-	   different audio formats.  */
-	switch (harmony.data_format) {
-		case HARMONY_DF_8BIT_ULAW:	silence_char = 0x55; break;
-		case HARMONY_DF_8BIT_ALAW:	silence_char = 0xff; break;
-		case HARMONY_DF_16BIT_LINEAR:	/* fall through */
-		default:			silence_char = 0;
-	}
-
-	memset(buffer->addr+start, silence_char, length);
-}
-
-
-static int harmony_audio_open(struct inode *inode, struct file *file)
-{
-	if (harmony.audio_open) 
-		return -EBUSY;
-	
-	harmony.audio_open = 1;
-	harmony.suspended_playing = harmony.suspended_recording = 1;
-	harmony.blocked_playing   = harmony.blocked_recording   = 0;
-	harmony.first_filled_play = harmony.first_filled_record = 0;
-	harmony.nb_filled_play    = harmony.nb_filled_record    = 0;
-	harmony.play_offset = 0;
-	init_waitqueue_head(&harmony.wq_play);
-	init_waitqueue_head(&harmony.wq_record);
-	
-	/* Start off in a balanced mode. */
-	harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-	harmony_update_control();
-	harmony.format_initialized = 0;
-
-	/* Clear out all the buffers and flush to cache */
-	harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-	CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-	
-	return 0;
-}
-
-/*
- * Release (close) the audio device.
- */
-
-static int harmony_audio_release(struct inode *inode, struct file *file)
-{
-	if (!harmony.audio_open) 
-		return -EBUSY;
-	
-	harmony.audio_open = 0;
-
-	return 0;
-}
-
-/*
- * Read recorded data off the audio device.
- */
-
-static ssize_t harmony_audio_read(struct file *file,
-                                char *buffer,
-                                size_t size_count,
-                                loff_t *ppos)
-{
-	int total_count = (int) size_count;
-	int count = 0;
-	int buf_to_read;
-
-	while (count<total_count) {
-		/* Wait until we're out of control mode */
-		harmony_wait_CNTL();
-		
-		/* Figure out which buffer to fill in */
-		if (harmony.nb_filled_record <= 2) {
-			harmony.blocked_recording = 1;
-		        if (harmony.suspended_recording) {
-				harmony.suspended_recording = 0;
-				harmony_enable_interrupts();
-			}
-							
-			interruptible_sleep_on(&harmony.wq_record);
-			harmony.blocked_recording = 0;
-		}
-		
-		if (harmony.nb_filled_record < 2)
-			return -EBUSY;
-		
-		buf_to_read = harmony.first_filled_record;
-
-		/* Copy the page to an aligned buffer */
-		if (copy_to_user(buffer+count, recorded_buf.addr +
-				 (HARMONY_BUF_SIZE*buf_to_read),
-				 HARMONY_BUF_SIZE)) {
-			count = -EFAULT;
-			break;
-		}
-		
-		harmony.nb_filled_record--;
-		harmony.first_filled_record++;
-		harmony.first_filled_record %= MAX_BUFS;
-				
-		count += HARMONY_BUF_SIZE;
-	}
-	return count;
-}
-
-
-
-
-/*
- * Here is the place where we try to recognize file format.
- * Sun/NeXT .au files begin with the string .snd
- * At offset 12 is specified the encoding.
- * At offset 16 is specified speed rate
- * At Offset 20 is specified the numbers of voices
- */
-
-#define four_bytes_to_u32(start) (file_header[start] << 24)|\
-                                  (file_header[start+1] << 16)|\
-                                  (file_header[start+2] << 8)|\
-                                  (file_header[start+3]);
-
-#define test_rate(tested,real_value,harmony_value) if ((tested)<=(real_value))\
-                                                    
-
-static int harmony_format_auto_detect(const char *buffer, int block_size)
-{
-	u8 file_header[24];
-	u32 start_string;
-	int ret = 0;
-	
-	if (block_size>24) {
-		if (copy_from_user(file_header, buffer, sizeof(file_header)))
-			ret = -EFAULT;
-			
-		start_string = four_bytes_to_u32(0);
-		
-		if ((file_header[4]==0) && (start_string==0x2E736E64)) {
-			u32 format;
-			u32 nb_voices;
-			u32 speed;
-			
-			format = four_bytes_to_u32(12);
-			nb_voices = four_bytes_to_u32(20);
-			speed = four_bytes_to_u32(16);
-			
-			switch (format) {
-			case HARMONY_MAGIC_8B_ULAW:
-				harmony.data_format = HARMONY_DF_8BIT_ULAW;
-				break;
-			case HARMONY_MAGIC_8B_ALAW:
-				harmony.data_format = HARMONY_DF_8BIT_ALAW;
-				break;
-			case HARMONY_MAGIC_16B_LINEAR:
-				harmony.data_format = HARMONY_DF_16BIT_LINEAR;
-				break;
-			default:
-				harmony_set_control(HARMONY_DF_16BIT_LINEAR,
-						HARMONY_SR_44KHZ, HARMONY_SS_STEREO);
-				goto out;
-			}
-			switch (nb_voices) {
-			case HARMONY_MAGIC_MONO:
-				harmony.stereo_select = HARMONY_SS_MONO;
-				break;
-			case HARMONY_MAGIC_STEREO:
-				harmony.stereo_select = HARMONY_SS_STEREO;
-				break;
-			default:
-				harmony.stereo_select = HARMONY_SS_MONO;
-				break;
-			}
-			harmony_set_rate(harmony_detect_rate(&speed));
-			harmony.dac_rate = speed;
-			goto out;
-		}
-	}
-	harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-out:
-	return ret;
-}
-#undef four_bytes_to_u32
-
-
-static ssize_t harmony_audio_write(struct file *file,
-                                 const char *buffer,
-                                 size_t size_count,
-                                 loff_t *ppos)
-{
-	int total_count = (int) size_count;
-	int count = 0;
-	int frame_size;
-	int buf_to_fill;
-	int fresh_buffer;
-
-	if (!harmony.format_initialized) {
-		if (harmony_format_auto_detect(buffer, total_count))
-			return -EFAULT;
-	}
-	
-	while (count<total_count) {
-		/* Wait until we're out of control mode */
-		harmony_wait_CNTL();
-
-		/* Figure out which buffer to fill in */
-		if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset) {
-			harmony.blocked_playing = 1;
-			interruptible_sleep_on(&harmony.wq_play);
-			harmony.blocked_playing = 0;
-		}
-		if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset)
-			return -EBUSY;
-		
-		
-		buf_to_fill = (harmony.first_filled_play+harmony.nb_filled_play); 
-		if (harmony.play_offset) {
-			buf_to_fill--;
-			buf_to_fill += MAX_BUFS;
-		}
-		buf_to_fill %= MAX_BUFS;
-		
-		fresh_buffer = (harmony.play_offset == 0);
-		
-		/* Figure out the size of the frame */
-		if ((total_count-count) >= HARMONY_BUF_SIZE - harmony.play_offset) {
-			frame_size = HARMONY_BUF_SIZE - harmony.play_offset;
-		} else {
-			frame_size = total_count - count;
-			/* Clear out the buffer, since there we'll only be 
-			   overlaying part of the old buffer with the new one */
-			harmony_silence(&played_buf, 
-				HARMONY_BUF_SIZE*buf_to_fill+frame_size+harmony.play_offset,
-				HARMONY_BUF_SIZE-frame_size-harmony.play_offset);
-		}
-
-		/* Copy the page to an aligned buffer */
-		if (copy_from_user(played_buf.addr +(HARMONY_BUF_SIZE*buf_to_fill) + harmony.play_offset, 
-				   buffer+count, frame_size))
-			return -EFAULT;
-		CHECK_WBACK_INV_OFFSET(played_buf, (HARMONY_BUF_SIZE*buf_to_fill + harmony.play_offset), 
-				frame_size);
-	
-		if (fresh_buffer)
-			harmony.nb_filled_play++;
-		
-		count += frame_size;
-		harmony.play_offset += frame_size;
-		harmony.play_offset %= HARMONY_BUF_SIZE;
-		if (harmony.suspended_playing && (harmony.nb_filled_play>=4))
-			harmony_enable_interrupts();
-	}
-	
-	return count;
-}
-
-static unsigned int harmony_audio_poll(struct file *file,
-                                     struct poll_table_struct *wait)
-{
-	unsigned int mask = 0;
-	
-	if (file->f_mode & FMODE_READ) {
-		if (!harmony.suspended_recording)
-			poll_wait(file, &harmony.wq_record, wait);
-		if (harmony.nb_filled_record)
-			mask |= POLLIN | POLLRDNORM;
-	}
-
-	if (file->f_mode & FMODE_WRITE) {
-		if (!harmony.suspended_playing)
-			poll_wait(file, &harmony.wq_play, wait);
-		if (harmony.nb_filled_play)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-
-	return mask;
-}
-
-static int harmony_audio_ioctl(struct inode *inode,
-                                struct file *file,
-				unsigned int cmd,
-                                unsigned long arg)
-{
-	int ival, new_format;
-	int frag_size, frag_buf;
-	struct audio_buf_info info;
-	
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, (int *) arg);
-
-	case SNDCTL_DSP_GETCAPS:
-		ival = DSP_CAP_DUPLEX;
-		return put_user(ival, (int *) arg);
-
-	case SNDCTL_DSP_GETFMTS:
-		ival = (AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW ); 
-		return put_user(ival, (int *) arg);
-	
-	case SNDCTL_DSP_SETFMT:
-		if (get_user(ival, (int *) arg)) 
-			return -EFAULT;
-		if (ival != AFMT_QUERY) {
-			switch (ival) {
-			case AFMT_MU_LAW:	new_format = HARMONY_DF_8BIT_ULAW; break;
-			case AFMT_A_LAW:	new_format = HARMONY_DF_8BIT_ALAW; break;
-			case AFMT_S16_BE:	new_format = HARMONY_DF_16BIT_LINEAR; break;
-			default: {
-				DPRINTK(KERN_WARNING PFX 
-					"unsupported sound format 0x%04x requested.\n",
-					ival);
-				ival = AFMT_S16_BE;
-				return put_user(ival, (int *) arg);
-			}
-			}
-			harmony_set_format(new_format);
-			return 0;
-		} else {
-			switch (harmony.data_format) {
-			case HARMONY_DF_8BIT_ULAW:	ival = AFMT_MU_LAW; break;
-			case HARMONY_DF_8BIT_ALAW:	ival = AFMT_A_LAW;  break;
-			case HARMONY_DF_16BIT_LINEAR:	ival = AFMT_U16_BE; break;
-			default: ival = 0;
-			}
-			return put_user(ival, (int *) arg);
-		}
-
-	case SOUND_PCM_READ_RATE:
-		ival = harmony.dac_rate;
-		return put_user(ival, (int *) arg);
-
-	case SNDCTL_DSP_SPEED:
-		if (get_user(ival, (int *) arg))
-			return -EFAULT;
-		harmony_set_rate(harmony_detect_rate(&ival));
-		harmony.dac_rate = ival;
-		return put_user(ival, (int*) arg);
-
-	case SNDCTL_DSP_STEREO:
-		if (get_user(ival, (int *) arg))
-			return -EFAULT;
-		if (ival != 0 && ival != 1)
-			return -EINVAL;
-		harmony_set_stereo(ival);
- 		return 0;
- 
- 	case SNDCTL_DSP_CHANNELS:
- 		if (get_user(ival, (int *) arg))
- 			return -EFAULT;
- 		if (ival != 1 && ival != 2) {
- 			ival = harmony.stereo_select == HARMONY_SS_MONO ? 1 : 2;
- 			return put_user(ival, (int *) arg);
- 		}
- 		harmony_set_stereo(ival-1);
- 		return 0;
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		ival = HARMONY_BUF_SIZE;
-		return put_user(ival, (int *) arg);
-		
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_RESET:
-		if (!harmony.suspended_recording) {
-			/* TODO: stop_recording() */
-		}
-		return 0;
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(ival, (int *)arg))
-			return -EFAULT;
-		frag_size = ival & 0xffff;
-		frag_buf = (ival>>16) & 0xffff;
-		/* TODO: We use hardcoded fragment sizes and numbers for now */
-		frag_size = 12;  /* 4096 == 2^12 */
-		frag_buf  = MAX_BUFS;
-		ival = (frag_buf << 16) + frag_size;
-		return put_user(ival, (int *) arg);
-		
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		info.fragstotal = MAX_BUFS;
-                info.fragments = MAX_BUFS - harmony.nb_filled_play;
-		info.fragsize = HARMONY_BUF_SIZE;
-                info.bytes = info.fragments * info.fragsize;
-		return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		info.fragstotal = MAX_BUFS;
-                info.fragments = /*MAX_BUFS-*/ harmony.nb_filled_record;
-		info.fragsize = HARMONY_BUF_SIZE;
-                info.bytes = info.fragments * info.fragsize;
-		return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-	
-	case SNDCTL_DSP_SYNC:
-		return 0;
-	}
-	
-	return -EINVAL;
-}
-
-
-/*
- * harmony_interrupt()
- *
- * harmony interruption service routine
- * 
- */
-
-static irqreturn_t harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
-{
-	u32 dstatus;
-	struct harmony_hpa *hpa;
-
-	/* Setup the hpa */
-	hpa = ((struct harmony_dev *)dev)->hpa;
-	harmony_wait_CNTL();
-
-	/* Read dstatus and pcuradd (the current address) */
-	dstatus = gsc_readl(&hpa->dstatus);
-	
-	/* Turn off interrupts */
-	harmony_disable_interrupts();
-	
-	/* Check if this is a request to get the next play buffer */
-	if (dstatus & DSTATUS_PN) {
-		if (!harmony.nb_filled_play) {
-			harmony.suspended_playing = 1;
-			gsc_writel((unsigned long)silent.dma_handle, &hpa->pnxtadd);
-						
-			if (!harmony.suspended_recording)
-				harmony_enable_interrupts();
-		} else {
-			harmony.suspended_playing = 0;
-			gsc_writel((unsigned long)played_buf.dma_handle + 
-					(HARMONY_BUF_SIZE*harmony.first_filled_play),
-					&hpa->pnxtadd);
-			harmony.first_filled_play++;
-			harmony.first_filled_play %= MAX_BUFS;
-			harmony.nb_filled_play--;
-			
-		       	harmony_enable_interrupts();
-		}
-		
-		if (harmony.blocked_playing)
-			wake_up_interruptible(&harmony.wq_play);
-	}
-	
-	/* Check if we're being asked to fill in a recording buffer */
-	if (dstatus & DSTATUS_RN) {
-		if((harmony.nb_filled_record+2>=MAX_BUFS) || harmony.suspended_recording)
-		{
-			harmony.nb_filled_record = 0;
-			harmony.first_filled_record = 0;
-			harmony.suspended_recording = 1;
-			gsc_writel((unsigned long)graveyard.dma_handle, &hpa->rnxtadd);
-			if (!harmony.suspended_playing)
-				harmony_enable_interrupts();
-		} else {
-			int buf_to_fill;
-			buf_to_fill = (harmony.first_filled_record+harmony.nb_filled_record) % MAX_BUFS;
-			CHECK_WBACK_INV_OFFSET(recorded_buf, HARMONY_BUF_SIZE*buf_to_fill, HARMONY_BUF_SIZE);
-			gsc_writel((unsigned long)recorded_buf.dma_handle +
-					HARMONY_BUF_SIZE*buf_to_fill,
-					&hpa->rnxtadd);
-			harmony.nb_filled_record++;
-			harmony_enable_interrupts();
-		}
-
-		if (harmony.blocked_recording && harmony.nb_filled_record>3)
-			wake_up_interruptible(&harmony.wq_record);
-	}
-	return IRQ_HANDLED;
-}
-
-/*
- * Sound playing functions
- */
-
-static struct file_operations harmony_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= harmony_audio_read,
-	.write		= harmony_audio_write,
-	.poll		= harmony_audio_poll,
-	.ioctl		= harmony_audio_ioctl,
-	.open		= harmony_audio_open,
-	.release	= harmony_audio_release,
-};
-
-static int harmony_audio_init(void)
-{
-	/* Request that IRQ */
-	if (request_irq(harmony.dev->irq, harmony_interrupt, 0 ,"harmony", &harmony)) {
-		printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.dev->irq);
-		return -EFAULT;
-	}
-
-   	harmony.dsp_unit = register_sound_dsp(&harmony_audio_fops, -1);
-	if (harmony.dsp_unit < 0) {
-		printk(KERN_ERR PFX "Error registering dsp\n");
-		free_irq(harmony.dev->irq, &harmony);
-		return -EFAULT;
-	}
-	
-	/* Clear the buffers so you don't end up with crap in the buffers. */ 
-	harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-
-	/* Make sure this makes it to cache */
-	CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-
-	/* Clear out the silent buffer and flush to cache */
-	harmony_silence(&silent, 0, HARMONY_BUF_SIZE);
-	CHECK_WBACK_INV_OFFSET(silent, 0, HARMONY_BUF_SIZE);
-	
-	harmony.audio_open = 0;
-	
-	return 0;
-}
-
-
-/*
- * mixer functions 
- */
-
-static void harmony_mixer_set_gain(void)
-{
-	harmony_wait_CNTL();
-	gsc_writel(harmony.current_gain, &harmony.hpa->gainctl);
-}
-
-/* 
- *  Read gain of selected channel.
- *  The OSS rate is from 0 (silent) to 100 -> need some conversions
- *
- *  The harmony gain are attenuation for output and monitor gain.
- *                   is amplifaction for input gain
- */
-#define to_harmony_level(level,max) ((level)*max/100)
-#define to_oss_level(level,max) ((level)*100/max)
-
-static int harmony_mixer_get_level(int channel)
-{
-	int left_level;
-	int right_level;
-
-	switch (channel) {
-		case SOUND_MIXER_VOLUME:
-			left_level  = (harmony.current_gain & GAIN_LO_MASK) >> GAIN_LO_SHIFT;
-			right_level = (harmony.current_gain & GAIN_RO_MASK) >> GAIN_RO_SHIFT;
-			left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-			right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-			return (right_level << 8)+left_level;
-			
-		case SOUND_MIXER_IGAIN:
-			left_level = (harmony.current_gain & GAIN_LI_MASK) >> GAIN_LI_SHIFT;
-			right_level= (harmony.current_gain & GAIN_RI_MASK) >> GAIN_RI_SHIFT;
-			left_level = to_oss_level(left_level, MAX_INPUT_LEVEL);
-			right_level= to_oss_level(right_level, MAX_INPUT_LEVEL);
-			return (right_level << 8)+left_level;
-			
-		case SOUND_MIXER_MONITOR:
-			left_level = (harmony.current_gain & GAIN_MA_MASK) >> GAIN_MA_SHIFT;
-			left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL);
-			return (left_level << 8)+left_level;
-	}
-	return -EINVAL;
-}
-
-
-
-/*
- * Some conversions for the same reasons.
- * We give back the new real value(s) due to
- * the rescale.
- */
-
-static int harmony_mixer_set_level(int channel, int value)
-{
-	int left_level;
-	int right_level;
-	int new_left_level;
-	int new_right_level;
-
-	right_level = (value & 0x0000ff00) >> 8;
-	left_level = value & 0x000000ff;
-	if (right_level > 100) right_level = 100;
-	if (left_level > 100) left_level = 100;
-  
-	switch (channel) {
-		case SOUND_MIXER_VOLUME:
-			right_level = to_harmony_level(100-right_level, MAX_OUTPUT_LEVEL);
-			left_level  = to_harmony_level(100-left_level, MAX_OUTPUT_LEVEL);
-			new_right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-			new_left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-			harmony.current_gain = (harmony.current_gain & ~(GAIN_LO_MASK | GAIN_RO_MASK)) 
-					| (left_level << GAIN_LO_SHIFT) | (right_level << GAIN_RO_SHIFT);
-			harmony_mixer_set_gain();
-			return (new_right_level << 8) + new_left_level;
-			
-		case SOUND_MIXER_IGAIN:
-			right_level = to_harmony_level(right_level, MAX_INPUT_LEVEL);
-			left_level  = to_harmony_level(left_level, MAX_INPUT_LEVEL);
-			new_right_level = to_oss_level(right_level, MAX_INPUT_LEVEL);
-			new_left_level  = to_oss_level(left_level, MAX_INPUT_LEVEL);
-			harmony.current_gain = (harmony.current_gain & ~(GAIN_LI_MASK | GAIN_RI_MASK))
-					| (left_level << GAIN_LI_SHIFT) | (right_level << GAIN_RI_SHIFT);
-			harmony_mixer_set_gain();
-			return (new_right_level << 8) + new_left_level;
-	
-		case SOUND_MIXER_MONITOR:
-			left_level = to_harmony_level(100-left_level, MAX_MONITOR_LEVEL);
-			new_left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL);
-			harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK) | (left_level << GAIN_MA_SHIFT);
-			harmony_mixer_set_gain();
-			return (new_left_level << 8) + new_left_level;
-	}
-
-	return -EINVAL;
-}
-
-#undef to_harmony_level
-#undef to_oss_level
-
-/* 
- * Return the selected input device (mic or line)
- */
-
-static int harmony_mixer_get_recmask(void) 
-{
-	int current_input_line;
-	
-	current_input_line = (harmony.current_gain & GAIN_IS_MASK) 
-				    >> GAIN_IS_SHIFT;
-	if (current_input_line) 
-		return SOUND_MASK_MIC;
-
-	return SOUND_MASK_LINE;
-}
-
-/*
- * Set the input (only one at time, arbitrary priority to line in)
- */
-
-static int harmony_mixer_set_recmask(int recmask)
-{
-	int new_input_line;
-	int new_input_mask;
-	int current_input_line;
-	
-	current_input_line = (harmony.current_gain & GAIN_IS_MASK)
-				    >> GAIN_IS_SHIFT;
-	if ((current_input_line && ((recmask & SOUND_MASK_LINE) || !(recmask & SOUND_MASK_MIC))) ||
-		(!current_input_line && ((recmask & SOUND_MASK_LINE) && !(recmask & SOUND_MASK_MIC)))) {
-		new_input_line = 0;
-		new_input_mask = SOUND_MASK_LINE;
-	} else {
-		new_input_line = 1;
-		new_input_mask = SOUND_MASK_MIC;
-	}
-	harmony.current_gain = ((harmony.current_gain & ~GAIN_IS_MASK) | 
-				(new_input_line << GAIN_IS_SHIFT ));
-	harmony_mixer_set_gain();
-	return new_input_mask;
-}
-
-
-/* 
- * give the active outlines
- */
-
-static int harmony_mixer_get_outmask(void)
-{
-	int outmask = 0;
-	
-	if (harmony.current_gain & GAIN_SE_MASK) outmask |= MASK_INTERNAL;
-	if (harmony.current_gain & GAIN_LE_MASK) outmask |= MASK_LINEOUT;
-	if (harmony.current_gain & GAIN_HE_MASK) outmask |= MASK_HEADPHONES;
-	
-	return outmask;
-}
-
-
-static int harmony_mixer_set_outmask(int outmask)
-{
-	if (outmask & MASK_INTERNAL) 
-		harmony.current_gain |= GAIN_SE_MASK;
-	else 
-		harmony.current_gain &= ~GAIN_SE_MASK;
-	
-	if (outmask & MASK_LINEOUT) 
-		harmony.current_gain |= GAIN_LE_MASK;
-	else 
-		harmony.current_gain &= ~GAIN_LE_MASK;
-	
-	if (outmask & MASK_HEADPHONES) 
-		harmony.current_gain |= GAIN_HE_MASK; 
-	else 
-		harmony.current_gain &= ~GAIN_HE_MASK;
-	
-	harmony_mixer_set_gain();
-
-	return (outmask & (MASK_INTERNAL | MASK_LINEOUT | MASK_HEADPHONES));
-}
-
-/*
- * This code is inspired from sb_mixer.c
- */
-
-static int harmony_mixer_ioctl(struct inode * inode, struct file * file,
-		unsigned int cmd, unsigned long arg)
-{
-	int val;
-	int ret;
-
-	if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		memset(&info, 0, sizeof(info));
-                strncpy(info.id, "harmony", sizeof(info.id)-1);
-                strncpy(info.name, "Harmony audio", sizeof(info.name)-1);
-                info.modify_counter = 1; /* ? */
-                if (copy_to_user((void *)arg, &info, sizeof(info)))
-                        return -EFAULT;
-		return 0;
-	}
-	
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, (int *)arg);
-
-	/* read */
-	val = 0;
-	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-
-	switch (cmd) {
-	case MIXER_READ(SOUND_MIXER_CAPS):
-		ret = SOUND_CAP_EXCL_INPUT;
-		break;
-	case MIXER_READ(SOUND_MIXER_STEREODEVS):
-		ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN;
-		break;
-		
-	case MIXER_READ(SOUND_MIXER_RECMASK):
-		ret = SOUND_MASK_MIC | SOUND_MASK_LINE;
-		break;
-	case MIXER_READ(SOUND_MIXER_DEVMASK):
-		ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN |
-			SOUND_MASK_MONITOR;
-		break;
-	case MIXER_READ(SOUND_MIXER_OUTMASK):
-		ret = MASK_INTERNAL | MASK_LINEOUT |
-			MASK_HEADPHONES;
-		break;
-		
-	case MIXER_WRITE(SOUND_MIXER_RECSRC):
-		ret = harmony_mixer_set_recmask(val);
-		break;
-	case MIXER_READ(SOUND_MIXER_RECSRC):
-		ret = harmony_mixer_get_recmask();
-		break;
-	      
-	case MIXER_WRITE(SOUND_MIXER_OUTSRC):
-		ret = harmony_mixer_set_outmask(val);
-		break;
-	case MIXER_READ(SOUND_MIXER_OUTSRC):
-		ret = harmony_mixer_get_outmask();
-		break;
-	
-	case MIXER_WRITE(SOUND_MIXER_VOLUME):
-	case MIXER_WRITE(SOUND_MIXER_IGAIN):
-	case MIXER_WRITE(SOUND_MIXER_MONITOR):
-		ret = harmony_mixer_set_level(cmd & 0xff, val);
-		break;
-
-	case MIXER_READ(SOUND_MIXER_VOLUME):
-	case MIXER_READ(SOUND_MIXER_IGAIN):
-	case MIXER_READ(SOUND_MIXER_MONITOR):
-		ret = harmony_mixer_get_level(cmd & 0xff);
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	if (put_user(ret, (int *)arg))
-		return -EFAULT;
-	return 0;
-}
-
-
-static int harmony_mixer_open(struct inode *inode, struct file *file)
-{
-	if (harmony.mixer_open) 
-		return -EBUSY;
-	harmony.mixer_open = 1;
-	return 0;
-}
-
-static int harmony_mixer_release(struct inode *inode, struct file *file)
-{
-	if (!harmony.mixer_open) 
-		return -EBUSY;
-	harmony.mixer_open = 0;
-	return 0;
-}
-
-static struct file_operations harmony_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.open		= harmony_mixer_open,
-	.release	= harmony_mixer_release,
-	.ioctl		= harmony_mixer_ioctl,
-};
-
-
-/*
- * Mute all the output and reset Harmony.
- */
-
-static void __init harmony_mixer_reset(void)
-{
-	harmony.current_gain = GAIN_TOTAL_SILENCE;
-	harmony_mixer_set_gain();
-	harmony_wait_CNTL();
-	gsc_writel(1, &harmony.hpa->reset);
-	mdelay(50);		/* wait 50 ms */
-	gsc_writel(0, &harmony.hpa->reset);
-	harmony.current_gain = GAIN_DEFAULT;
-	harmony_mixer_set_gain();
-}
-
-static int __init harmony_mixer_init(void)
-{
-	/* Register the device file operations */
-	harmony.mixer_unit = register_sound_mixer(&harmony_mixer_fops, -1);
-	if (harmony.mixer_unit < 0) {
-		printk(KERN_WARNING PFX "Error Registering Mixer Driver\n");
-		return -EFAULT;
-	}
-  
-	harmony_mixer_reset();
-	harmony.mixer_open = 0;
-	
-	return 0;
-}
-
-
-
-/* 
- * This is the callback that's called by the inventory hardware code 
- * if it finds a match to the registered driver. 
- */
-static int __devinit
-harmony_driver_probe(struct parisc_device *dev)
-{
-	u8	id;
-	u8	rev;
-	u32	cntl;
-	int	ret;
-
-	if (harmony.hpa) {
-		/* We only support one Harmony at this time */
-		printk(KERN_ERR PFX "driver already registered\n");
-		return -EBUSY;
-	}
-
-	if (!dev->irq) {
-		printk(KERN_ERR PFX "no irq found\n");
-		return -ENODEV;
-	}
-
-	/* Set the HPA of harmony */
-	harmony.hpa = (struct harmony_hpa *)dev->hpa.start;
-	harmony.dev = dev;
-
-	/* Grab the ID and revision from the device */
-	id = gsc_readb(&harmony.hpa->id);
-	if ((id | 1) != 0x15) {
-		printk(KERN_WARNING PFX "wrong harmony id 0x%02x\n", id);
-		return -EBUSY;
-	}
-	cntl = gsc_readl(&harmony.hpa->cntl);
-	rev = (cntl>>20) & 0xff;
-
-	printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", "
-			"h/w id %i, rev. %i at 0x%lx, IRQ %i\n",
-			id, rev, dev->hpa.start, harmony.dev->irq);
-	
-	/* Make sure the control bit isn't set, although I don't think it 
-	   ever is. */
-	if (cntl & CNTL_C) {
-		printk(KERN_WARNING PFX "CNTL busy\n");
-		harmony.hpa = 0;
-		return -EBUSY;
-	}
-
-	/* Initialize the memory buffers */
-	if (harmony_alloc_buffer(&played_buf, MAX_BUFS) || 
-	    harmony_alloc_buffer(&recorded_buf, MAX_BUFS) ||
-	    harmony_alloc_buffer(&graveyard, 1) ||
-	    harmony_alloc_buffer(&silent, 1)) {
-		ret = -EBUSY;
-		goto out_err;
-	}
-
-	/* Initialize /dev/mixer and /dev/audio  */
-	if ((ret=harmony_mixer_init())) 
-		goto out_err;
-	if ((ret=harmony_audio_init())) 
-		goto out_err;
-
-	return 0;
-
-out_err:
-	harmony.hpa = 0;
-	harmony_free_buffer(&played_buf);
-	harmony_free_buffer(&recorded_buf);
-	harmony_free_buffer(&graveyard);
-	harmony_free_buffer(&silent);
-	return ret;
-}
-
-
-static struct parisc_device_id harmony_tbl[] = {
- /* { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, Bushmaster/Flounder */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, /* 712/715 Audio */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, /* Pace Audio */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, /* Outfield / Coral II */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(parisc, harmony_tbl);
-
-static struct parisc_driver harmony_driver = {
-	.name		= "Lasi Harmony",
-	.id_table	= harmony_tbl,
-	.probe		= harmony_driver_probe,
-};
-
-static int __init init_harmony(void)
-{
-	return register_parisc_driver(&harmony_driver);
-}
-
-static void __exit cleanup_harmony(void)
-{
-	free_irq(harmony.dev->irq, &harmony);
-	unregister_sound_mixer(harmony.mixer_unit);
-	unregister_sound_dsp(harmony.dsp_unit);
-	harmony_free_buffer(&played_buf);
-	harmony_free_buffer(&recorded_buf);
-	harmony_free_buffer(&graveyard);
-	harmony_free_buffer(&silent);
-	unregister_parisc_driver(&harmony_driver);
-}
-
-
-MODULE_AUTHOR("Alex DeVries <alex@onefishtwo.ca>");
-MODULE_DESCRIPTION("Harmony sound driver");
-MODULE_LICENSE("GPL");
-
-module_init(init_harmony);
-module_exit(cleanup_harmony);
-
diff --git a/sound/oss/ics2101.c b/sound/oss/ics2101.c
deleted file mode 100644
index d5f3be8..0000000
--- a/sound/oss/ics2101.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * sound/ics2101.c
- *
- * Driver for the ICS2101 mixer of GUS v3.7.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
- * Bartlomiej Zolnierkiewicz : added __init to ics2101_mixer_init()
- */
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include <linux/ultrasound.h>
-
-#include "gus.h"
-#include "gus_hw.h"
-
-#define MIX_DEVS	(SOUND_MASK_MIC|SOUND_MASK_LINE| \
-			 SOUND_MASK_SYNTH| \
-  			 SOUND_MASK_CD | SOUND_MASK_VOLUME)
-
-extern int     *gus_osp;
-extern int      gus_base;
-extern spinlock_t gus_lock;
-static int      volumes[ICS_MIXDEVS];
-static int      left_fix[ICS_MIXDEVS] =
-{1, 1, 1, 2, 1, 2};
-static int      right_fix[ICS_MIXDEVS] =
-{2, 2, 2, 1, 2, 1};
-
-static int scale_vol(int vol)
-{
-	/*
-	 *  Experimental volume scaling by Risto Kankkunen.
-	 *  This should give smoother volume response than just
-	 *  a plain multiplication.
-	 */
-	 
-	int e;
-
-	if (vol < 0)
-		vol = 0;
-	if (vol > 100)
-		vol = 100;
-	vol = (31 * vol + 50) / 100;
-	e = 0;
-	if (vol)
-	{
-		while (vol < 16)
-		{
-			vol <<= 1;
-			e--;
-		}
-		vol -= 16;
-		e += 7;
-	}
-	return ((e << 4) + vol);
-}
-
-static void write_mix(int dev, int chn, int vol)
-{
-	int *selector;
-	unsigned long flags;
-	int ctrl_addr = dev << 3;
-	int attn_addr = dev << 3;
-
-	vol = scale_vol(vol);
-
-	if (chn == CHN_LEFT)
-	{
-		selector = left_fix;
-		ctrl_addr |= 0x00;
-		attn_addr |= 0x02;
-	}
-	else
-	{
-		selector = right_fix;
-		ctrl_addr |= 0x01;
-		attn_addr |= 0x03;
-	}
-
-	spin_lock_irqsave(&gus_lock, flags);
-	outb((ctrl_addr), u_MixSelect);
-	outb((selector[dev]), u_MixData);
-	outb((attn_addr), u_MixSelect);
-	outb(((unsigned char) vol), u_MixData);
-	spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int set_volumes(int dev, int vol)
-{
-	int left = vol & 0x00ff;
-	int right = (vol >> 8) & 0x00ff;
-
-	if (left < 0)
-		left = 0;
-	if (left > 100)
-		left = 100;
-	if (right < 0)
-		right = 0;
-	if (right > 100)
-		right = 100;
-
-	write_mix(dev, CHN_LEFT, left);
-	write_mix(dev, CHN_RIGHT, right);
-
-	vol = left + (right << 8);
-	volumes[dev] = vol;
-	return vol;
-}
-
-static int ics2101_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-	int val;
-	
-	if (((cmd >> 8) & 0xff) == 'M') {
-		if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
-			
-			if (get_user(val, (int __user *)arg))
-				return -EFAULT;
-			switch (cmd & 0xff) {
-			case SOUND_MIXER_RECSRC:
-				return gus_default_mixer_ioctl(dev, cmd, arg);
-
-			case SOUND_MIXER_MIC:
-				val = set_volumes(DEV_MIC, val);
-				break;
-				
-			case SOUND_MIXER_CD:
-				val = set_volumes(DEV_CD, val);
-				break;
-
-			case SOUND_MIXER_LINE:
-				val = set_volumes(DEV_LINE, val);
-				break;
-
-			case SOUND_MIXER_SYNTH:
-				val = set_volumes(DEV_GF1, val);
-				break;
-
-			case SOUND_MIXER_VOLUME:
-				val = set_volumes(DEV_VOL, val);
-				break;
-
-			default:
-				return -EINVAL;
-			}
-			return put_user(val, (int __user *)arg);
-		} else {
-			switch (cmd & 0xff) {
-				/*
-				 * Return parameters
-				 */
-			case SOUND_MIXER_RECSRC:
-				return gus_default_mixer_ioctl(dev, cmd, arg);
-
-			case SOUND_MIXER_DEVMASK:
-				val = MIX_DEVS; 
-				break;
-
-			case SOUND_MIXER_STEREODEVS:
-				val = SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC; 
-				break;
-
-			case SOUND_MIXER_RECMASK:
-				val = SOUND_MASK_MIC | SOUND_MASK_LINE; 
-				break;
-				
-			case SOUND_MIXER_CAPS:
-				val = 0; 
-				break;
-
-			case SOUND_MIXER_MIC:
-				val = volumes[DEV_MIC];
-				break;
-				
-			case SOUND_MIXER_LINE:
-				val = volumes[DEV_LINE];
-				break;
-
-			case SOUND_MIXER_CD:
-				val = volumes[DEV_CD];
-				break;
-
-			case SOUND_MIXER_VOLUME:
-				val = volumes[DEV_VOL];
-				break;
-
-			case SOUND_MIXER_SYNTH:
-				val = volumes[DEV_GF1]; 
-				break;
-
-			default:
-				return -EINVAL;
-			}
-			return put_user(val, (int __user *)arg);
-		}
-	}
-	return -EINVAL;
-}
-
-static struct mixer_operations ics2101_mixer_operations =
-{
-	.owner	= THIS_MODULE,
-	.id	= "ICS2101",
-	.name	= "ICS2101 Multimedia Mixer",
-	.ioctl	= ics2101_mixer_ioctl
-};
-
-int __init ics2101_mixer_init(void)
-{
-	int i;
-	int n;
-
-	if ((n = sound_alloc_mixerdev()) != -1)
-	{
-		mixer_devs[n] = &ics2101_mixer_operations;
-
-		/*
-		 * Some GUS v3.7 cards had some channels flipped. Disable
-		 * the flipping feature if the model id is other than 5.
-		 */
-
-		if (inb(u_MixSelect) != 5)
-		{
-			for (i = 0; i < ICS_MIXDEVS; i++)
-				left_fix[i] = 1;
-			for (i = 0; i < ICS_MIXDEVS; i++)
-				right_fix[i] = 2;
-		}
-		set_volumes(DEV_GF1, 0x5a5a);
-		set_volumes(DEV_CD, 0x5a5a);
-		set_volumes(DEV_MIC, 0x0000);
-		set_volumes(DEV_LINE, 0x5a5a);
-		set_volumes(DEV_VOL, 0x5a5a);
-		set_volumes(DEV_UNUSED, 0x0000);
-	}
-	return n;
-}
diff --git a/sound/oss/ite8172.c b/sound/oss/ite8172.c
deleted file mode 100644
index 68aab36..0000000
--- a/sound/oss/ite8172.c
+++ /dev/null
@@ -1,2261 +0,0 @@
-/*
- *      ite8172.c  --  ITE IT8172G Sound Driver.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * Module command line parameters:
- *
- *  Supported devices:
- *  /dev/dsp    standard OSS /dev/dsp device
- *  /dev/mixer  standard OSS /dev/mixer device
- *
- * Notes:
- *
- *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
- *     taken, slightly modified or not at all, from the ES1371 driver,
- *     so refer to the credits in es1371.c for those. The rest of the
- *     code (probe, open, read, write, the ISR, etc.) is new.
- *  2. The following support is untested:
- *      * Memory mapping the audio buffers, and the ioctl controls that go
- *        with it.
- *      * S/PDIF output.
- *      * I2S support.
- *  3. The following is not supported:
- *      * legacy audio mode.
- *  4. Support for volume button interrupts is implemented but doesn't
- *     work yet.
- *
- *  Revision history
- *    02.08.2001  Initial release
- *    06.22.2001  Added I2S support
- *    07.30.2003  Removed initialisation to zero for static variables
- *		   (spdif[NR_DEVICE], i2s_fmt[NR_DEVICE], and devindex)
- */
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-#include <asm/it8172/it8172.h>
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define IT8172_DEBUG
-#undef IT8172_VERBOSE_DEBUG
-#define DBG(x) {}
-
-#define IT8172_MODULE_NAME "IT8172 audio"
-#define PFX IT8172_MODULE_NAME
-
-#ifdef IT8172_DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
-
-
-#define IT8172_MODULE_NAME "IT8172 audio"
-#define PFX IT8172_MODULE_NAME
-
-#ifdef IT8172_DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
-
-
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-
-/*
- * Audio Controller register bit definitions follow. See
- * include/asm/it8172/it8172.h for register offsets.
- */
-
-/* PCM Out Volume Reg */
-#define PCMOV_PCMOM	(1<<15)	/* PCM Out Mute default 1: mute */
-#define	PCMOV_PCMRCG_BIT 8	/* PCM Right channel Gain */
-#define	PCMOV_PCMRCG_MASK (0x1f<<PCMOV_PCMRCG_BIT)
-#define PCMOV_PCMLCG_BIT 0	/* PCM Left channel gain  */
-#define PCMOV_PCMLCG_MASK 0x1f
-
-/* FM Out Volume Reg */
-#define FMOV_FMOM       (1<<15)	/* FM Out Mute default 1: mute */
-#define	FMOV_FMRCG_BIT	8	/* FM Right channel Gain */
-#define	FMOV_FMRCG_MASK (0x1f<<FMOV_FMRCG_BIT)
-#define FMOV_FMLCG_BIT	0	/* FM Left channel gain  */
-#define FMOV_FMLCG_MASK 0x1f
-
-/* I2S Out Volume Reg */
-#define I2SV_I2SOM	 (1<<15) /* I2S Out Mute default 1: mute */
-#define	I2SV_I2SRCG_BIT	 8	 /* I2S Right channel Gain */
-#define	I2SV_I2SRCG_MASK (0x1f<<I2SV_I2SRCG_BIT)
-#define I2SV_I2SLCG_BIT	 0	 /* I2S Left channel gain  */
-#define I2SV_I2SLCG_MASK 0x1f
-
-/* Digital Recording Source Select Reg */
-#define	DRSS_BIT   0
-#define	DRSS_MASK  0x07
-#define   DRSS_AC97_PRIM 0
-#define   DRSS_FM        1
-#define   DRSS_I2S       2
-#define   DRSS_PCM       3
-#define   DRSS_AC97_SEC  4
-
-/* Playback/Capture Channel Control Registers */
-#define	CC_SM	        (1<<15)	/* Stereo, Mone 0: mono 1: stereo */
-#define	CC_DF	        (1<<14)	/* Data Format 0: 8 bit 1: 16 bit */
-#define CC_FMT_BIT      14
-#define CC_FMT_MASK     (0x03<<CC_FMT_BIT)
-#define CC_CF_BIT       12      /* Channel format (Playback only) */
-#define CC_CF_MASK      (0x03<<CC_CF_BIT)
-#define	  CC_CF_2	0
-#define   CC_CF_4	(1<<CC_CF_BIT)
-#define   CC_CF_6	(2<<CC_CF_BIT)
-#define CC_SR_BIT       8       /* sample Rate */
-#define CC_SR_MASK      (0x0f<<CC_SR_BIT)
-#define	  CC_SR_5500	0
-#define	  CC_SR_8000	(1<<CC_SR_BIT)
-#define	  CC_SR_9600	(2<<CC_SR_BIT)
-#define	  CC_SR_11025	(3<<CC_SR_BIT)
-#define	  CC_SR_16000	(4<<CC_SR_BIT)
-#define	  CC_SR_19200	(5<<CC_SR_BIT)
-#define	  CC_SR_22050	(6<<CC_SR_BIT)
-#define	  CC_SR_32000	(7<<CC_SR_BIT)
-#define	  CC_SR_38400	(8<<CC_SR_BIT)
-#define	  CC_SR_44100	(9<<CC_SR_BIT)
-#define	  CC_SR_48000	(10<<CC_SR_BIT)
-#define	CC_CSP	        (1<<7)	/* Channel stop 
-				 * 0: End of Current buffer
-				 * 1: Immediately stop when rec stop */
-#define CC_CP	        (1<<6)	/* Channel pause 0: normal, 1: pause */
-#define	CC_CA	        (1<<5)	/* Channel Action 0: Stop , 1: start */
-#define	CC_CB2L         (1<<2)	/* Cur. buf. 2 xfr is last 0: No, 1: Yes */
-#define CC_CB1L         (1<<1)	/* Cur. buf. 1 xfr is last 0: No, 1: Yes */
-#define CC_DE	        1	/* DFC/DFIFO Data Empty 1: empty, 0: not empty
-				 * (Playback only)
-				 */
-
-/* Codec Control Reg */
-#define CODECC_GME	(1<<9)	/* AC97 GPIO Mode enable */
-#define	CODECC_ATM	(1<<8)	/* AC97 ATE test mode 0: test 1: normal */
-#define	CODECC_WR	(1<<6)	/* AC97 Warn reset 1: warm reset , 0: Normal */
-#define	CODECC_CR	(1<<5)	/* AC97 Cold reset 1: Cold reset , 0: Normal */
-
-
-/* I2S Control Reg	*/
-#define	I2SMC_SR_BIT	 6	/* I2S Sampling rate 
-				 * 00: 48KHz, 01: 44.1 KHz, 10: 32 32 KHz */
-#define	I2SMC_SR_MASK    (0x03<<I2SMC_SR_BIT)
-#define	  I2SMC_SR_48000 0
-#define	  I2SMC_SR_44100 (1<<I2SMC_SR_BIT)
-#define	  I2SMC_SR_32000 (2<<I2SMC_SR_BIT)
-#define	I2SMC_SRSS	 (1<<5)	/* Sample Rate Source Select 1:S/W, 0: H/W */
-#define I2SMC_I2SF_BIT	 0	/* I2S Format */
-#define I2SMC_I2SF_MASK  0x03
-#define   I2SMC_I2SF_DAC 0
-#define   I2SMC_I2SF_ADC 2
-#define   I2SMC_I2SF_I2S 3
-
-
-/* Volume up, Down, Mute */
-#define	VS_VMP	(1<<2)	/* Volume mute 1: pushed, 0: not */
-#define	VS_VDP	(1<<1)	/* Volume Down 1: pushed, 0: not */
-#define VS_VUP	1	/* Volime Up 1: pushed, 0: not */
-
-/* SRC, Mixer test control/DFC status reg */
-#define SRCS_DPUSC      (1<<5)	/* DFC Playback underrun Status/clear */
-#define	SRCS_DCOSC	(1<<4)	/* DFC Capture Overrun Status/clear */
-#define SRCS_SIS	(1<<3)	/* SRC input select 1: Mixer, 0: Codec I/F */
-#define SRCS_CDIS_BIT	0	/* Codec Data Input Select */
-#define SRCS_CDIS_MASK  0x07
-#define   SRCS_CDIS_MIXER 0
-#define   SRCS_CDIS_PCM   1
-#define   SRCS_CDIS_I2S   2
-#define   SRCS_CDIS_FM    3
-#define   SRCS_CDIS_DFC   4
-
-
-/* Codec Index Reg command Port */
-#define CIRCP_CID_BIT   10
-#define CIRCP_CID_MASK  (0x03<<CIRCP_CID_BIT)
-#define CIRCP_CPS	(1<<9)	/* Command Port Status 0: ready, 1: busy */
-#define	CIRCP_DPVF	(1<<8)	/* Data Port Valid Flag 0: invalis, 1: valid */
-#define CIRCP_RWC	(1<<7)	/* Read/write command */
-#define CIRCP_CIA_BIT   0
-#define CIRCP_CIA_MASK  0x007F	/* Codec Index Address */
-
-/* Test Mode Control/Test group Select Control */
-
-/* General Control Reg */
-#define GC_VDC_BIT	6	/* Volume Division Control */
-#define GC_VDC_MASK     (0x03<<GC_VDC_BIT)
-#define   GC_VDC_NONE   0
-#define   GC_VDC_DIV2   (1<<GC_VDC_BIT)
-#define   GC_VDC_DIV4   (2<<GC_VDC_BIT)
-#define	GC_SOE	        (1<<2)	/* S/PDIF Output enable */
-#define	GC_SWR	        1	/* Software warn reset */
-
-/* Interrupt mask Control Reg */
-#define	IMC_VCIM	(1<<6)	/* Volume CNTL interrupt mask */
-#define	IMC_CCIM	(1<<1)	/* Capture Chan. iterrupt mask */
-#define	IMC_PCIM	1	/* Playback Chan. interrupt mask */
-
-/* Interrupt status/clear reg */
-#define	ISC_VCI	        (1<<6)	/* Volume CNTL interrupt 1: clears */
-#define	ISC_CCI	        (1<<1)	/* Capture Chan. interrupt 1: clears  */
-#define	ISC_PCI	        1	/* Playback Chan. interrupt 1: clears */
-
-/* misc stuff */
-#define POLL_COUNT   0x5000
-
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Define DIGITAL1 as the I2S channel, since it is not listed in
- * soundcard.h.
- */
-#define SOUND_MIXER_I2S        SOUND_MIXER_DIGITAL1
-#define SOUND_MASK_I2S         SOUND_MASK_DIGITAL1
-#define SOUND_MIXER_READ_I2S   MIXER_READ(SOUND_MIXER_I2S)
-#define SOUND_MIXER_WRITE_I2S  MIXER_WRITE(SOUND_MIXER_I2S)
-
-/* --------------------------------------------------------------------- */
-
-struct it8172_state {
-	/* list of it8172 devices */
-	struct list_head devs;
-
-	/* the corresponding pci_dev structure */
-	struct pci_dev *dev;
-
-	/* soundcore stuff */
-	int dev_audio;
-
-	/* hardware resources */
-	unsigned long io;
-	unsigned int irq;
-
-	/* PCI ID's */
-	u16 vendor;
-	u16 device;
-	u8 rev; /* the chip revision */
-
-	/* options */
-	int spdif_volume; /* S/PDIF output is enabled if != -1 */
-	int i2s_volume;   /* current I2S out volume, in OSS format */
-	int i2s_recording;/* 1 = recording from I2S, 0 = not */
-    
-#ifdef IT8172_DEBUG
-	/* debug /proc entry */
-	struct proc_dir_entry *ps;
-	struct proc_dir_entry *ac97_ps;
-#endif /* IT8172_DEBUG */
-
-	struct ac97_codec codec;
-
-	unsigned short pcc, capcc;
-	unsigned dacrate, adcrate;
-
-	spinlock_t lock;
-	struct mutex open_mutex;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-
-	struct dmabuf {
-		void *rawbuf;
-		dma_addr_t dmaaddr;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-		void* nextIn;
-		void* nextOut;
-		int count;
-		int curBufPtr;
-		unsigned total_bytes;
-		unsigned error; /* over/underrun */
-		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;
-		unsigned dmasize;
-		unsigned fragsamples;
-		/* OSS stuff */
-		unsigned mapped:1;
-		unsigned ready:1;
-		unsigned stopped:1;
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac, dma_adc;
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned r = 0;
-	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void it8172_delay(int msec)
-{
-	unsigned long tmo;
-	signed long tmo2;
-
-	if (in_interrupt())
-		return;
-    
-	tmo = jiffies + (msec*HZ)/1000;
-	for (;;) {
-		tmo2 = tmo - jiffies;
-		if (tmo2 <= 0)
-			break;
-		schedule_timeout(tmo2);
-	}
-}
-
-
-static unsigned short
-get_compat_rate(unsigned* rate)
-{
-	unsigned rate_out = *rate;
-	unsigned short sr;
-    
-	if (rate_out >= 46050) {
-		sr = CC_SR_48000; rate_out = 48000;
-	} else if (rate_out >= 41250) {
-		sr = CC_SR_44100; rate_out = 44100;
-	} else if (rate_out >= 35200) {
-		sr = CC_SR_38400; rate_out = 38400;
-	} else if (rate_out >= 27025) {
-		sr = CC_SR_32000; rate_out = 32000;
-	} else if (rate_out >= 20625) {
-		sr = CC_SR_22050; rate_out = 22050;
-	} else if (rate_out >= 17600) {
-		sr = CC_SR_19200; rate_out = 19200;
-	} else if (rate_out >= 13513) {
-		sr = CC_SR_16000; rate_out = 16000;
-	} else if (rate_out >= 10313) {
-		sr = CC_SR_11025; rate_out = 11025;
-	} else if (rate_out >= 8800) {
-		sr = CC_SR_9600; rate_out = 9600;
-	} else if (rate_out >= 6750) {
-		sr = CC_SR_8000; rate_out = 8000;
-	} else {
-		sr = CC_SR_5500; rate_out = 5500;
-	}
-
-	*rate = rate_out;
-	return sr;
-}
-
-static void set_adc_rate(struct it8172_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned short sr;
-    
-	sr = get_compat_rate(&rate);
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->capcc &= ~CC_SR_MASK;
-	s->capcc |= sr;
-	outw(s->capcc, s->io+IT_AC_CAPCC);
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	s->adcrate = rate;
-}
-
-
-static void set_dac_rate(struct it8172_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned short sr;
-    
-	sr = get_compat_rate(&rate);
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->pcc &= ~CC_SR_MASK;
-	s->pcc |= sr;
-	outw(s->pcc, s->io+IT_AC_PCC);
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	s->dacrate = rate;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
-	struct it8172_state *s = (struct it8172_state *)codec->private_data;
-	unsigned long flags;
-	unsigned short circp, data;
-	int i;
-    
-	spin_lock_irqsave(&s->lock, flags);
-
-	for (i = 0; i < POLL_COUNT; i++)
-		if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
-			break;
-	if (i == POLL_COUNT)
-		err("rdcodec: codec ready poll expired!");
-
-	circp = addr & CIRCP_CIA_MASK;
-	circp |= (codec->id << CIRCP_CID_BIT);
-	circp |= CIRCP_RWC; // read command
-	outw(circp, s->io+IT_AC_CIRCP);
-
-	/* now wait for the data */
-	for (i = 0; i < POLL_COUNT; i++)
-		if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)
-			break;
-	if (i == POLL_COUNT)
-		err("rdcodec: read poll expired!");
-
-	data = inw(s->io+IT_AC_CIRDP);
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	return data;
-}
-
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
-	struct it8172_state *s = (struct it8172_state *)codec->private_data;
-	unsigned long flags;
-	unsigned short circp;
-	int i;
-    
-	spin_lock_irqsave(&s->lock, flags);
-
-	for (i = 0; i < POLL_COUNT; i++)
-		if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
-			break;
-	if (i == POLL_COUNT)
-		err("wrcodec: codec ready poll expired!");
-
-	circp = addr & CIRCP_CIA_MASK;
-	circp |= (codec->id << CIRCP_CID_BIT);
-	circp &= ~CIRCP_RWC; // write command
-
-	outw(data,  s->io+IT_AC_CIRDP);  // send data first
-	outw(circp, s->io+IT_AC_CIRCP);
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void waitcodec(struct ac97_codec *codec)
-{
-	unsigned short temp;
-
-	/* codec_wait is used to wait for a ready state after
-	   an AC97_RESET. */
-	it8172_delay(10);
-
-	temp = rdcodec(codec, 0x26);
-
-	// If power down, power up
-	if (temp & 0x3f00) {
-		// Power on
-		wrcodec(codec, 0x26, 0);
-		it8172_delay(100);
-		// Reread
-		temp = rdcodec(codec, 0x26);
-	}
-    
-	// Check if Codec REF,ANL,DAC,ADC ready***/
-	if ((temp & 0x3f0f) != 0x000f) {
-		err("codec reg 26 status (0x%x) not ready!!", temp);
-		return;
-	}
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct it8172_state *s)
-{
-	struct dmabuf* db = &s->dma_adc;
-	unsigned long flags;
-	unsigned char imc;
-    
-	if (db->stopped)
-		return;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
-	s->capcc |= CC_CSP;
-	outw(s->capcc, s->io+IT_AC_CAPCC);
-    
-	// disable capture interrupt
-	imc = inb(s->io+IT_AC_IMC);
-	outb(imc | IMC_CCIM, s->io+IT_AC_IMC);
-
-	db->stopped = 1;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static inline void stop_dac(struct it8172_state *s)
-{
-	struct dmabuf* db = &s->dma_dac;
-	unsigned long flags;
-	unsigned char imc;
-    
-	if (db->stopped)
-		return;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	s->pcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
-	s->pcc |= CC_CSP;
-	outw(s->pcc, s->io+IT_AC_PCC);
-    
-	// disable playback interrupt
-	imc = inb(s->io+IT_AC_IMC);
-	outb(imc | IMC_PCIM, s->io+IT_AC_IMC);
-
-	db->stopped = 1;
-    
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_dac(struct it8172_state *s)
-{
-	struct dmabuf* db = &s->dma_dac;
-	unsigned long flags;
-	unsigned char imc;
-	unsigned long buf1, buf2;
-    
-	if (!db->stopped)
-		return;
-    
-	spin_lock_irqsave(&s->lock, flags);
-
-	// reset Buffer 1 and 2 pointers to nextOut and nextOut+fragsize
-	buf1 = virt_to_bus(db->nextOut);
-	buf2 = buf1 + db->fragsize;
-	if (buf2 >= db->dmaaddr + db->dmasize)
-		buf2 -= db->dmasize;
-    
-	outl(buf1, s->io+IT_AC_PCB1STA);
-	outl(buf2, s->io+IT_AC_PCB2STA);
-	db->curBufPtr = IT_AC_PCB1STA;
-    
-	// enable playback interrupt
-	imc = inb(s->io+IT_AC_IMC);
-	outb(imc & ~IMC_PCIM, s->io+IT_AC_IMC);
-
-	s->pcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
-	s->pcc |= CC_CA;
-	outw(s->pcc, s->io+IT_AC_PCC);
-    
-	db->stopped = 0;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_adc(struct it8172_state *s)
-{
-	struct dmabuf* db = &s->dma_adc;
-	unsigned long flags;
-	unsigned char imc;
-	unsigned long buf1, buf2;
-    
-	if (!db->stopped)
-		return;
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	// reset Buffer 1 and 2 pointers to nextIn and nextIn+fragsize
-	buf1 = virt_to_bus(db->nextIn);
-	buf2 = buf1 + db->fragsize;
-	if (buf2 >= db->dmaaddr + db->dmasize)
-		buf2 -= db->dmasize;
-    
-	outl(buf1, s->io+IT_AC_CAPB1STA);
-	outl(buf2, s->io+IT_AC_CAPB2STA);
-	db->curBufPtr = IT_AC_CAPB1STA;
-
-	// enable capture interrupt
-	imc = inb(s->io+IT_AC_IMC);
-	outb(imc & ~IMC_CCIM, s->io+IT_AC_IMC);
-
-	s->capcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
-	s->capcc |= CC_CA;
-	outw(s->capcc, s->io+IT_AC_CAPCC);
-    
-	db->stopped = 0;
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct it8172_state *s, struct dmabuf *db)
-{
-	struct page *page, *pend;
-
-	if (db->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(db->rawbuf +
-				    (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			ClearPageReserved(page);
-		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
-				    db->rawbuf, db->dmaaddr);
-	}
-	db->rawbuf = db->nextIn = db->nextOut = NULL;
-	db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct it8172_state *s, struct dmabuf *db,
-		       unsigned rate, unsigned fmt, unsigned reg)
-{
-	int order;
-	unsigned bytepersec;
-	unsigned bufs;
-	struct page *page, *pend;
-
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER;
-		     order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf =
-			     pci_alloc_consistent(s->dev,
-						  PAGE_SIZE << order,
-						  &db->dmaaddr)))
-				break;
-		if (!db->rawbuf)
-			return -ENOMEM;
-		db->buforder = order;
-		/* now mark the pages as reserved;
-		   otherwise remap_pfn_range doesn't do what we want */
-		pend = virt_to_page(db->rawbuf +
-				    (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			SetPageReserved(page);
-	}
-
-	db->count = 0;
-	db->nextIn = db->nextOut = db->rawbuf;
-    
-	bytepersec = rate << sample_shift[fmt];
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < bytepersec)
-			db->fragshift = ld2(bytepersec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(bytepersec/100/(db->subdivision ?
-						    db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3;
-	}
-	db->numfrag = bufs >> db->fragshift;
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->numfrag = bufs >> db->fragshift;
-	}
-	db->fragsize = 1 << db->fragshift;
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
-	db->fragsamples = db->fragsize >> sample_shift[fmt];
-	db->dmasize = db->numfrag << db->fragshift;
-	memset(db->rawbuf, (fmt & (CC_DF>>CC_FMT_BIT)) ? 0 : 0x80, bufs);
-    
-#ifdef IT8172_VERBOSE_DEBUG
-	dbg("rate=%d, fragsize=%d, numfrag=%d, dmasize=%d",
-	    rate, db->fragsize, db->numfrag, db->dmasize);
-#endif
-
-	// set data length register
-	outw(db->fragsize, s->io+reg+2);
-	db->ready = 1;
-
-	return 0;
-}
-
-static inline int prog_dmabuf_adc(struct it8172_state *s)
-{
-	stop_adc(s);
-	return prog_dmabuf(s, &s->dma_adc, s->adcrate,
-			   (s->capcc & CC_FMT_MASK) >> CC_FMT_BIT,
-			   IT_AC_CAPCC);
-}
-
-static inline int prog_dmabuf_dac(struct it8172_state *s)
-{
-	stop_dac(s);
-	return prog_dmabuf(s, &s->dma_dac, s->dacrate,
-			   (s->pcc & CC_FMT_MASK) >> CC_FMT_BIT,
-			   IT_AC_PCC);
-}
-
-
-/* hold spinlock for the following! */
-
-static irqreturn_t it8172_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct it8172_state *s = (struct it8172_state *)dev_id;
-	struct dmabuf* dac = &s->dma_dac;
-	struct dmabuf* adc = &s->dma_adc;
-	unsigned char isc, vs;
-	unsigned short vol, mute;
-	unsigned long newptr;
-    
-	spin_lock(&s->lock);
-
-	isc = inb(s->io+IT_AC_ISC);
-
-	/* fastpath out, to ease interrupt sharing */
-	if (!(isc & (ISC_VCI | ISC_CCI | ISC_PCI))) {
-		spin_unlock(&s->lock);
-		return IRQ_NONE;
-	}
-    
-	/* clear audio interrupts first */
-	outb(isc | ISC_VCI | ISC_CCI | ISC_PCI, s->io+IT_AC_ISC);
-    
-	/* handle volume button events (ignore if S/PDIF enabled) */
-	if ((isc & ISC_VCI) && s->spdif_volume == -1) {
-		vs = inb(s->io+IT_AC_VS);
-		outb(0, s->io+IT_AC_VS);
-		vol = inw(s->io+IT_AC_PCMOV);
-		mute = vol & PCMOV_PCMOM;
-		vol &= PCMOV_PCMLCG_MASK;
-		if ((vs & VS_VUP) && vol > 0)
-			vol--;
-		if ((vs & VS_VDP) && vol < 0x1f)
-			vol++;
-		vol |= (vol << PCMOV_PCMRCG_BIT);
-		if (vs & VS_VMP)
-			vol |= (mute ^ PCMOV_PCMOM);
-		outw(vol, s->io+IT_AC_PCMOV);
-	}
-    
-	/* update capture pointers */
-	if (isc & ISC_CCI) {
-		if (adc->count > adc->dmasize - adc->fragsize) {
-			// Overrun. Stop ADC and log the error
-			stop_adc(s);
-			adc->error++;
-			dbg("adc overrun");
-		} else {
-			newptr = virt_to_bus(adc->nextIn) + 2*adc->fragsize;
-			if (newptr >= adc->dmaaddr + adc->dmasize)
-				newptr -= adc->dmasize;
-	    
-			outl(newptr, s->io+adc->curBufPtr);
-			adc->curBufPtr = (adc->curBufPtr == IT_AC_CAPB1STA) ?
-				IT_AC_CAPB2STA : IT_AC_CAPB1STA;
-	    
-			adc->nextIn += adc->fragsize;
-			if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-				adc->nextIn -= adc->dmasize;
-	    
-			adc->count += adc->fragsize;
-			adc->total_bytes += adc->fragsize;
-
-			/* wake up anybody listening */
-			if (waitqueue_active(&adc->wait))
-				wake_up_interruptible(&adc->wait);
-		}
-	}
-    
-	/* update playback pointers */
-	if (isc & ISC_PCI) {
-		newptr = virt_to_bus(dac->nextOut) + 2*dac->fragsize;
-		if (newptr >= dac->dmaaddr + dac->dmasize)
-			newptr -= dac->dmasize;
-	
-		outl(newptr, s->io+dac->curBufPtr);
-		dac->curBufPtr = (dac->curBufPtr == IT_AC_PCB1STA) ?
-			IT_AC_PCB2STA : IT_AC_PCB1STA;
-	
-		dac->nextOut += dac->fragsize;
-		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-			dac->nextOut -= dac->dmasize;
-	
-		dac->count -= dac->fragsize;
-		dac->total_bytes += dac->fragsize;
-
-		/* wake up anybody listening */
-		if (waitqueue_active(&dac->wait))
-			wake_up_interruptible(&dac->wait);
-	
-		if (dac->count <= 0)
-			stop_dac(s);
-	}
-    
-	spin_unlock(&s->lock);
-	return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int it8172_open_mixdev(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	struct list_head *list;
-	struct it8172_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct it8172_state, devs);
-		if (s->codec.dev_mixer == minor)
-			break;
-	}
-	file->private_data = s;
-	return nonseekable_open(inode, file);
-}
-
-static int it8172_release_mixdev(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-
-static u16
-cvt_ossvol(unsigned int gain)
-{
-	u16 ret;
-    
-	if (gain == 0)
-		return 0;
-    
-	if (gain > 100)
-		gain = 100;
-    
-	ret = (100 - gain + 32) / 4;
-	ret = ret > 31 ? 31 : ret;
-	return ret;
-}
-
-
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
-			unsigned long arg)
-{
-	struct it8172_state *s = (struct it8172_state *)codec->private_data;
-	unsigned int left, right;
-	unsigned long flags;
-	int val;
-	u16 vol;
-    
-	/*
-	 * When we are in S/PDIF mode, we want to disable any analog output so
-	 * we filter the master/PCM channel volume ioctls.
-	 *
-	 * Also filter I2S channel, which AC'97 knows nothing about.
-	 */
-
-	switch (cmd) {
-	case SOUND_MIXER_WRITE_VOLUME:
-		// if not in S/PDIF mode, pass to AC'97
-		if (s->spdif_volume == -1)
-			break;
-		return 0;
-	case SOUND_MIXER_WRITE_PCM:
-		// if not in S/PDIF mode, pass to AC'97
-		if (s->spdif_volume == -1)
-			break;
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		right = ((val >> 8)  & 0xff);
-		left = (val  & 0xff);
-		if (right > 100)
-			right = 100;
-		if (left > 100)
-			left = 100;
-		s->spdif_volume = (right << 8) | left;
-		vol = cvt_ossvol(left);
-		vol |= (cvt_ossvol(right) << PCMOV_PCMRCG_BIT);
-		if (vol == 0)
-			vol = PCMOV_PCMOM; // mute
-		spin_lock_irqsave(&s->lock, flags);
-		outw(vol, s->io+IT_AC_PCMOV);
-		spin_unlock_irqrestore(&s->lock, flags);
-		return put_user(s->spdif_volume, (int *)arg);
-	case SOUND_MIXER_READ_PCM:
-		// if not in S/PDIF mode, pass to AC'97
-		if (s->spdif_volume == -1)
-			break;
-		return put_user(s->spdif_volume, (int *)arg);
-	case SOUND_MIXER_WRITE_I2S:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		right = ((val >> 8)  & 0xff);
-		left = (val  & 0xff);
-		if (right > 100)
-			right = 100;
-		if (left > 100)
-			left = 100;
-		s->i2s_volume = (right << 8) | left;
-		vol = cvt_ossvol(left);
-		vol |= (cvt_ossvol(right) << I2SV_I2SRCG_BIT);
-		if (vol == 0)
-			vol = I2SV_I2SOM; // mute
-		outw(vol, s->io+IT_AC_I2SV);
-		return put_user(s->i2s_volume, (int *)arg);
-	case SOUND_MIXER_READ_I2S:
-		return put_user(s->i2s_volume, (int *)arg);
-	case SOUND_MIXER_WRITE_RECSRC:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val & SOUND_MASK_I2S) {
-			s->i2s_recording = 1;
-			outb(DRSS_I2S, s->io+IT_AC_DRSS);
-			return 0;
-		} else {
-			s->i2s_recording = 0;
-			outb(DRSS_AC97_PRIM, s->io+IT_AC_DRSS);
-			// now let AC'97 select record source
-			break;
-		}
-	case SOUND_MIXER_READ_RECSRC:
-		if (s->i2s_recording)
-			return put_user(SOUND_MASK_I2S, (int *)arg);
-		else
-			// let AC'97 report recording source
-			break;
-	}
-
-	return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int it8172_ioctl_mixdev(struct inode *inode, struct file *file,
-			       unsigned int cmd, unsigned long arg)
-{
-	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	struct ac97_codec *codec = &s->codec;
-
-	return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const*/ struct file_operations it8172_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= it8172_ioctl_mixdev,
-	.open		= it8172_open_mixdev,
-	.release	= it8172_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct it8172_state *s, int nonblock)
-{
-	unsigned long flags;
-	int count, tmo;
-	
-	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
-		return 0;
-
-	for (;;) {
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-			break;
-		//if (nonblock)
-		//return -EBUSY;
-		tmo = 1000 * count / s->dacrate;
-		tmo >>= sample_shift[(s->pcc & CC_FMT_MASK) >> CC_FMT_BIT];
-		it8172_delay(tmo);
-	}
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-
-/*
- * Copy audio data to/from user buffer from/to dma buffer, taking care
- * that we wrap when reading/writing the dma buffer. Returns actual byte
- * count written to or read from the dma buffer.
- */
-static int copy_dmabuf_user(struct dmabuf *db, char* userbuf,
-			    int count, int to_user)
-{
-	char* bufptr = to_user ? db->nextOut : db->nextIn;
-	char* bufend = db->rawbuf + db->dmasize;
-	
-	if (bufptr + count > bufend) {
-		int partial = (int)(bufend - bufptr);
-		if (to_user) {
-			if (copy_to_user(userbuf, bufptr, partial))
-				return -EFAULT;
-			if (copy_to_user(userbuf + partial, db->rawbuf,
-					 count - partial))
-				return -EFAULT;
-		} else {
-			if (copy_from_user(bufptr, userbuf, partial))
-				return -EFAULT;
-			if (copy_from_user(db->rawbuf,
-					   userbuf + partial,
-					   count - partial))
-				return -EFAULT;
-		}
-	} else {
-		if (to_user) {
-			if (copy_to_user(userbuf, bufptr, count))
-				return -EFAULT;
-		} else {
-			if (copy_from_user(bufptr, userbuf, count))
-				return -EFAULT;
-		}
-	}
-	
-	return count;
-}
-
-
-static ssize_t it8172_read(struct file *file, char *buffer,
-			   size_t count, loff_t *ppos)
-{
-	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	struct dmabuf *db = &s->dma_adc;
-	ssize_t ret;
-	unsigned long flags;
-	int cnt, remainder, avail;
-
-	if (db->mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-
-	while (count > 0) {
-		// wait for samples in capture buffer
-		do {
-			spin_lock_irqsave(&s->lock, flags);
-			if (db->stopped)
-				start_adc(s);
-			avail = db->count;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (avail <= 0) {
-				if (file->f_flags & O_NONBLOCK) {
-					if (!ret)
-						ret = -EAGAIN;
-					return ret;
-				}
-				interruptible_sleep_on(&db->wait);
-				if (signal_pending(current)) {
-					if (!ret)
-						ret = -ERESTARTSYS;
-					return ret;
-				}
-			}
-		} while (avail <= 0);
-
-		// copy from nextOut to user
-		if ((cnt = copy_dmabuf_user(db, buffer, count > avail ?
-					    avail : count, 1)) < 0) {
-			if (!ret)
-				ret = -EFAULT;
-			return ret;
-		}
-
-		spin_lock_irqsave(&s->lock, flags);
-		db->count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-
-		db->nextOut += cnt;
-		if (db->nextOut >= db->rawbuf + db->dmasize)
-			db->nextOut -= db->dmasize;	
-
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-	} // while (count > 0)
-
-	/*
-	 * See if the dma buffer count after this read call is
-	 * aligned on a fragsize boundary. If not, read from
-	 * buffer until we reach a boundary, and let's hope this
-	 * is just the last remainder of an audio record. If not
-	 * it means the user is not reading in fragsize chunks, in
-	 * which case it's his/her fault that there are audio gaps
-	 * in their record.
-	 */
-	spin_lock_irqsave(&s->lock, flags);
-	remainder = db->count % db->fragsize;
-	if (remainder) {
-		db->nextOut += remainder;
-		if (db->nextOut >= db->rawbuf + db->dmasize)
-			db->nextOut -= db->dmasize;
-		db->count -= remainder;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	return ret;
-}
-
-static ssize_t it8172_write(struct file *file, const char *buffer,
-			    size_t count, loff_t *ppos)
-{
-	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	struct dmabuf *db = &s->dma_dac;
-	ssize_t ret;
-	unsigned long flags;
-	int cnt, remainder, avail;
-
-	if (db->mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-    
-	while (count > 0) {
-		// wait for space in playback buffer
-		do {
-			spin_lock_irqsave(&s->lock, flags);
-			avail = db->dmasize - db->count;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (avail <= 0) {
-				if (file->f_flags & O_NONBLOCK) {
-					if (!ret)
-						ret = -EAGAIN;
-					return ret;
-				}
-				interruptible_sleep_on(&db->wait);
-				if (signal_pending(current)) {
-					if (!ret)
-						ret = -ERESTARTSYS;
-					return ret;
-				}
-			}
-		} while (avail <= 0);
-	
-		// copy to nextIn
-		if ((cnt = copy_dmabuf_user(db, (char*)buffer,
-					    count > avail ?
-					    avail : count, 0)) < 0) {
-			if (!ret)
-				ret = -EFAULT;
-			return ret;
-		}
-
-		spin_lock_irqsave(&s->lock, flags);
-		db->count += cnt;
-		if (db->stopped)
-			start_dac(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	
-		db->nextIn += cnt;
-		if (db->nextIn >= db->rawbuf + db->dmasize)
-			db->nextIn -= db->dmasize;
-	
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-	} // while (count > 0)
-	
-	/*
-	 * See if the dma buffer count after this write call is
-	 * aligned on a fragsize boundary. If not, fill buffer
-	 * with silence to the next boundary, and let's hope this
-	 * is just the last remainder of an audio playback. If not
-	 * it means the user is not sending us fragsize chunks, in
-	 * which case it's his/her fault that there are audio gaps
-	 * in their playback.
-	 */
-	spin_lock_irqsave(&s->lock, flags);
-	remainder = db->count % db->fragsize;
-	if (remainder) {
-		int fill_cnt = db->fragsize - remainder;
-		memset(db->nextIn, 0, fill_cnt);
-		db->nextIn += fill_cnt;
-		if (db->nextIn >= db->rawbuf + db->dmasize)
-			db->nextIn -= db->dmasize;
-		db->count += fill_cnt;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int it8172_poll(struct file *file,
-				struct poll_table_struct *wait)
-{
-	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready)
-			return 0;
-		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready)
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-	
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed)s->dma_dac.dmasize >=
-			    s->dma_dac.count + (signed)s->dma_dac.fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int it8172_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	struct dmabuf *db;
-	unsigned long size;
-
-	lock_kernel();
-	if (vma->vm_flags & VM_WRITE)
-		db = &s->dma_dac;
-	else if (vma->vm_flags & VM_READ)
-		db = &s->dma_adc;
-	else {
-		unlock_kernel();
-		return -EINVAL;
-	}
-	if (vma->vm_pgoff != 0) {
-		unlock_kernel();
-		return -EINVAL;
-	}
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder)) {
-		unlock_kernel();
-		return -EINVAL;
-	}
-	if (remap_pfn_range(vma, vma->vm_start,
-			     virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-			     size, vma->vm_page_prot)) {
-		unlock_kernel();
-		return -EAGAIN;
-	}
-	db->mapped = 1;
-	unlock_kernel();
-	return 0;
-}
-
-
-#ifdef IT8172_VERBOSE_DEBUG
-static struct ioctl_str_t {
-	unsigned int cmd;
-	const char* str;
-} ioctl_str[] = {
-	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
-	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
-	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
-	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
-	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
-	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
-	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
-	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
-	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
-	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
-	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
-	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
-	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
-	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
-	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
-	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
-	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
-	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
-	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
-	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
-	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
-	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
-	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
-	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
-	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
-	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
-	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
-	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
-	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
-	{OSS_GETVERSION, "OSS_GETVERSION"},
-	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
-	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
-	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
-	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
-};
-#endif    
-
-static int it8172_ioctl(struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg)
-{
-	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	unsigned long flags;
-	audio_buf_info abinfo;
-	count_info cinfo;
-	int count;
-	int val, mapped, ret, diff;
-
-	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-
-#ifdef IT8172_VERBOSE_DEBUG
-	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
-		if (ioctl_str[count].cmd == cmd)
-			break;
-	}
-	if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
-		dbg("ioctl %s, arg=0x%08x",
-		    ioctl_str[count].str, (unsigned int)arg);
-	else
-		dbg("ioctl unknown, 0x%x", cmd);
-#endif
-    
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, (int *)arg);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s, file->f_flags & O_NONBLOCK);
-		return 0;
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
-		
-	case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq(s->irq);
-			s->dma_dac.count = s->dma_dac.total_bytes = 0;
-			s->dma_dac.nextIn = s->dma_dac.nextOut =
-				s->dma_dac.rawbuf;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->irq);
-			s->dma_adc.count = s->dma_adc.total_bytes = 0;
-			s->dma_adc.nextIn = s->dma_adc.nextOut =
-				s->dma_adc.rawbuf;
-		}
-		return 0;
-
-	case SNDCTL_DSP_SPEED:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val >= 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				set_adc_rate(s, val);
-				if ((ret = prog_dmabuf_adc(s)))
-					return ret;
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				set_dac_rate(s, val);
-				if ((ret = prog_dmabuf_dac(s)))
-					return ret;
-			}
-		}
-		return put_user((file->f_mode & FMODE_READ) ?
-				s->adcrate : s->dacrate, (int *)arg);
-
-	case SNDCTL_DSP_STEREO:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			if (val)
-				s->capcc |= CC_SM;
-			else
-				s->capcc &= ~CC_SM;
-			outw(s->capcc, s->io+IT_AC_CAPCC);
-			if ((ret = prog_dmabuf_adc(s)))
-				return ret;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			if (val)
-				s->pcc |= CC_SM;
-			else
-				s->pcc &= ~CC_SM;
-			outw(s->pcc, s->io+IT_AC_PCC);
-			if ((ret = prog_dmabuf_dac(s)))
-				return ret;
-		}
-		return 0;
-
-	case SNDCTL_DSP_CHANNELS:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val != 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				if (val >= 2) {
-					val = 2;
-					s->capcc |= CC_SM;
-				}
-				else
-					s->capcc &= ~CC_SM;
-				outw(s->capcc, s->io+IT_AC_CAPCC);
-				if ((ret = prog_dmabuf_adc(s)))
-					return ret;
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				switch (val) {
-				case 1:
-					s->pcc &= ~CC_SM;
-					break;
-				case 2:
-					s->pcc |= CC_SM;
-					break;
-				default:
-					// FIX! support multichannel???
-					val = 2;
-					s->pcc |= CC_SM;
-					break;
-				}
-				outw(s->pcc, s->io+IT_AC_PCC);
-				if ((ret = prog_dmabuf_dac(s)))
-					return ret;
-			}
-		}
-		return put_user(val, (int *)arg);
-		
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-		return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
-		
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				if (val == AFMT_S16_LE)
-					s->capcc |= CC_DF;
-				else {
-					val = AFMT_U8;
-					s->capcc &= ~CC_DF;
-				}
-				outw(s->capcc, s->io+IT_AC_CAPCC);
-				if ((ret = prog_dmabuf_adc(s)))
-					return ret;
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				if (val == AFMT_S16_LE)
-					s->pcc |= CC_DF;
-				else {
-					val = AFMT_U8;
-					s->pcc &= ~CC_DF;
-				}
-				outw(s->pcc, s->io+IT_AC_PCC);
-				if ((ret = prog_dmabuf_dac(s)))
-					return ret;
-			}
-		} else {
-			if (file->f_mode & FMODE_READ)
-				val = (s->capcc & CC_DF) ?
-					AFMT_S16_LE : AFMT_U8;
-			else
-				val = (s->pcc & CC_DF) ?
-					AFMT_S16_LE : AFMT_U8;
-		}
-		return put_user(val, (int *)arg);
-		
-	case SNDCTL_DSP_POST:
-		return 0;
-
-	case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		spin_lock_irqsave(&s->lock, flags);
-		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
-			val |= PCM_ENABLE_OUTPUT;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return put_user(val, (int *)arg);
-		
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT)
-				start_adc(s);
-			else
-				stop_adc(s);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT)
-				start_dac(s);
-			else
-				stop_dac(s);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		abinfo.fragsize = s->dma_dac.fragsize;
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		if (!s->dma_dac.stopped)
-			count -= (s->dma_dac.fragsize -
-				  inw(s->io+IT_AC_PCDL));
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		abinfo.bytes = s->dma_dac.dmasize - count;
-		abinfo.fragstotal = s->dma_dac.numfrag;
-		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ?
-			-EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		abinfo.fragsize = s->dma_adc.fragsize;
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_adc.count;
-		if (!s->dma_adc.stopped)
-			count += (s->dma_adc.fragsize -
-				  inw(s->io+IT_AC_CAPCDL));
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		abinfo.bytes = count;
-		abinfo.fragstotal = s->dma_adc.numfrag;
-		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ?
-			-EFAULT : 0;
-		
-	case SNDCTL_DSP_NONBLOCK:
-		file->f_flags |= O_NONBLOCK;
-		return 0;
-
-	case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		if (!s->dma_dac.stopped)
-			count -= (s->dma_dac.fragsize -
-				  inw(s->io+IT_AC_PCDL));
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		return put_user(count, (int *)arg);
-
-	case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		cinfo.bytes = s->dma_adc.total_bytes;
-		count = s->dma_adc.count;
-		if (!s->dma_adc.stopped) {
-			diff = s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL);
-			count += diff;
-			cinfo.bytes += diff;
-			cinfo.ptr = inl(s->io+s->dma_adc.curBufPtr) -
-				s->dma_adc.dmaaddr;
-		} else
-			cinfo.ptr = virt_to_bus(s->dma_adc.nextIn) -
-				s->dma_adc.dmaaddr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		cinfo.blocks = count >> s->dma_adc.fragshift;
-		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-	case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		spin_lock_irqsave(&s->lock, flags);
-		cinfo.bytes = s->dma_dac.total_bytes;
-		count = s->dma_dac.count;
-		if (!s->dma_dac.stopped) {
-			diff = s->dma_dac.fragsize - inw(s->io+IT_AC_CAPCDL);
-			count -= diff;
-			cinfo.bytes += diff;
-			cinfo.ptr = inl(s->io+s->dma_dac.curBufPtr) -
-				s->dma_dac.dmaaddr;
-		} else
-			cinfo.ptr = virt_to_bus(s->dma_dac.nextOut) -
-				s->dma_dac.dmaaddr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= s->dma_dac.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		cinfo.blocks = count >> s->dma_dac.fragshift;
-		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE)
-			return put_user(s->dma_dac.fragsize, (int *)arg);
-		else
-			return put_user(s->dma_adc.fragsize, (int *)arg);
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-			if ((ret = prog_dmabuf_adc(s)))
-				return ret;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.ossfragshift = val & 0xffff;
-			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac.ossfragshift < 4)
-				s->dma_dac.ossfragshift = 4;
-			if (s->dma_dac.ossfragshift > 15)
-				s->dma_dac.ossfragshift = 15;
-			if (s->dma_dac.ossmaxfrags < 4)
-				s->dma_dac.ossmaxfrags = 4;
-			if ((ret = prog_dmabuf_dac(s)))
-				return ret;
-		}
-		return 0;
-
-	case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-			return -EINVAL;
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.subdivision = val;
-			if ((ret = prog_dmabuf_adc(s)))
-				return ret;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.subdivision = val;
-			if ((ret = prog_dmabuf_dac(s)))
-				return ret;
-		}
-		return 0;
-
-	case SOUND_PCM_READ_RATE:
-		return put_user((file->f_mode & FMODE_READ) ?
-				s->adcrate : s->dacrate, (int *)arg);
-
-	case SOUND_PCM_READ_CHANNELS:
-		if (file->f_mode & FMODE_READ)
-			return put_user((s->capcc & CC_SM) ? 2 : 1,
-					(int *)arg);
-		else
-			return put_user((s->pcc & CC_SM) ? 2 : 1,
-					(int *)arg);
-	    
-	case SOUND_PCM_READ_BITS:
-		if (file->f_mode & FMODE_READ)
-			return put_user((s->capcc & CC_DF) ? 16 : 8,
-					(int *)arg);
-		else
-			return put_user((s->pcc & CC_DF) ? 16 : 8,
-					(int *)arg);
-
-	case SOUND_PCM_WRITE_FILTER:
-	case SNDCTL_DSP_SETSYNCRO:
-	case SOUND_PCM_READ_FILTER:
-		return -EINVAL;
-	}
-
-	return mixdev_ioctl(&s->codec, cmd, arg);
-}
-
-
-static int it8172_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct it8172_state *s;
-	int ret;
-    
-#ifdef IT8172_VERBOSE_DEBUG
-	if (file->f_flags & O_NONBLOCK)
-		dbg("%s: non-blocking", __FUNCTION__);
-	else
-		dbg("%s: blocking", __FUNCTION__);
-#endif
-	
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct it8172_state, devs);
-		if (!((s->dev_audio ^ minor) & ~0xf))
-			break;
-	}
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & file->f_mode) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-
-	spin_lock_irqsave(&s->lock, flags);
-
-	if (file->f_mode & FMODE_READ) {
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
-		s->capcc &= ~(CC_SM | CC_DF);
-		set_adc_rate(s, 8000);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->capcc |= CC_DF;
-		outw(s->capcc, s->io+IT_AC_CAPCC);
-		if ((ret = prog_dmabuf_adc(s))) {
-			spin_unlock_irqrestore(&s->lock, flags);
-			return ret;
-		}
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
-		s->pcc &= ~(CC_SM | CC_DF);
-		set_dac_rate(s, 8000);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->pcc |= CC_DF;
-		outw(s->pcc, s->io+IT_AC_PCC);
-		if ((ret = prog_dmabuf_dac(s))) {
-			spin_unlock_irqrestore(&s->lock, flags);
-			return ret;
-		}
-	}
-    
-	spin_unlock_irqrestore(&s->lock, flags);
-
-	s->open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int it8172_release(struct inode *inode, struct file *file)
-{
-	struct it8172_state *s = (struct it8172_state *)file->private_data;
-
-#ifdef IT8172_VERBOSE_DEBUG
-	dbg("%s", __FUNCTION__);
-#endif
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-		dealloc_dmabuf(s, &s->dma_dac);
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-	}
-	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
-	mutex_unlock(&s->open_mutex);
-	wake_up(&s->open_wait);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations it8172_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= it8172_read,
-	.write		= it8172_write,
-	.poll		= it8172_poll,
-	.ioctl		= it8172_ioctl,
-	.mmap		= it8172_mmap,
-	.open		= it8172_open,
-	.release	= it8172_release,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef IT8172_DEBUG
-static int proc_it8172_dump (char *buf, char **start, off_t fpos,
-			     int length, int *eof, void *data)
-{
-	struct it8172_state *s;
-	int cnt, len = 0;
-
-	if (list_empty(&devs))
-		return 0;
-	s = list_entry(devs.next, struct it8172_state, devs);
-
-	/* print out header */
-	len += sprintf(buf + len, "\n\t\tIT8172 Audio Debug\n\n");
-
-	// print out digital controller state
-	len += sprintf (buf + len, "IT8172 Audio Controller registers\n");
-	len += sprintf (buf + len, "---------------------------------\n");
-	cnt=0;
-	while (cnt < 0x72) {
-		if (cnt == IT_AC_PCB1STA || cnt == IT_AC_PCB2STA ||
-		    cnt == IT_AC_CAPB1STA || cnt == IT_AC_CAPB2STA ||
-		    cnt == IT_AC_PFDP) {
-			len+= sprintf (buf + len, "reg %02x = %08x\n",
-				       cnt, inl(s->io+cnt));
-			cnt += 4;
-		} else {
-			len+= sprintf (buf + len, "reg %02x = %04x\n",
-				       cnt, inw(s->io+cnt));
-			cnt += 2;
-		}
-	}
-    
-	/* print out CODEC state */
-	len += sprintf (buf + len, "\nAC97 CODEC registers\n");
-	len += sprintf (buf + len, "----------------------\n");
-	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
-		len+= sprintf (buf + len, "reg %02x = %04x\n",
-			       cnt, rdcodec(&s->codec, cnt));
-
-	if (fpos >=len){
-		*start = buf;
-		*eof =1;
-		return 0;
-	}
-	*start = buf + fpos;
-	if ((len -= fpos) > length)
-		return length;
-	*eof =1;
-	return len;
-
-}
-#endif /* IT8172_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int spdif[NR_DEVICE];
-static int i2s_fmt[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(spdif, int, NULL, 0);
-MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled");
-module_param_array(i2s_fmt, int, NULL, 0);
-MODULE_PARM_DESC(i2s_fmt, "the format of I2S");
-
-MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
-MODULE_DESCRIPTION("IT8172 Audio Driver");
-
-/* --------------------------------------------------------------------- */
-
-static int __devinit it8172_probe(struct pci_dev *pcidev,
-				  const struct pci_device_id *pciid)
-{
-	struct it8172_state *s;
-	int i, val;
-	unsigned short pcisr, vol;
-	unsigned char legacy, imc;
-	char proc_str[80];
-    
-	if (pcidev->irq == 0) 
-		return -1;
-
-	if (!(s = kmalloc(sizeof(struct it8172_state), GFP_KERNEL))) {
-		err("alloc of device struct failed");
-		return -1;
-	}
-	
-	memset(s, 0, sizeof(struct it8172_state));
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac.wait);
-	init_waitqueue_head(&s->open_wait);
-	mutex_init(&s->open_mutex);
-	spin_lock_init(&s->lock);
-	s->dev = pcidev;
-	s->io = pci_resource_start(pcidev, 0);
-	s->irq = pcidev->irq;
-	s->vendor = pcidev->vendor;
-	s->device = pcidev->device;
-	pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
-	s->codec.private_data = s;
-	s->codec.id = 0;
-	s->codec.codec_read = rdcodec;
-	s->codec.codec_write = wrcodec;
-	s->codec.codec_wait = waitcodec;
-
-	if (!request_region(s->io, pci_resource_len(pcidev,0),
-			    IT8172_MODULE_NAME)) {
-		err("io ports %#lx->%#lx in use",
-		    s->io, s->io + pci_resource_len(pcidev,0)-1);
-		goto err_region;
-	}
-	if (request_irq(s->irq, it8172_interrupt, IRQF_DISABLED,
-			IT8172_MODULE_NAME, s)) {
-		err("irq %u in use", s->irq);
-		goto err_irq;
-	}
-
-	info("IO at %#lx, IRQ %d", s->io, s->irq);
-
-	/* register devices */
-	if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
-		goto err_dev1;
-	if ((s->codec.dev_mixer =
-	     register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
-		goto err_dev2;
-
-#ifdef IT8172_DEBUG
-	/* initialize the debug proc device */
-	s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
-				       proc_it8172_dump, NULL);
-#endif /* IT8172_DEBUG */
-	
-	/*
-	 * Reset the Audio device using the IT8172 PCI Reset register. This
-	 * creates an audible double click on a speaker connected to Line-out.
-	 */
-	IT_IO_READ16(IT_PM_PCISR, pcisr);
-	pcisr |= IT_PM_PCISR_ACSR;
-	IT_IO_WRITE16(IT_PM_PCISR, pcisr);
-	/* wait up to 100msec for reset to complete */
-	for (i=0; pcisr & IT_PM_PCISR_ACSR; i++) {
-		it8172_delay(10);
-		if (i == 10)
-			break;
-		IT_IO_READ16(IT_PM_PCISR, pcisr);
-	}
-	if (i == 10) {
-		err("chip reset timeout!");
-		goto err_dev3;
-	}
-    
-	/* enable pci io and bus mastering */
-	if (pci_enable_device(pcidev))
-		goto err_dev3;
-	pci_set_master(pcidev);
-
-	/* get out of legacy mode */
-	pci_read_config_byte (pcidev, 0x40, &legacy);
-	pci_write_config_byte (pcidev, 0x40, legacy & ~1);
-    
-	s->spdif_volume = -1;
-	/* check to see if s/pdif mode is being requested */
-	if (spdif[devindex]) {
-		info("enabling S/PDIF output");
-		s->spdif_volume = 0;
-		outb(GC_SOE, s->io+IT_AC_GC);
-	} else {
-		info("disabling S/PDIF output");
-		outb(0, s->io+IT_AC_GC);
-	}
-    
-	/* check to see if I2S format requested */
-	if (i2s_fmt[devindex]) {
-		info("setting I2S format to 0x%02x", i2s_fmt[devindex]);
-		outb(i2s_fmt[devindex], s->io+IT_AC_I2SMC);
-	} else {
-		outb(I2SMC_I2SF_I2S, s->io+IT_AC_I2SMC);
-	}
-
-	/* cold reset the AC97 */
-	outw(CODECC_CR, s->io+IT_AC_CODECC);
-	udelay(1000);
-	outw(0, s->io+IT_AC_CODECC);
-	/* need to delay around 500msec(bleech) to give
-	   some CODECs enough time to wakeup */
-	it8172_delay(500);
-    
-	/* AC97 warm reset to start the bitclk */
-	outw(CODECC_WR, s->io+IT_AC_CODECC);
-	udelay(1000);
-	outw(0, s->io+IT_AC_CODECC);
-    
-	/* codec init */
-	if (!ac97_probe_codec(&s->codec))
-		goto err_dev3;
-
-	/* add I2S as allowable recording source */
-	s->codec.record_sources |= SOUND_MASK_I2S;
-	
-	/* Enable Volume button interrupts */
-	imc = inb(s->io+IT_AC_IMC);
-	outb(imc & ~IMC_VCIM, s->io+IT_AC_IMC);
-
-	/* Un-mute PCM and FM out on the controller */
-	vol = inw(s->io+IT_AC_PCMOV);
-	outw(vol & ~PCMOV_PCMOM, s->io+IT_AC_PCMOV);
-	vol = inw(s->io+IT_AC_FMOV);
-	outw(vol & ~FMOV_FMOM, s->io+IT_AC_FMOV);
-    
-	/* set channel defaults to 8-bit, mono, 8 Khz */
-	s->pcc = 0;
-	s->capcc = 0;
-	set_dac_rate(s, 8000);
-	set_adc_rate(s, 8000);
-
-	/* set mic to be the recording source */
-	val = SOUND_MASK_MIC;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
-		     (unsigned long)&val);
-
-	/* mute AC'97 master and PCM when in S/PDIF mode */
-	if (s->spdif_volume != -1) {
-		val = 0x0000;
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
-				     (unsigned long)&val);
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
-				     (unsigned long)&val);
-	}
-    
-#ifdef IT8172_DEBUG
-	sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME,
-		s->codec.id);
-	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					     ac97_read_proc, &s->codec);
-#endif
-    
-	/* store it in the driver field */
-	pci_set_drvdata(pcidev, s);
-	pcidev->dma_mask = 0xffffffff;
-	/* put it into driver list */
-	list_add_tail(&s->devs, &devs);
-	/* increment devindex */
-	if (devindex < NR_DEVICE-1)
-		devindex++;
-	return 0;
-
- err_dev3:
-	unregister_sound_mixer(s->codec.dev_mixer);
- err_dev2:
-	unregister_sound_dsp(s->dev_audio);
- err_dev1:
-	err("cannot register misc device");
-	free_irq(s->irq, s);
- err_irq:
-	release_region(s->io, pci_resource_len(pcidev,0));
- err_region:
-	kfree(s);
-	return -1;
-}
-
-static void __devexit it8172_remove(struct pci_dev *dev)
-{
-	struct it8172_state *s = pci_get_drvdata(dev);
-
-	if (!s)
-		return;
-	list_del(&s->devs);
-#ifdef IT8172_DEBUG
-	if (s->ps)
-		remove_proc_entry(IT8172_MODULE_NAME, NULL);
-#endif /* IT8172_DEBUG */
-	synchronize_irq(s->irq);
-	free_irq(s->irq, s);
-	release_region(s->io, pci_resource_len(dev,0));
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec.dev_mixer);
-	kfree(s);
-	pci_set_drvdata(dev, NULL);
-}
-
-
-
-static struct pci_device_id id_table[] = {
-	{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G_AUDIO, PCI_ANY_ID,
-	  PCI_ANY_ID, 0, 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver it8172_driver = {
-	.name = IT8172_MODULE_NAME,
-	.id_table = id_table,
-	.probe = it8172_probe,
-	.remove = __devexit_p(it8172_remove)
-};
-
-static int __init init_it8172(void)
-{
-	info("version v0.5 time " __TIME__ " " __DATE__);
-	return pci_register_driver(&it8172_driver);
-}
-
-static void __exit cleanup_it8172(void)
-{
-	info("unloading");
-	pci_unregister_driver(&it8172_driver);
-}
-
-module_init(init_it8172);
-module_exit(cleanup_it8172);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: it8172=[spdif],[i2s:<I2S format>] */
-
-static int __init it8172_setup(char *options)
-{
-	char* this_opt;
-	static unsigned __initdata nr_dev = 0;
-
-	if (nr_dev >= NR_DEVICE)
-		return 0;
-
-	if (!options || !*options)
-		return 0;
-
-	while (this_opt = strsep(&options, ",")) {
-		if (!*this_opt)
-			continue;
-		if (!strncmp(this_opt, "spdif", 5)) {
-			spdif[nr_dev] = 1;
-		} else if (!strncmp(this_opt, "i2s:", 4)) {
-			if (!strncmp(this_opt+4, "dac", 3))
-				i2s_fmt[nr_dev] = I2SMC_I2SF_DAC;
-			else if (!strncmp(this_opt+4, "adc", 3))
-				i2s_fmt[nr_dev] = I2SMC_I2SF_ADC;
-			else if (!strncmp(this_opt+4, "i2s", 3))
-				i2s_fmt[nr_dev] = I2SMC_I2SF_I2S;
-		}
-	}
-
-	nr_dev++;
-	return 1;
-}
-
-__setup("it8172=", it8172_setup);
-
-#endif /* MODULE */
diff --git a/sound/oss/iwmem.h b/sound/oss/iwmem.h
deleted file mode 100644
index 84745fbc..0000000
--- a/sound/oss/iwmem.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * sound/iwmem.h
- *
- * DRAM size encoding table for AMD Interwave chip.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * Bartlomiej Zolnierkiewicz	: added __initdata to mem_decode
- */
-
-
-#define K 1024
-#define M (1024*K)
-static int mem_decode[][4] __initdata =
-{
-/*	Bank0	Bank1	Bank2	Bank3	Encoding bits	*/
-	{256*K,	0,	0,	0},		/*  0 */
-	{256*K,	256*K,	0,	0},		/*  1 */
-	{256*K,	256*K,	256*K,	256*K},		/*  2 */
-	{256*K,	1*M,	0,	0},		/*  3 */
-	{256*K,	1*M,	1*M,	1*M},		/*  4 */
-	{256*K,	256*K,	1*M,	0},		/*  5 */
-	{256*K,	256*K,	1*M,	1*M},		/*  6 */
-	{1*M,	0,	0,	0},		/*  7 */
-	{1*M,	1*M,	0,	0},		/*  8 */
-	{1*M,	1*M,	1*M,	1*M},		/*  9 */
-	{4*M,	0,	0,	0},		/* 10 */
-	{4*M,	4*M,	0,	0},		/* 11 */
-	{4*M,	4*M,	4*M,	4*M}		/* 12 */
-};
diff --git a/sound/oss/mad16.c b/sound/oss/mad16.c
deleted file mode 100644
index aa3c50d..0000000
--- a/sound/oss/mad16.c
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * mad16.c
- *
- * Initialization code for OPTi MAD16 compatible audio chips. Including
- *
- *      OPTi 82C928     MAD16           (replaced by C929)
- *      OAK OTI-601D    Mozart
- *      OAK OTI-605	Mozart		(later version with MPU401 Midi)
- *      OPTi 82C929     MAD16 Pro
- *      OPTi 82C930
- *      OPTi 82C924
- *
- * These audio interface chips don't produce sound themselves. They just
- * connect some other components (OPL-[234] and a WSS compatible codec)
- * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
- * also a UART for the MPU-401 mode (not 82C928/Mozart).
- * The Mozart chip appears to be compatible with the 82C928, although later
- * issues of the card, using the OTI-605 chip, have an MPU-401 compatible Midi
- * port. This port is configured differently to that of the OPTi audio chips.
- *
- *	Changes
- *	
- *	Alan Cox		Clean up, added module selections.
- *
- *	A. Wik			Added support for Opti924 PnP.
- *				Improved debugging support.	16-May-1998
- *				Fixed bug.			16-Jun-1998
- *
- *      Torsten Duwe            Made Opti924 PnP support non-destructive
- *                                                             	23-Dec-1998
- *
- *	Paul Grayson		Added support for Midi on later Mozart cards.
- *								25-Nov-1999
- *	Christoph Hellwig	Adapted to module_init/module_exit.
- *	Arnaldo C. de Melo	got rid of attach_uart401       21-Sep-2000
- *
- *	Pavel Rabel		Clean up                           Nov-2000
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gameport.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "ad1848.h"
-#include "sb.h"
-#include "mpu401.h"
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int      mad16_conf;
-static int      mad16_cdsel;
-static DEFINE_SPINLOCK(lock);
-
-#define C928	1
-#define MOZART	2
-#define C929	3
-#define C930	4
-#define C924    5
-
-/*
- *    Registers
- *
- *      The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
- *      All ports are inactive by default. They can be activated by
- *      writing 0xE2 or 0xE3 to the password register. The password is valid
- *      only until the next I/O read or write.
- *
- *      82C930 uses 0xE4 as the password and indirect addressing to access
- *      the config registers.
- */
-
-#define MC0_PORT	0xf8c	/* Dummy port */
-#define MC1_PORT	0xf8d	/* SB address, CD-ROM interface type, joystick */
-#define MC2_PORT	0xf8e	/* CD-ROM address, IRQ, DMA, plus OPL4 bit */
-#define MC3_PORT	0xf8f
-#define PASSWD_REG	0xf8f
-#define MC4_PORT	0xf90
-#define MC5_PORT	0xf91
-#define MC6_PORT	0xf92
-#define MC7_PORT	0xf93
-#define MC8_PORT	0xf94
-#define MC9_PORT	0xf95
-#define MC10_PORT	0xf96
-#define MC11_PORT	0xf97
-#define MC12_PORT	0xf98
-
-static int      board_type = C928;
-
-static int     *mad16_osp;
-static int	c931_detected;	/* minor differences from C930 */
-static char	c924pnp;	/* "     "           "    C924 */
-static int	debug;  	/* debugging output */
-
-#ifdef DDB
-#undef DDB
-#endif
-#define DDB(x) do {if (debug) x;} while (0)
-
-static unsigned char mad_read(int port)
-{
-	unsigned long flags;
-	unsigned char tmp;
-
-	spin_lock_irqsave(&lock,flags);
-
-	switch (board_type)	/* Output password */
-	{
-		case C928:
-		case MOZART:
-			outb((0xE2), PASSWD_REG);
-			break;
-
-		case C929:
-			outb((0xE3), PASSWD_REG);
-			break;
-
-		case C930:
-			/* outb(( 0xE4),  PASSWD_REG); */
-			break;
-
-		case C924:
-			/* the c924 has its ports relocated by -128 if
-			   PnP is enabled  -aw */
-			if (!c924pnp)
-				outb((0xE5), PASSWD_REG); else
-				outb((0xE5), PASSWD_REG - 0x80);
-			break;
-	}
-
-	if (board_type == C930)
-	{
-		outb((port - MC0_PORT), 0xe0e);	/* Write to index reg */
-		tmp = inb(0xe0f);	/* Read from data reg */
-	}
-	else
-		if (!c924pnp)
-			tmp = inb(port); else
-			tmp = inb(port-0x80);
-	spin_unlock_irqrestore(&lock,flags);
-
-	return tmp;
-}
-
-static void mad_write(int port, int value)
-{
-	unsigned long   flags;
-
-	spin_lock_irqsave(&lock,flags);
-
-	switch (board_type)	/* Output password */
-	{
-		case C928:
-		case MOZART:
-			outb((0xE2), PASSWD_REG);
-			break;
-
-		case C929:
-			outb((0xE3), PASSWD_REG);
-			break;
-
-		case C930:
-			/* outb(( 0xE4),  PASSWD_REG); */
-			break;
-
-		case C924:
-			if (!c924pnp)
-				outb((0xE5), PASSWD_REG); else
-				outb((0xE5), PASSWD_REG - 0x80);
-			break;
-	}
-
-	if (board_type == C930)
-	{
-		outb((port - MC0_PORT), 0xe0e);	/* Write to index reg */
-		outb(((unsigned char) (value & 0xff)), 0xe0f);
-	}
-	else
-		if (!c924pnp)
-			outb(((unsigned char) (value & 0xff)), port); else
-			outb(((unsigned char) (value & 0xff)), port-0x80);
-	spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init detect_c930(void)
-{
-	unsigned char   tmp = mad_read(MC1_PORT);
-
-	if ((tmp & 0x06) != 0x06)
-	{
-		DDB(printk("Wrong C930 signature (%x)\n", tmp));
-		/* return 0; */
-	}
-	mad_write(MC1_PORT, 0);
-
-	if (mad_read(MC1_PORT) != 0x06)
-	{
-		DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
-		/* return 0; */
-	}
-	mad_write(MC1_PORT, tmp);	/* Restore bits */
-
-	mad_write(MC7_PORT, 0);
-	if ((tmp = mad_read(MC7_PORT)) != 0)
-	{
-		DDB(printk("MC7 not writable (%x)\n", tmp));
-		return 0;
-	}
-	mad_write(MC7_PORT, 0xcb);
-	if ((tmp = mad_read(MC7_PORT)) != 0xcb)
-	{
-		DDB(printk("MC7 not writable2 (%x)\n", tmp));
-		return 0;
-	}
-
-	tmp = mad_read(MC0_PORT+18);
-	if (tmp == 0xff || tmp == 0x00)
-		return 1;
-	/* We probably have a C931 */
-	DDB(printk("Detected C931 config=0x%02x\n", tmp));
-	c931_detected = 1;
-
-	/*
-         * We cannot configure the chip if it is in PnP mode.
-         * If we have a CSN assigned (bit 8 in MC13) we first try
-         * a software reset, then a software power off, finally
-         * Clearing PnP mode. The last option is not
-	 * Bit 8 in MC13 
-         */
-	if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-		return 1;
-
-	/* Software reset */
-	mad_write(MC9_PORT, 0x02);
-	mad_write(MC9_PORT, 0x00);
-
-	if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-		return 1;
-	
-	/* Power off, and on again */
-	mad_write(MC9_PORT, 0xc2);
-	mad_write(MC9_PORT, 0xc0);
-
-	if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-		return 1;
-	
-#if 0	
-	/* Force off PnP mode. This is not recommended because
-	 * the PnP bios will not recognize the chip on the next
-	 * warm boot and may assignd different resources to other
-	 * PnP/PCI cards.
-	 */
-	mad_write(MC0_PORT+17, 0x04);
-#endif
-	return 1;
-}
-
-static int __init detect_mad16(void)
-{
-	unsigned char tmp, tmp2, bit;
-	int i, port;
-
-	/*
-	 * Check that reading a register doesn't return bus float (0xff)
-	 * when the card is accessed using password. This may fail in case
-	 * the card is in low power mode. Normally at least the power saving
-	 * mode bit should be 0.
-	 */
-
-	if ((tmp = mad_read(MC1_PORT)) == 0xff)
-	{
-		DDB(printk("MC1_PORT returned 0xff\n"));
-		return 0;
-	}
-	for (i = 0xf8d; i <= 0xf98; i++)
-		if (!c924pnp)
-			DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i)));
-		else
-			DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i)));
-
-	if (board_type == C930)
-		return detect_c930();
-
-	/*
-	 * Now check that the gate is closed on first I/O after writing
-	 * the password. (This is how a MAD16 compatible card works).
-	 */
-
-	if ((tmp2 = inb(MC1_PORT)) == tmp)	/* It didn't close */
-	{
-		DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
-		return 0;
-	}
-
-	bit  = (c924pnp) ?     0x20 : 0x80;
-	port = (c924pnp) ? MC2_PORT : MC1_PORT;
-
-	tmp = mad_read(port);
-	mad_write(port, tmp ^ bit);	/* Toggle a bit */
-	if ((tmp2 = mad_read(port)) != (tmp ^ bit))	/* Compare the bit */
-	{
-		mad_write(port, tmp);	/* Restore */
-		DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
-		return 0;
-	}
-	mad_write(port, tmp);	/* Restore */
-	return 1;		/* Bingo */
-}
-
-static int __init wss_init(struct address_info *hw_config)
-{
-	/*
-	 * Check if the IO port returns valid signature. The original MS Sound
-	 * system returns 0x04 while some cards (AudioTrix Pro for example)
-	 * return 0x00.
-	 */
-
-	if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
-	    (inb(hw_config->io_base + 3) & 0x3f) != 0x00)
-	{
-		DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
-		return 0;
-	}
-	/*
-	 * Check that DMA0 is not in use with a 8 bit board.
-	 */
-	if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
-	{
-		printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
-		return 0;
-	}
-	if (hw_config->irq > 9 && inb(hw_config->io_base + 3) & 0x80)
-		printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
-	return 1;
-}
-
-static void __init init_c930(struct address_info *hw_config, int base)
-{
-	unsigned char cfg = 0;
-
-	cfg |= (0x0f & mad16_conf);
-
-	if(c931_detected)
-	{
-		/* Bit 0 has reversd meaning. Bits 1 and 2 sese
-		   reversed on write.
-		   Support only IDE cdrom. IDE port programmed
-		   somewhere else. */
-		cfg =  (cfg & 0x09) ^ 0x07;
-	}
-	cfg |= base << 4;
-	mad_write(MC1_PORT, cfg);
-
-	/* MC2 is CD configuration. Don't touch it. */
-
-	mad_write(MC3_PORT, 0);	/* Disable SB mode IRQ and DMA */
-
-	/* bit 2 of MC4 reverses it's meaning between the C930
-	   and the C931. */
-	cfg = c931_detected ? 0x04 : 0x00;
-
-	if(mad16_cdsel & 0x20)
-		mad_write(MC4_PORT, 0x62|cfg);  /* opl4 */
-	else
-		mad_write(MC4_PORT, 0x52|cfg);  /* opl3 */
-
-	mad_write(MC5_PORT, 0x3C);	/* Init it into mode2 */
-	mad_write(MC6_PORT, 0x02);	/* Enable WSS, Disable MPU and SB */
-	mad_write(MC7_PORT, 0xCB);
-	mad_write(MC10_PORT, 0x11);
-}
-
-static int __init chip_detect(void)
-{
-	int i;
-
-	/*
-	 *    Then try to detect with the old password
-	 */
-	board_type = C924;
-
-	DDB(printk("Detect using password = 0xE5\n"));
-	
-	if (detect_mad16()) {
-		return 1;
-	}
-	
-	board_type = C928;
-
-	DDB(printk("Detect using password = 0xE2\n"));
-
-	if (detect_mad16())
-	{
-		unsigned char model;
-
-		if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
-			DDB(printk("mad16.c: Mozart detected\n"));
-			board_type = MOZART;
-		} else {
-			DDB(printk("mad16.c: 82C928 detected???\n"));
-			board_type = C928;
-		}
-		return 1;
-	}
-
-	board_type = C929;
-
-	DDB(printk("Detect using password = 0xE3\n"));
-
-	if (detect_mad16())
-	{
-		DDB(printk("mad16.c: 82C929 detected\n"));
-		return 1;
-	}
-
-	if (inb(PASSWD_REG) != 0xff)
-		return 0;
-
-	/*
-	 * First relocate MC# registers to 0xe0e/0xe0f, disable password 
-	 */
-
-	outb((0xE4), PASSWD_REG);
-	outb((0x80), PASSWD_REG);
-
-	board_type = C930;
-
-	DDB(printk("Detect using password = 0xE4\n"));
-
-	for (i = 0xf8d; i <= 0xf93; i++)
-		DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-
-        if(detect_mad16()) {
-		DDB(printk("mad16.c: 82C930 detected\n"));
-		return 1;
-	}
-
-	/* The C931 has the password reg at F8D */
-	outb((0xE4), 0xF8D);
-	outb((0x80), 0xF8D);
-	DDB(printk("Detect using password = 0xE4 for C931\n"));
-
-	if (detect_mad16()) {
-		return 1;
-	}
-
-	board_type = C924;
-	c924pnp++;
-	DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
-	if (detect_mad16()) {
-		DDB(printk("mad16.c: 82C924 PnP detected\n"));
-		return 1;
-	}
-	
-	c924pnp=0;
-
-	return 0;
-}
-
-static int __init probe_mad16(struct address_info *hw_config)
-{
-	int i;
-	unsigned char tmp;
-	unsigned char cs4231_mode = 0;
-
-	int ad_flags = 0;
-
-	signed char bits;
-
-	static char     dma_bits[4] = {
-		1, 2, 0, 3
-	};
-
-	int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
-	int dma = hw_config->dma, dma2 = hw_config->dma2;
-	unsigned char dma2_bit = 0;
-	int base;
-	struct resource *ports;
-
-	mad16_osp = hw_config->osp;
-
-	switch (hw_config->io_base) {
-	case 0x530:
-		base = 0;
-		break;
-	case 0xe80:
-		base = 1;
-		break;
-	case 0xf40:
-		base = 2;
-		break;
-	case 0x604:
-		base = 3;
-		break;
-	default:
-		printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
-		return 0;
-	}
-
-	if (dma != 0 && dma != 1 && dma != 3) {
-		printk(KERN_ERR "MSS: Bad DMA %d\n", dma);
-		return 0;
-	}
-
-	/*
-	 *    Check that all ports return 0xff (bus float) when no password
-	 *      is written to the password register.
-	 */
-
-	DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
-	if (!chip_detect())
-		return 0;
-
-	switch (hw_config->irq) {
-	case 7:
-		bits = 8;
-		break;
-	case 9:
-		bits = 0x10;
-		break;
-	case 10:
-		bits = 0x18;
-		break;
-	case 12:
-		bits = 0x20;
-		break;
-	case 5:	/* Also IRQ5 is possible on C930 */
-		if (board_type == C930 || c924pnp) {
-			bits = 0x28;
-			break;
-		}
-	default:
-		printk(KERN_ERR "MAD16/Mozart: Bad IRQ %d\n", hw_config->irq);
-		return 0;
-	}
-
-	ports = request_region(hw_config->io_base + 4, 4, "ad1848");
-	if (!ports) {
-		printk(KERN_ERR "MSS: I/O port conflict\n");
-		return 0;
-	}
-	if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) {
-		release_region(hw_config->io_base + 4, 4);
-		printk(KERN_ERR "MSS: I/O port conflict\n");
-		return 0;
-	}
-
-	if (board_type == C930) {
-		init_c930(hw_config, base);
-		goto got_it;
-	}
-
-	for (i = 0xf8d; i <= 0xf93; i++) {
-		if (!c924pnp)
-			DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-		else
-			DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i)));
-	}
-
-/*
- * Set the WSS address
- */
-
-	tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80;	/* Enable WSS, Disable SB */
-	tmp |= base << 4;	/* WSS port select bits */
-
-	/*
-	 * Set optional CD-ROM and joystick settings.
-	 */
-
-	tmp &= ~0x0f;
-	tmp |= (mad16_conf & 0x0f);	/* CD-ROM and joystick bits */
-	mad_write(MC1_PORT, tmp);
-
-	tmp = mad16_cdsel;
-	mad_write(MC2_PORT, tmp);
-	mad_write(MC3_PORT, 0xf0);	/* Disable SB */
-
-	if (board_type == C924)	/* Specific C924 init values */
-	{
-		mad_write(MC4_PORT, 0xA0);
-		mad_write(MC5_PORT, 0x05);
-		mad_write(MC6_PORT, 0x03);
-	}
-	if (!ad1848_detect(ports, &ad_flags, mad16_osp))
-		goto fail;
-
-	if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
-		cs4231_mode = 0x02;	/* CS4248/CS4231 sync delay switch */
-
-	if (board_type == C929)
-	{
-		mad_write(MC4_PORT, 0xa2);
-		mad_write(MC5_PORT, 0xA5 | cs4231_mode);
-		mad_write(MC6_PORT, 0x03);	/* Disable MPU401 */
-	}
-	else
-	{
-		mad_write(MC4_PORT, 0x02);
-		mad_write(MC5_PORT, 0x30 | cs4231_mode);
-	}
-
-	for (i = 0xf8d; i <= 0xf93; i++) {
-		if (!c924pnp)
-			DDB(printk("port %03x after init = %02x\n", i, mad_read(i)));
-		else
-			DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));
-	}
-
-got_it:
-	ad_flags = 0;
-	if (!ad1848_detect(ports, &ad_flags, mad16_osp))
-		goto fail;
-
-	if (!wss_init(hw_config))
-		goto fail;
-
-	/*
-	 * Set the IRQ and DMA addresses.
-	 */
-	
-	outb((bits | 0x40), config_port);
-	if ((inb(version_port) & 0x40) == 0)
-		printk(KERN_ERR "[IRQ Conflict?]\n");
-
-	/*
-	 * Handle the capture DMA channel
-	 */
-
-	if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
-	{
-		if (!((dma == 0 && dma2 == 1) ||
-			(dma == 1 && dma2 == 0) ||
-			(dma == 3 && dma2 == 0)))
-		{		/* Unsupported combination. Try to swap channels */
-			int tmp = dma;
-
-			dma = dma2;
-			dma2 = tmp;
-		}
-		if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||
-			(dma == 3 && dma2 == 0))
-		{
-			dma2_bit = 0x04;	/* Enable capture DMA */
-		}
-		else
-		{
-			printk("MAD16: Invalid capture DMA\n");
-			dma2 = dma;
-		}
-	}
-	else dma2 = dma;
-
-	outb((bits | dma_bits[dma] | dma2_bit), config_port);	/* Write IRQ+DMA setup */
-
-	hw_config->slots[0] = ad1848_init("mad16 WSS", ports,
-					  hw_config->irq,
-					  dma,
-					  dma2, 0,
-					  hw_config->osp,
-					  THIS_MODULE);
-	return 1;
-
-fail:
-	release_region(hw_config->io_base + 4, 4);
-	release_region(hw_config->io_base, 4);
-	return 0;
-}
-
-static int __init probe_mad16_mpu(struct address_info *hw_config)
-{
-	unsigned char tmp;
-
-	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */
-	{
-
-#ifdef CONFIG_MAD16_OLDCARD
-
-		tmp = mad_read(MC3_PORT);
-
-		/* 
-		 * MAD16 SB base is defined by the WSS base. It cannot be changed 
-		 * alone.
-		 * Ignore configured I/O base. Use the active setting. 
-		 */
-
-		if (mad_read(MC1_PORT) & 0x20)
-			hw_config->io_base = 0x240;
-		else
-			hw_config->io_base = 0x220;
-
-		switch (hw_config->irq)
-		{
-			case 5:
-				tmp = (tmp & 0x3f) | 0x80;
-				break;
-			case 7:
-				tmp = (tmp & 0x3f);
-				break;
-			case 11:
-				tmp = (tmp & 0x3f) | 0x40;
-				break;
-			default:
-				printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
-				return 0;
-		}
-
-		mad_write(MC3_PORT, tmp | 0x04);
-		hw_config->driver_use_1 = SB_MIDI_ONLY;
-		if (!request_region(hw_config->io_base, 16, "soundblaster"))
-			return 0;
-		if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
-			release_region(hw_config->io_base, 16);
-			return 0;
-		}
-
-		if (mad_read(MC1_PORT) & 0x20)
-			hw_config->io_base = 0x240;
-		else
-			hw_config->io_base = 0x220;
-
-		hw_config->name = "Mad16/Mozart";
-		sb_dsp_init(hw_config, THIS_MODULE);
-		return 1;
-#else
-		/* assuming all later Mozart cards are identified as
-		 * either 82C928 or Mozart. If so, following code attempts
-		 * to set MPU register. TODO - add probing
-		 */
-
-		tmp = mad_read(MC8_PORT);
-
-		switch (hw_config->irq)
-		{
-			case 5:
-				tmp |= 0x08;
-				break;
-			case 7:
-				tmp |= 0x10;
-				break;
-			case 9:
-				tmp |= 0x18;
-				break;
-			case 10:
-				tmp |= 0x20;
-				break;
-			case 11:
-				tmp |= 0x28;
-				break;
-			default:
-				printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");
-				return 0;
-		}
-
-		switch (hw_config->io_base)
-		{
-			case 0x300:
-				tmp |= 0x01;
-				break;
-			case 0x310:
-				tmp |= 0x03;
-				break;
-			case 0x320:
-				tmp |= 0x05;
-				break;
-			case 0x330:
-				tmp |= 0x07;
-				break;
-			default:
-				printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");
-				return 0;
-		}
-
-		mad_write(MC8_PORT, tmp);	/* write MPU port parameters */
-		goto probe_401;
-#endif
-	}
-	tmp = mad_read(MC6_PORT) & 0x83;
-	tmp |= 0x80;		/* MPU-401 enable */
-
-	/* Set the MPU base bits */
-
-	switch (hw_config->io_base)
-	{
-		case 0x300:
-			tmp |= 0x60;
-			break;
-		case 0x310:
-			tmp |= 0x40;
-			break;
-		case 0x320:
-			tmp |= 0x20;
-			break;
-		case 0x330:
-			tmp |= 0x00;
-			break;
-		default:
-			printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);
-			return 0;
-	}
-
-	/* Set the MPU IRQ bits */
-
-	switch (hw_config->irq)
-	{
-		case 5:
-			tmp |= 0x10;
-			break;
-		case 7:
-			tmp |= 0x18;
-			break;
-		case 9:
-			tmp |= 0x00;
-			break;
-		case 10:
-			tmp |= 0x08;
-			break;
-		default:
-			printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);
-			break;
-	}
-			
-	mad_write(MC6_PORT, tmp);	/* Write MPU401 config */
-
-#ifndef CONFIG_MAD16_OLDCARD
-probe_401:
-#endif
-	hw_config->driver_use_1 = SB_MIDI_ONLY;
-	hw_config->name = "Mad16/Mozart";
-	return probe_uart401(hw_config, THIS_MODULE);
-}
-
-static void __exit unload_mad16(struct address_info *hw_config)
-{
-	ad1848_unload(hw_config->io_base + 4,
-			hw_config->irq,
-			hw_config->dma,
-			hw_config->dma2, 0);
-	release_region(hw_config->io_base, 4);
-	sound_unload_audiodev(hw_config->slots[0]);
-}
-
-static void __exit unload_mad16_mpu(struct address_info *hw_config)
-{
-#ifdef CONFIG_MAD16_OLDCARD
-	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */
-	{
-		sb_dsp_unload(hw_config, 0);
-		return;
-	}
-#endif
-
-	unload_uart401(hw_config);
-}
-
-static struct address_info cfg;
-static struct address_info cfg_mpu;
-
-static int found_mpu;
-
-static int __initdata mpu_io = 0;
-static int __initdata mpu_irq = 0;
-static int __initdata io = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1; /* Set this for modules that need it */
-static int __initdata irq = -1;
-static int __initdata cdtype = 0;
-static int __initdata cdirq = 0;
-static int __initdata cdport = 0x340;
-static int __initdata cddma = -1;
-static int __initdata opl4 = 0;
-static int __initdata joystick = 0;
-
-module_param(mpu_io, int, 0);
-module_param(mpu_irq, int, 0);
-module_param(io, int, 0);
-module_param(dma, int, 0);
-module_param(dma16, int, 0);
-module_param(irq, int, 0);
-module_param(cdtype, int, 0);
-module_param(cdirq, int, 0);
-module_param(cdport, int, 0);
-module_param(cddma, int, 0);
-module_param(opl4, int, 0);
-module_param(joystick, bool, 0);
-module_param(debug, bool, 0644);
-
-static int __initdata dma_map[2][8] =
-{
-	{0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
-	{0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
-};
-
-static int __initdata irq_map[16] =
-{
-	0x00, -1, -1, 0x0A,
-	-1, 0x04, -1, 0x08,
-	-1, 0x10, 0x14, 0x18,
-	-1, -1, -1, -1
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static struct gameport *gameport;
-
-static int __devinit mad16_register_gameport(int io_port)
-{
-	if (!request_region(io_port, 1, "mad16 gameport")) {
-		printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port);
-		return -EBUSY;
-	}
-
-	gameport = gameport_allocate_port();
-	if (!gameport) {
-		printk(KERN_ERR "mad16: can not allocate memory for gameport\n");
-		release_region(io_port, 1);
-		return -ENOMEM;
-	}
-
-	gameport_set_name(gameport, "MAD16 Gameport");
-	gameport_set_phys(gameport, "isa%04x/gameport0", io_port);
-	gameport->io = io_port;
-
-	gameport_register_port(gameport);
-
-	return 0;
-}
-
-static inline void mad16_unregister_gameport(void)
-{
-	if (gameport) {
-		/* the gameport was initialized so we must free it up */
-		gameport_unregister_port(gameport);
-		gameport = NULL;
-		release_region(0x201, 1);
-	}
-}
-#else
-static inline int mad16_register_gameport(int io_port) { return -ENOSYS; }
-static inline void mad16_unregister_gameport(void) { }
-#endif
-
-static int __devinit init_mad16(void)
-{
-	int dmatype = 0;
-
-	printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-	printk(KERN_INFO "CDROM ");
-	switch (cdtype)
-	{
-		case 0x00:
-			printk("Disabled");
-			cdirq = 0;
-			break;
-		case 0x02:
-			printk("Sony CDU31A");
-			dmatype = 1;
-			if(cddma == -1) cddma = 3;
-			break;
-		case 0x04:
-			printk("Mitsumi");
-			dmatype = 0;
-			if(cddma == -1) cddma = 5;
-			break;
-		case 0x06:
-			printk("Panasonic Lasermate");
-			dmatype = 1;
-			if(cddma == -1) cddma = 3;
-			break;
-		case 0x08:
-			printk("Secondary IDE");
-			dmatype = 0;
-			if(cddma == -1) cddma = 5;
-			break;
-		case 0x0A:
-			printk("Primary IDE");
-			dmatype = 0;
-			if(cddma == -1) cddma = 5;
-			break;
-		default:
-			printk("\n");
-			printk(KERN_ERR "Invalid CDROM type\n");
-			return -EINVAL;
-	}
-
-	/*
-	 *    Build the config words
-	 */
-
-	mad16_conf = (joystick ^ 1) | cdtype;
-	mad16_cdsel = 0;
-	if (opl4)
-		mad16_cdsel |= 0x20;
-
-	if(cdtype){
-		if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
-		{
-			printk("\n");
-			printk(KERN_ERR "Invalid CDROM DMA\n");
-			return -EINVAL;
-		}
-		if (cddma)
-			printk(", DMA %d", cddma);
-		else
-			printk(", no DMA");
-
-		if (!cdirq)
-			printk(", no IRQ");
-		else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
-		{
-			printk(", invalid IRQ (disabling)");
-			cdirq = 0;
-		}
-		else printk(", IRQ %d", cdirq);
-
-		mad16_cdsel |= dma_map[dmatype][cddma];
-
-		if (cdtype < 0x08)
-		{
-			switch (cdport)
-			{
-				case 0x340:
-					mad16_cdsel |= 0x00;
-					break;
-				case 0x330:
-					mad16_cdsel |= 0x40;
-					break;
-				case 0x360:
-					mad16_cdsel |= 0x80;
-					break;
-				case 0x320:
-					mad16_cdsel |= 0xC0;
-					break;
-				default:
-					printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);
-					return -EINVAL;
-			}
-		}
-		mad16_cdsel |= irq_map[cdirq];
-	}
-
-	printk(".\n");
-
-	cfg.io_base = io;
-	cfg.irq = irq;
-	cfg.dma = dma;
-	cfg.dma2 = dma16;
-
-	if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
-		printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
-		return -EINVAL;
-	}
-
-	if (!request_region(MC0_PORT, 12, "mad16"))
-		return -EBUSY;
-
-	if (!probe_mad16(&cfg)) {
-		release_region(MC0_PORT, 12);
-		return -ENODEV;
-	}
-
-	cfg_mpu.io_base = mpu_io;
-	cfg_mpu.irq = mpu_irq;
-
-	found_mpu = probe_mad16_mpu(&cfg_mpu);
-
-	if (joystick)
-		mad16_register_gameport(0x201);
-
-	return 0;
-}
-
-static void __exit cleanup_mad16(void)
-{
-	if (found_mpu)
-		unload_mad16_mpu(&cfg_mpu);
-	mad16_unregister_gameport();
-	unload_mad16(&cfg);
-	release_region(MC0_PORT, 12);
-}
-
-module_init(init_mad16);
-module_exit(cleanup_mad16);
-
-#ifndef MODULE
-static int __init setup_mad16(char *str)
-{
-	/* io, irq */
-	int ints[8];
-
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-
-	io	 = ints[1];
-	irq	 = ints[2];
-	dma	 = ints[3];
-	dma16	 = ints[4];
-	mpu_io	 = ints[5];
-	mpu_irq  = ints[6];
-	joystick = ints[7];
-
-	return 1;
-}
-
-__setup("mad16=", setup_mad16);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
deleted file mode 100644
index 1d98d10..0000000
--- a/sound/oss/maestro.c
+++ /dev/null
@@ -1,3686 +0,0 @@
-/*****************************************************************************
- *
- *      ESS Maestro/Maestro-2/Maestro-2E driver for Linux 2.[23].x
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *	(c) Copyright 1999	 Alan Cox <alan.cox@linux.org>
- *
- *	Based heavily on SonicVibes.c:
- *      Copyright (C) 1998-1999  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *	Heavily modified by Zach Brown <zab@zabbo.net> based on lunch
- *	with ESS engineers.  Many thanks to Howard Kim for providing 
- *	contacts and hardware.  Honorable mention goes to Eric 
- *	Brombaugh for all sorts of things.  Best regards to the 
- *	proprietors of Hack Central for fine lodging.
- *
- *  Supported devices:
- *  /dev/dsp0-3    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *
- *  Hardware Description
- *
- *	A working Maestro setup contains the Maestro chip wired to a 
- *	codec or 2.  In the Maestro we have the APUs, the ASSP, and the
- *	Wavecache.  The APUs can be though of as virtual audio routing
- *	channels.  They can take data from a number of sources and perform
- *	basic encodings of the data.  The wavecache is a storehouse for
- *	PCM data.  Typically it deals with PCI and interracts with the
- *	APUs.  The ASSP is a wacky DSP like device that ESS is loth
- *	to release docs on.  Thankfully it isn't required on the Maestro
- *	until you start doing insane things like FM emulation and surround
- *	encoding.  The codecs are almost always AC-97 compliant codecs, 
- *	but it appears that early Maestros may have had PT101 (an ESS
- *	part?) wired to them.  The only real difference in the Maestro
- *	families is external goop like docking capability, memory for
- *	the ASSP, and initialization differences.
- *
- *  Driver Operation
- *
- *	We only drive the APU/Wavecache as typical DACs and drive the
- *	mixers in the codecs.  There are 64 APUs.  We assign 6 to each
- *	/dev/dsp? device.  2 channels for output, and 4 channels for
- *	input.
- *
- *	Each APU can do a number of things, but we only really use
- *	3 basic functions.  For playback we use them to convert PCM
- *	data fetched over PCI by the wavecahche into analog data that
- *	is handed to the codec.  One APU for mono, and a pair for stereo.
- *	When in stereo, the combination of smarts in the APU and Wavecache
- *	decide which wavecache gets the left or right channel.
- *
- *	For record we still use the old overly mono system.  For each in
- *	coming channel the data comes in from the codec, through a 'input'
- *	APU, through another rate converter APU, and then into memory via
- *	the wavecache and PCI.  If its stereo, we mash it back into LRLR in
- *	software.  The pass between the 2 APUs is supposedly what requires us
- *	to have a 512 byte buffer sitting around in wavecache/memory.
- *
- *	The wavecache makes our life even more fun.  First off, it can
- *	only address the first 28 bits of PCI address space, making it
- *	useless on quite a few architectures.  Secondly, its insane.
- *	It claims to fetch from 4 regions of PCI space, each 4 meg in length.
- *	But that doesn't really work.  You can only use 1 region.  So all our
- *	allocations have to be in 4meg of each other.  Booo.  Hiss.
- *	So we have a module parameter, dsps_order, that is the order of
- *	the number of dsps to provide.  All their buffer space is allocated
- *	on open time.  The sonicvibes OSS routines we inherited really want
- *	power of 2 buffers, so we have all those next to each other, then
- *	512 byte regions for the recording wavecaches.  This ends up
- *	wasting quite a bit of memory.  The only fixes I can see would be 
- *	getting a kernel allocator that could work in zones, or figuring out
- *	just how to coerce the WP into doing what we want.
- *
- *	The indirection of the various registers means we have to spinlock
- *	nearly all register accesses.  We have the main register indirection
- *	like the wave cache, maestro registers, etc.  Then we have beasts
- *	like the APU interface that is indirect registers gotten at through
- *	the main maestro indirection.  Ouch.  We spinlock around the actual
- *	ports on a per card basis.  This means spinlock activity at each IO
- *	operation, but the only IO operation clusters are in non critical 
- *	paths and it makes the code far easier to follow.  Interrupts are
- *	blocked while holding the locks because the int handler has to
- *	get at some of them :(.  The mixer interface doesn't, however.
- *	We also have an OSS state lock that is thrown around in a few
- *	places.
- *
- *	This driver has brute force APM suspend support.  We catch suspend
- *	notifications and stop all work being done on the chip.  Any people
- *	that try between this shutdown and the real suspend operation will
- *	be put to sleep.  When we resume we restore our software state on
- *	the chip and wake up the people that were using it.  The code thats
- *	being used now is quite dirty and assumes we're on a uni-processor
- *	machine.  Much of it will need to be cleaned up for SMP ACPI or 
- *	similar.
- *
- *	We also pay attention to PCI power management now.  The driver
- *	will power down units of the chip that it knows aren't needed.
- *	The WaveProcessor and company are only powered on when people
- *	have /dev/dsp*s open.  On removal the driver will
- *	power down the maestro entirely.  There could still be
- *	trouble with BIOSen that magically change power states 
- *	themselves, but we'll see.  
- *	
- * History
- *  v0.15 - May 21 2001 - Marcus Meissner <mm@caldera.de>
- *      Ported to Linux 2.4 PCI API. Some clean ups, global devs list
- *      removed (now using pci device driver data).
- *      PM needs to be polished still. Bumped version.
- *  (still kind of v0.14) May 13 2001 - Ben Pfaff <pfaffben@msu.edu>
- *      Add support for 978 docking and basic hardware volume control
- *  (still kind of v0.14) Nov 23 - Alan Cox <alan@redhat.com>
- *	Add clocking= for people with seriously warped hardware
- *  (still v0.14) Nov 10 2000 - Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *	add __init to maestro_ac97_init() and maestro_install()
- *  (still based on v0.14) Mar 29 2000 - Zach Brown <zab@redhat.com>
- *	move to 2.3 power management interface, which
- *		required hacking some suspend/resume/check paths 
- *	make static compilation work
- *  v0.14 - Jan 28 2000 - Zach Brown <zab@redhat.com>
- *	add PCI power management through ACPI regs.
- *	we now shut down on machine reboot/halt
- *	leave scary PCI config items alone (isa stuff, mostly)
- *	enable 1921s, it seems only mine was broke.
- *	fix swapped left/right pcm dac.  har har.
- *	up bob freq, increase buffers, fix pointers at underflow
- *	silly compilation problems
- *  v0.13 - Nov 18 1999 - Zach Brown <zab@redhat.com>
- *	fix nec Versas?  man would that be cool.
- *  v0.12 - Nov 12 1999 - Zach Brown <zab@redhat.com>
- *	brown bag volume max fix..
- *  v0.11 - Nov 11 1999 - Zach Brown <zab@redhat.com>
- *	use proper stereo apu decoding, mmap/write should work.
- *	make volume sliders more useful, tweak rate calculation.
- *	fix lame 8bit format reporting bug.  duh. apm apu saving buglet also
- *	fix maestro 1 clock freq "bug", remove pt101 support
- *  v0.10 - Oct 28 1999 - Zach Brown <zab@redhat.com>
- *	aha, so, sometimes the WP writes a status word to offset 0
- *	  from one of the PCMBARs.  rearrange allocation accordingly..
- *	  cheers again to Eric for being a good hacker in investigating this.
- *	Jeroen Hoogervorst submits 7500 fix out of nowhere.  yay.  :)
- *  v0.09 - Oct 23 1999 - Zach Brown <zab@redhat.com>
- *	added APM support.
- *	re-order something such that some 2Es now work.  Magic!
- *	new codec reset routine.  made some codecs come to life.
- *	fix clear_advance, sync some control with ESS.
- *	now write to all base regs to be paranoid.
- *  v0.08 - Oct 20 1999 - Zach Brown <zab@redhat.com>
- *	Fix initial buflen bug.  I am so smart.  also smp compiling..
- *	I owe Eric yet another beer: fixed recmask, igain, 
- *	  muting, and adc sync consistency.  Go Team.
- *  v0.07 - Oct 4 1999 - Zach Brown <zab@redhat.com>
- *	tweak adc/dac, formating, and stuff to allow full duplex
- *	allocate dsps memory at open() so we can fit in the wavecache window
- *	fix wavecache braindamage.  again.  no more scribbling?
- *	fix ess 1921 codec bug on some laptops.
- *	fix dumb pci scanning bug
- *	started 2.3 cleanup, redid spinlocks, little cleanups
- *  v0.06 - Sep 20 1999 - Zach Brown <zab@redhat.com>
- *	fix wavecache thinkos.  limit to 1 /dev/dsp.
- *	eric is wearing his thinking toque this week.
- *		spotted apu mode bugs and gain ramping problem
- *	don't touch weird mixer regs, make recmask optional
- *	fixed igain inversion, defaults for mixers, clean up rec_start
- *	make mono recording work.
- *	report subsystem stuff, please send reports.
- *	littles: parallel out, amp now
- *  v0.05 - Sep 17 1999 - Zach Brown <zab@redhat.com>
- *	merged and fixed up Eric's initial recording code
- *	munged format handling to catch misuse, needs rewrite.
- *	revert ring bus init, fixup shared int, add pci busmaster setting
- *	fix mixer oss interface, fix mic mute and recmask
- *	mask off unsupported mixers, reset with all 1s, modularize defaults
- *	make sure bob is running while we need it
- *	got rid of device limit, initial minimal apm hooks
- *	pull out dead code/includes, only allow multimedia/audio maestros
- *  v0.04 - Sep 01 1999 - Zach Brown <zab@redhat.com>
- *	copied memory leak fix from sonicvibes driver
- *	different ac97 reset, play with 2.0 ac97, simplify ring bus setup
- *	bob freq code, region sanity, jitter sync fix; all from Eric 
- *
- * TODO
- *	fix bob frequency
- *	endianness
- *	do smart things with ac97 2.0 bits.
- *	dual codecs
- *	leave 54->61 open
- *
- *	it also would be fun to have a mode that would not use pci dma at all
- *	but would copy into the wavecache on board memory and use that 
- *	on architectures that don't like the maestro's pci dma ickiness.
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/reboot.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-
-#include <asm/current.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "maestro.h"
-
-static struct pci_driver maestro_pci_driver;
-
-/* --------------------------------------------------------------------- */
-
-#define M_DEBUG 1
-
-#ifdef M_DEBUG
-static int debug;
-#define M_printk(args...) {if (debug) printk(args);}
-#else
-#define M_printk(x)
-#endif
-
-/* we try to setup 2^(dsps_order) /dev/dsp devices */
-static int dsps_order;
-/* whether or not we mess around with power management */
-static int use_pm=2; /* set to 1 for force */
-/* clocking for broken hardware - a few laptops seem to use a 50Khz clock
-	ie insmod with clocking=50000 or so */
-	
-static int clocking=48000;
-
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>");
-MODULE_DESCRIPTION("ESS Maestro Driver");
-MODULE_LICENSE("GPL");
-
-#ifdef M_DEBUG
-module_param(debug, bool, 0644);
-#endif
-module_param(dsps_order, int, 0);
-module_param(use_pm, int, 0);
-module_param(clocking, int, 0);
-
-/* --------------------------------------------------------------------- */
-#define DRIVER_VERSION "0.15"
-
-#ifndef PCI_VENDOR_ESS
-#define PCI_VENDOR_ESS			0x125D
-#define PCI_DEVICE_ID_ESS_ESS1968	0x1968		/* Maestro 2	*/
-#define PCI_DEVICE_ID_ESS_ESS1978      	0x1978		/* Maestro 2E	*/
-
-#define PCI_VENDOR_ESS_OLD		0x1285		/* Platform Tech, 
-						the people the maestro 
-						was bought from */
-#define PCI_DEVICE_ID_ESS_ESS0100	0x0100		/* maestro 1 */
-#endif /* PCI_VENDOR_ESS */
-
-#define ESS_CHAN_HARD		0x100
-
-/* NEC Versas ? */
-#define NEC_VERSA_SUBID1	0x80581033
-#define NEC_VERSA_SUBID2	0x803c1033
-
-
-/* changed so that I could actually find all the
-	references and fix them up.  it's a little more readable now. */
-#define ESS_FMT_STEREO	0x01
-#define ESS_FMT_16BIT	0x02
-#define ESS_FMT_MASK	0x03
-#define ESS_DAC_SHIFT	0   
-#define ESS_ADC_SHIFT	4
-
-#define ESS_STATE_MAGIC		0x125D1968
-#define ESS_CARD_MAGIC		0x19283746
-
-#define DAC_RUNNING		1
-#define ADC_RUNNING		2
-
-#define MAX_DSP_ORDER	2
-#define MAX_DSPS	(1<<MAX_DSP_ORDER)
-#define NR_DSPS		(1<<dsps_order)
-#define NR_IDRS		32
-
-#define NR_APUS		64
-#define NR_APU_REGS	16
-
-/* acpi states */
-enum {
-	ACPI_D0=0,
-	ACPI_D1,
-	ACPI_D2,
-	ACPI_D3
-};
-
-/* bits in the acpi masks */
-#define ACPI_12MHZ	( 1 << 15)
-#define ACPI_24MHZ	( 1 << 14)
-#define ACPI_978	( 1 << 13)
-#define ACPI_SPDIF	( 1 << 12)
-#define ACPI_GLUE	( 1 << 11)
-#define ACPI__10	( 1 << 10) /* reserved */
-#define ACPI_PCIINT	( 1 << 9)
-#define ACPI_HV		( 1 << 8) /* hardware volume */
-#define ACPI_GPIO	( 1 << 7)
-#define ACPI_ASSP	( 1 << 6)
-#define ACPI_SB		( 1 << 5) /* sb emul */
-#define ACPI_FM		( 1 << 4) /* fm emul */
-#define ACPI_RB		( 1 << 3) /* ringbus / aclink */
-#define ACPI_MIDI	( 1 << 2) 
-#define ACPI_GP		( 1 << 1) /* game port */
-#define ACPI_WP		( 1 << 0) /* wave processor */
-
-#define ACPI_ALL	(0xffff)
-#define ACPI_SLEEP	(~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
-			ACPI_MIDI|ACPI_GP|ACPI_WP))
-#define ACPI_NONE	(ACPI__10)
-
-/* these masks indicate which units we care about at
-	which states */
-static u16 acpi_state_mask[] = {
-	[ACPI_D0] = ACPI_ALL,
-	[ACPI_D1] = ACPI_SLEEP,
-	[ACPI_D2] = ACPI_SLEEP,
-	[ACPI_D3] = ACPI_NONE
-};
-
-static char version[] __devinitdata =
-KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n";
-
-
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-enum card_types_t {
-	TYPE_MAESTRO,
-	TYPE_MAESTRO2,
-	TYPE_MAESTRO2E
-};
-
-static const char *card_names[]={
-	[TYPE_MAESTRO] = "ESS Maestro",
-	[TYPE_MAESTRO2] = "ESS Maestro 2",
-	[TYPE_MAESTRO2E] = "ESS Maestro 2E"
-};
-
-static int clock_freq[]={
-	[TYPE_MAESTRO] = (49152000L / 1024L),
-	[TYPE_MAESTRO2] = (50000000L / 1024L),
-	[TYPE_MAESTRO2E] = (50000000L / 1024L)
-};
-
-static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf);
-
-static struct notifier_block maestro_nb = {maestro_notifier, NULL, 0};
-
-/* --------------------------------------------------------------------- */
-
-struct ess_state {
-	unsigned int magic;
-	/* FIXME: we probably want submixers in here, but only one record pair */
-	u8 apu[6];		/* l/r output, l/r intput converters, l/r input apus */
-	u8 apu_mode[6];		/* Running mode for this APU */
-	u8 apu_pan[6];		/* Panning setup for this APU */
-	u32 apu_base[6];	/* base address for this apu */
-	struct ess_card *card;	/* Card info */
-	/* wave stuff */
-	unsigned int rateadc, ratedac;
-	unsigned char fmt, enable;
-
-	int index;
-
-	/* this locks around the oss state in the driver */
-	spinlock_t lock;
-	/* only let 1 be opening at a time */
-	struct mutex open_mutex;
-	wait_queue_head_t open_wait;
-	mode_t open_mode;
-
-	/* soundcore stuff */
-	int dev_audio;
-
-	struct dmabuf {
-		void *rawbuf;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-		/* XXX zab - swptr only in here so that it can be referenced by
-			clear_advance, as far as I can tell :( */
-		unsigned hwptr, swptr;
-		unsigned total_bytes;
-		int count;
-		unsigned error; /* over/underrun */
-		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;
-		unsigned dmasize;
-		unsigned fragsamples;
-		/* OSS stuff */
-		unsigned mapped:1;
-		unsigned ready:1;	/* our oss buffers are ready to go */
-		unsigned endcleared:1;
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-		u16 base;		/* Offset for ptr */
-	} dma_dac, dma_adc;
-
-	/* pointer to each dsp?s piece of the apu->src buffer page */
-	void *mixbuf;
-
-};
-	
-struct ess_card {
-	unsigned int magic;
-
-	/* We keep maestro cards in a linked list */
-	struct ess_card *next;
-
-	int dev_mixer;
-
-	int card_type;
-
-	/* as most of this is static,
-		perhaps it should be a pointer to a global struct */
-	struct mixer_goo {
-		int modcnt;
-		int supported_mixers;
-		int stereo_mixers;
-		int record_sources;
-		/* the caller must guarantee arg sanity before calling these */
-/*		int (*read_mixer)(struct ess_card *card, int index);*/
-		void (*write_mixer)(struct ess_card *card,int mixer, unsigned int left,unsigned int right);
-		int (*recmask_io)(struct ess_card *card,int rw,int mask);
-		unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
-	} mix;
-	
-	int power_regs;
-		
-	int in_suspend;
-	wait_queue_head_t suspend_queue;
-
-	struct ess_state channels[MAX_DSPS];
-	u16 maestro_map[NR_IDRS];	/* Register map */
-	/* we have to store this junk so that we can come back from a
-		suspend */
-	u16 apu_map[NR_APUS][NR_APU_REGS];	/* contents of apu regs */
-
-	/* this locks around the physical registers on the card */
-	spinlock_t lock;
-
-	/* memory for this card.. wavecache limited :(*/
-	void *dmapages;
-	int dmaorder;
-
-	/* hardware resources */
-	struct pci_dev *pcidev;
-	u32 iobase;
-	u32 irq;
-
-	int bob_freq;
-	char dsps_open;
-
-	int dock_mute_vol;
-};
-
-static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val );
-
-static unsigned 
-ld2(unsigned int x)
-{
-	unsigned r = 0;
-	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static void check_suspend(struct ess_card *card);
-
-/* --------------------------------------------------------------------- */
-
-
-/*
- *	ESS Maestro AC97 codec programming interface.
- */
-	 
-static void maestro_ac97_set(struct ess_card *card, u8 cmd, u16 val)
-{
-	int io = card->iobase;
-	int i;
-	/*
-	 *	Wait for the codec bus to be free 
-	 */
-
-	check_suspend(card);
-	 
-	for(i=0;i<10000;i++)
-	{
-		if(!(inb(io+ESS_AC97_INDEX)&1)) 
-			break;
-	}
-	/*
-	 *	Write the bus
-	 */ 
-	outw(val, io+ESS_AC97_DATA);
-	mdelay(1);
-	outb(cmd, io+ESS_AC97_INDEX);
-	mdelay(1);
-}
-
-static u16 maestro_ac97_get(struct ess_card *card, u8 cmd)
-{
-	int io = card->iobase;
-	int sanity=10000;
-	u16 data;
-	int i;
-	
-	check_suspend(card);
-	/*
-	 *	Wait for the codec bus to be free 
-	 */
-	 
-	for(i=0;i<10000;i++)
-	{
-		if(!(inb(io+ESS_AC97_INDEX)&1))
-			break;
-	}
-
-	outb(cmd|0x80, io+ESS_AC97_INDEX);
-	mdelay(1);
-	
-	while(inb(io+ESS_AC97_INDEX)&1)
-	{
-		sanity--;
-		if(!sanity)
-		{
-			printk(KERN_ERR "maestro: ac97 codec timeout reading 0x%x.\n",cmd);
-			return 0;
-		}
-	}
-	data=inw(io+ESS_AC97_DATA);
-	mdelay(1);
-	return data;
-}
-
-/* OSS interface to the ac97s.. */
-
-#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\
-	SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\
-	SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN)
-
-#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
-	SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\
-	SOUND_MASK_SPEAKER)
-
-#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
-	SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\
-	SOUND_MASK_PHONEIN)
-
-#define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1<<FOO) )
-
-/* this table has default mixer values for all OSS mixers.
-	be sure to fill it in if you add oss mixers
-	to anyone's supported mixer defines */
-
-static unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
-	[SOUND_MIXER_VOLUME] =          0x3232,
-	[SOUND_MIXER_BASS] =            0x3232,
-	[SOUND_MIXER_TREBLE] =          0x3232,
-	[SOUND_MIXER_SPEAKER] =         0x3232,
-	[SOUND_MIXER_MIC] =     0x8000, /* annoying */
-	[SOUND_MIXER_LINE] =    0x3232,
-	[SOUND_MIXER_CD] =      0x3232,
-	[SOUND_MIXER_VIDEO] =   0x3232,
-	[SOUND_MIXER_LINE1] =   0x3232,
-	[SOUND_MIXER_PCM] =             0x3232,
-	[SOUND_MIXER_IGAIN] =           0x3232
-};
-	
-static struct ac97_mixer_hw {
-	unsigned char offset;
-	int scale;
-} ac97_hw[SOUND_MIXER_NRDEVICES]= {
-	[SOUND_MIXER_VOLUME]	=	{0x02,63},
-	[SOUND_MIXER_BASS]	=	{0x08,15},
-	[SOUND_MIXER_TREBLE]	=	{0x08,15},
-	[SOUND_MIXER_SPEAKER]	=	{0x0a,15},
-	[SOUND_MIXER_MIC]	=	{0x0e,31},
-	[SOUND_MIXER_LINE]	=	{0x10,31},
-	[SOUND_MIXER_CD]	=	{0x12,31},
-	[SOUND_MIXER_VIDEO]	=	{0x14,31},
-	[SOUND_MIXER_LINE1]	=	{0x16,31},
-	[SOUND_MIXER_PCM]	=	{0x18,31},
-	[SOUND_MIXER_IGAIN]	=	{0x1c,15}
-};
-
-#if 0 /* *shrug* removed simply because we never used it.
-		feel free to implement again if needed */
-
-/* reads the given OSS mixer from the ac97
-	the caller must have insured that the ac97 knows
-	about that given mixer, and should be holding a
-	spinlock for the card */
-static int ac97_read_mixer(struct ess_card *card, int mixer) 
-{
-	u16 val;
-	int ret=0;
-	struct ac97_mixer_hw *mh = &ac97_hw[mixer];
-
-	val = maestro_ac97_get(card, mh->offset);
-
-	if(AC97_STEREO_MASK & (1<<mixer)) {
-		/* nice stereo mixers .. */
-		int left,right;
-
-		left = (val >> 8)  & 0x7f;
-		right = val  & 0x7f;
-
-		if (mixer == SOUND_MIXER_IGAIN) {
-			right = (right * 100) / mh->scale;
-			left = (left * 100) / mh->scale;
-		} else {
-			right = 100 - ((right * 100) / mh->scale);
-			left = 100 - ((left * 100) / mh->scale);
-		}
-
-		ret = left | (right << 8);
-	} else if (mixer == SOUND_MIXER_SPEAKER) {
-		ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale);
-	} else if (mixer == SOUND_MIXER_MIC) {
-		ret = 100 - (((val & 0x1f) * 100) / mh->scale);
-	/*  the low bit is optional in the tone sliders and masking
-		it lets is avoid the 0xf 'bypass'.. */
-	} else if (mixer == SOUND_MIXER_BASS) {
-		ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale);
-	} else if (mixer == SOUND_MIXER_TREBLE) {
-		ret = 100 - (((val & 0xe) * 100) / mh->scale);
-	}
-
-	M_printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret);
-
-	return ret;
-}
-#endif
-
-/* write the OSS encoded volume to the given OSS encoded mixer,
-	again caller's job to make sure all is well in arg land,
-	call with spinlock held */
-	
-/* linear scale -> log */
-static unsigned char lin2log[101] = 
-{
-0, 0 , 15 , 23 , 30 , 34 , 38 , 42 , 45 , 47 ,
-50 , 52 , 53 , 55 , 57 , 58 , 60 , 61 , 62 ,
-63 , 65 , 66 , 67 , 68 , 69 , 69 , 70 , 71 ,
-72 , 73 , 73 , 74 , 75 , 75 , 76 , 77 , 77 ,
-78 , 78 , 79 , 80 , 80 , 81 , 81 , 82 , 82 ,
-83 , 83 , 84 , 84 , 84 , 85 , 85 , 86 , 86 ,
-87 , 87 , 87 , 88 , 88 , 88 , 89 , 89 , 89 ,
-90 , 90 , 90 , 91 , 91 , 91 , 92 , 92 , 92 ,
-93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 ,
-95 , 95 , 96 , 96 , 96 , 96 , 97 , 97 , 97 ,
-97 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 
-};
-
-static void ac97_write_mixer(struct ess_card *card,int mixer, unsigned int left, unsigned int right)
-{
-	u16 val=0;
-	struct ac97_mixer_hw *mh = &ac97_hw[mixer];
-
-	M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right);
-
-	if(AC97_STEREO_MASK & (1<<mixer)) {
-		/* stereo mixers, mute them if we can */
-
-		if (mixer == SOUND_MIXER_IGAIN) {
-			/* igain's slider is reversed.. */
-			right = (right * mh->scale) / 100;
-			left = (left * mh->scale) / 100;
-			if ((left == 0) && (right == 0))
-				val |= 0x8000;
-		} else if (mixer == SOUND_MIXER_PCM || mixer == SOUND_MIXER_CD) {
-			/* log conversion seems bad for them */
-			if ((left == 0) && (right == 0))
-				val = 0x8000;
-			right = ((100 - right) * mh->scale) / 100;
-			left = ((100 - left) * mh->scale) / 100;
-		} else {
-			/* log conversion for the stereo controls */
-			if((left == 0) && (right == 0))
-				val = 0x8000;
-			right = ((100 - lin2log[right]) * mh->scale) / 100;
-			left = ((100 - lin2log[left]) * mh->scale) / 100;
-		}
-
-		val |= (left << 8) | right;
-
-	} else if (mixer == SOUND_MIXER_SPEAKER) {
-		val = (((100 - left) * mh->scale) / 100) << 1;
-	} else if (mixer == SOUND_MIXER_MIC) {
-		val = maestro_ac97_get(card, mh->offset) & ~0x801f;
-		val |= (((100 - left) * mh->scale) / 100);
-	/*  the low bit is optional in the tone sliders and masking
-		it lets is avoid the 0xf 'bypass'.. */
-	} else if (mixer == SOUND_MIXER_BASS) {
-		val = maestro_ac97_get(card , mh->offset) & ~0x0f00;
-		val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00;
-	} else if (mixer == SOUND_MIXER_TREBLE)  {
-		val = maestro_ac97_get(card , mh->offset) & ~0x000f;
-		val |= (((100 - left) * mh->scale) / 100) & 0x000e;
-	}
-
-	maestro_ac97_set(card , mh->offset, val);
-	
-	M_printk(" -> %x\n",val);
-}
-
-/* the following tables allow us to go from 
-	OSS <-> ac97 quickly. */
-
-enum ac97_recsettings {
-	AC97_REC_MIC=0,
-	AC97_REC_CD,
-	AC97_REC_VIDEO,
-	AC97_REC_AUX,
-	AC97_REC_LINE,
-	AC97_REC_STEREO, /* combination of all enabled outputs..  */
-	AC97_REC_MONO,        /*.. or the mono equivalent */
-	AC97_REC_PHONE        
-};
-
-static unsigned int ac97_oss_mask[] = {
-	[AC97_REC_MIC] = SOUND_MASK_MIC, 
-	[AC97_REC_CD] = SOUND_MASK_CD, 
-	[AC97_REC_VIDEO] = SOUND_MASK_VIDEO, 
-	[AC97_REC_AUX] = SOUND_MASK_LINE1, 
-	[AC97_REC_LINE] = SOUND_MASK_LINE, 
-	[AC97_REC_PHONE] = SOUND_MASK_PHONEIN
-};
-
-/* indexed by bit position */
-static unsigned int ac97_oss_rm[] = {
-	[SOUND_MIXER_MIC] = AC97_REC_MIC,
-	[SOUND_MIXER_CD] = AC97_REC_CD,
-	[SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
-	[SOUND_MIXER_LINE1] = AC97_REC_AUX,
-	[SOUND_MIXER_LINE] = AC97_REC_LINE,
-	[SOUND_MIXER_PHONEIN] = AC97_REC_PHONE
-};
-	
-/* read or write the recmask 
-	the ac97 can really have left and right recording
-	inputs independently set, but OSS doesn't seem to 
-	want us to express that to the user. 
-	the caller guarantees that we have a supported bit set,
-	and they must be holding the card's spinlock */
-static int 
-ac97_recmask_io(struct ess_card *card, int read, int mask) 
-{
-	unsigned int val = ac97_oss_mask[ maestro_ac97_get(card, 0x1a) & 0x7 ];
-
-	if (read) return val;
-
-	/* oss can have many inputs, maestro can't.  try
-		to pick the 'new' one */
-
-	if (mask != val) mask &= ~val;
-
-	val = ffs(mask) - 1; 
-	val = ac97_oss_rm[val];
-	val |= val << 8;  /* set both channels */
-
-	M_printk("maestro: setting ac97 recmask to 0x%x\n",val);
-
-	maestro_ac97_set(card,0x1a,val);
-
-	return 0;
-};
-
-/*
- *	The Maestro can be wired to a standard AC97 compliant codec
- *	(see www.intel.com for the pdf's on this), or to a PT101 codec
- *	which appears to be the ES1918 (data sheet on the esstech.com.tw site)
- *
- *	The PT101 setup is untested.
- */
- 
-static u16 __init maestro_ac97_init(struct ess_card *card)
-{
-	u16 vend1, vend2, caps;
-
-	card->mix.supported_mixers = AC97_SUPPORTED_MASK;
-	card->mix.stereo_mixers = AC97_STEREO_MASK;
-	card->mix.record_sources = AC97_RECORD_MASK;
-/*	card->mix.read_mixer = ac97_read_mixer;*/
-	card->mix.write_mixer = ac97_write_mixer;
-	card->mix.recmask_io = ac97_recmask_io;
-
-	vend1 = maestro_ac97_get(card, 0x7c);
-	vend2 = maestro_ac97_get(card, 0x7e);
-
-	caps = maestro_ac97_get(card, 0x00);
-
-	printk(KERN_INFO "maestro: AC97 Codec detected: v: 0x%2x%2x caps: 0x%x pwr: 0x%x\n",
-		vend1,vend2,caps,maestro_ac97_get(card,0x26) & 0xf);
-
-	if (! (caps & 0x4) ) {
-		/* no bass/treble nobs */
-		card->mix.supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
-	}
-
-	/* XXX endianness, dork head. */
-	/* vendor specifc bits.. */
-	switch ((long)(vend1 << 16) | vend2) {
-	case 0x545200ff:	/* TriTech */
-		/* no idea what this does */
-		maestro_ac97_set(card,0x2a,0x0001);
-		maestro_ac97_set(card,0x2c,0x0000);
-		maestro_ac97_set(card,0x2c,0xffff);
-		break;
-#if 0	/* i thought the problems I was seeing were with
-	the 1921, but apparently they were with the pci board
-	it was on, so this code is commented out.
-	 lets see if this holds true. */
-	case 0x83847609:	/* ESS 1921 */
-		/* writing to 0xe (mic) or 0x1a (recmask) seems
-			to hang this codec */
-		card->mix.supported_mixers &= ~(SOUND_MASK_MIC);
-		card->mix.record_sources = 0;
-		card->mix.recmask_io = NULL;
-#if 0	/* don't ask.  I have yet to see what these actually do. */
-		maestro_ac97_set(card,0x76,0xABBA); /* o/~ Take a chance on me o/~ */
-		udelay(20);
-		maestro_ac97_set(card,0x78,0x3002);
-		udelay(20);
-		maestro_ac97_set(card,0x78,0x3802);
-		udelay(20);
-#endif
-		break;
-#endif
-	default: break;
-	}
-
-	maestro_ac97_set(card, 0x1E, 0x0404);
-	/* null misc stuff */
-	maestro_ac97_set(card, 0x20, 0x0000);
-
-	return 0;
-}
-
-#if 0  /* there has been 1 person on the planet with a pt101 that we
-	know of.  If they care, they can put this back in :) */
-static u16 maestro_pt101_init(struct ess_card *card,int iobase)
-{
-	printk(KERN_INFO "maestro: PT101 Codec detected, initializing but _not_ installing mixer device.\n");
-	/* who knows.. */
-	maestro_ac97_set(iobase, 0x2A, 0x0001);
-	maestro_ac97_set(iobase, 0x2C, 0x0000);
-	maestro_ac97_set(iobase, 0x2C, 0xFFFF);
-	maestro_ac97_set(iobase, 0x10, 0x9F1F);
-	maestro_ac97_set(iobase, 0x12, 0x0808);
-	maestro_ac97_set(iobase, 0x14, 0x9F1F);
-	maestro_ac97_set(iobase, 0x16, 0x9F1F);
-	maestro_ac97_set(iobase, 0x18, 0x0404);
-	maestro_ac97_set(iobase, 0x1A, 0x0000);
-	maestro_ac97_set(iobase, 0x1C, 0x0000);
-	maestro_ac97_set(iobase, 0x02, 0x0404);
-	maestro_ac97_set(iobase, 0x04, 0x0808);
-	maestro_ac97_set(iobase, 0x0C, 0x801F);
-	maestro_ac97_set(iobase, 0x0E, 0x801F);
-	return 0;
-}
-#endif
-
-/* this is very magic, and very slow.. */
-static void 
-maestro_ac97_reset(int ioaddr, struct pci_dev *pcidev)
-{
-	u16 save_68;
-	u16 w;
-	u32 vend;
-
-	outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
-	outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
-	outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
-	/* reset the first codec */
-	outw(0x0000,  ioaddr+0x36);
-	save_68 = inw(ioaddr+0x68);
-	pci_read_config_word(pcidev, 0x58, &w);	/* something magical with gpio and bus arb. */
-	pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &vend);
-	if( w & 0x1)
-		save_68 |= 0x10;
-	outw(0xfffe, ioaddr + 0x64);	/* tickly gpio 0.. */
-	outw(0x0001, ioaddr + 0x68);
-	outw(0x0000, ioaddr + 0x60);
-	udelay(20);
-	outw(0x0001, ioaddr + 0x60);
-	mdelay(20);
-
-	outw(save_68 | 0x1, ioaddr + 0x68);	/* now restore .. */
-	outw( (inw(ioaddr + 0x38) & 0xfffc)|0x1, ioaddr + 0x38);
-	outw( (inw(ioaddr + 0x3a) & 0xfffc)|0x1, ioaddr + 0x3a);
-	outw( (inw(ioaddr + 0x3c) & 0xfffc)|0x1, ioaddr + 0x3c);
-
-	/* now the second codec */
-	outw(0x0000,  ioaddr+0x36);
-	outw(0xfff7, ioaddr + 0x64);
-	save_68 = inw(ioaddr+0x68);
-	outw(0x0009, ioaddr + 0x68);
-	outw(0x0001, ioaddr + 0x60);
-	udelay(20);
-	outw(0x0009, ioaddr + 0x60);
-	mdelay(500);	/* .. ouch.. */
-	outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
-	outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
-	outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
-#if 0 /* the loop here needs to be much better if we want it.. */
-	M_printk("trying software reset\n");
-	/* try and do a software reset */
-	outb(0x80|0x7c, ioaddr + 0x30);
-	for (w=0; ; w++) {
-		if ((inw(ioaddr+ 0x30) & 1) == 0) {
-			if(inb(ioaddr + 0x32) !=0) break;
-
-			outb(0x80|0x7d, ioaddr + 0x30);
-			if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
-			outb(0x80|0x7f, ioaddr + 0x30);
-			if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
-		}
-
-		if( w > 10000) {
-			outb( inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37);  /* do a software reset */
-			mdelay(500); /* oh my.. */
-			outb( inb(ioaddr + 0x37) & ~0x08, ioaddr + 0x37);  
-			udelay(1);
-			outw( 0x80, ioaddr+0x30);
-			for(w = 0 ; w < 10000; w++) {
-				if((inw(ioaddr + 0x30) & 1) ==0) break;
-			}
-		}
-	}
-#endif
-	if ( vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) {
-		/* turn on external amp? */
-		outw(0xf9ff, ioaddr + 0x64);
-		outw(inw(ioaddr+0x68) | 0x600, ioaddr + 0x68);
-		outw(0x0209, ioaddr + 0x60);
-	}
-
-	/* Turn on the 978 docking chip.
-	   First frob the "master output enable" bit,
-	   then set most of the playback volume control registers to max. */
-	outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0);
-	outb(0xff, ioaddr+0xc3);
-	outb(0xff, ioaddr+0xc4);
-	outb(0xff, ioaddr+0xc6);
-	outb(0xff, ioaddr+0xc8);
-	outb(0x3f, ioaddr+0xcf);
-	outb(0x3f, ioaddr+0xd0);
-}
-/*
- *	Indirect register access. Not all registers are readable so we
- *	need to keep register state ourselves
- */
- 
-#define WRITEABLE_MAP	0xEFFFFF
-#define READABLE_MAP	0x64003F
-
-/*
- *	The Maestro engineers were a little indirection happy. These indirected
- *	registers themselves include indirect registers at another layer
- */
-
-static void __maestro_write(struct ess_card *card, u16 reg, u16 data)
-{
-	long ioaddr = card->iobase;
-
-	outw(reg, ioaddr+0x02);
-	outw(data, ioaddr+0x00);
-	if( reg >= NR_IDRS) printk("maestro: IDR %d out of bounds!\n",reg);
-	else card->maestro_map[reg]=data;
-
-}
- 
-static void maestro_write(struct ess_state *s, u16 reg, u16 data)
-{
-	unsigned long flags;
-
-	check_suspend(s->card);
-	spin_lock_irqsave(&s->card->lock,flags);
-
-	__maestro_write(s->card,reg,data);
-
-	spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 __maestro_read(struct ess_card *card, u16 reg)
-{
-	long ioaddr = card->iobase;
-
-	outw(reg, ioaddr+0x02);
-	return card->maestro_map[reg]=inw(ioaddr+0x00);
-}
-
-static u16 maestro_read(struct ess_state *s, u16 reg)
-{
-	if(READABLE_MAP & (1<<reg))
-	{
-		unsigned long flags;
-		check_suspend(s->card);
-		spin_lock_irqsave(&s->card->lock,flags);
-
-		__maestro_read(s->card,reg);
-
-		spin_unlock_irqrestore(&s->card->lock,flags);
-	}
-	return s->card->maestro_map[reg];
-}
-
-/*
- *	These routines handle accessing the second level indirections to the
- *	wave ram.
- */
-
-/*
- *	The register names are the ones ESS uses (see 104T31.ZIP)
- */
- 
-#define IDR0_DATA_PORT		0x00
-#define IDR1_CRAM_POINTER	0x01
-#define IDR2_CRAM_DATA		0x02
-#define IDR3_WAVE_DATA		0x03
-#define IDR4_WAVE_PTR_LOW	0x04
-#define IDR5_WAVE_PTR_HI	0x05
-#define IDR6_TIMER_CTRL		0x06
-#define IDR7_WAVE_ROMRAM	0x07
-
-static void apu_index_set(struct ess_card *card, u16 index)
-{
-	int i;
-	__maestro_write(card, IDR1_CRAM_POINTER, index);
-	for(i=0;i<1000;i++)
-		if(__maestro_read(card, IDR1_CRAM_POINTER)==index)
-			return;
-	printk(KERN_WARNING "maestro: APU register select failed.\n");
-}
-
-static void apu_data_set(struct ess_card *card, u16 data)
-{
-	int i;
-	for(i=0;i<1000;i++)
-	{
-		if(__maestro_read(card, IDR0_DATA_PORT)==data)
-			return;
-		__maestro_write(card, IDR0_DATA_PORT, data);
-	}
-}
-
-/*
- *	This is the public interface for APU manipulation. It handles the
- *	interlock to avoid two APU writes in parallel etc. Don't diddle
- *	directly with the stuff above.
- */
-
-static void apu_set_register(struct ess_state *s, u16 channel, u8 reg, u16 data)
-{
-	unsigned long flags;
-	
-	check_suspend(s->card);
-
-	if(channel&ESS_CHAN_HARD)
-		channel&=~ESS_CHAN_HARD;
-	else
-	{
-		if(channel>5)
-			printk("BAD CHANNEL %d.\n",channel);
-		else
-			channel = s->apu[channel];
-		/* store based on real hardware apu/reg */
-		s->card->apu_map[channel][reg]=data;
-	}
-	reg|=(channel<<4);
-	
-	/* hooray for double indirection!! */
-	spin_lock_irqsave(&s->card->lock,flags);
-
-	apu_index_set(s->card, reg);
-	apu_data_set(s->card, data);
-
-	spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 apu_get_register(struct ess_state *s, u16 channel, u8 reg)
-{
-	unsigned long flags;
-	u16 v;
-	
-	check_suspend(s->card);
-
-	if(channel&ESS_CHAN_HARD)
-		channel&=~ESS_CHAN_HARD;
-	else
-		channel = s->apu[channel];
-
-	reg|=(channel<<4);
-	
-	spin_lock_irqsave(&s->card->lock,flags);
-
-	apu_index_set(s->card, reg);
-	v=__maestro_read(s->card, IDR0_DATA_PORT);
-
-	spin_unlock_irqrestore(&s->card->lock,flags);
-	return v;
-}
-
-
-/*
- *	The wavecache buffers between the APUs and
- *	pci bus mastering
- */
- 
-static void wave_set_register(struct ess_state *s, u16 reg, u16 value)
-{
-	long ioaddr = s->card->iobase;
-	unsigned long flags;
-	check_suspend(s->card);
-	
-	spin_lock_irqsave(&s->card->lock,flags);
-
-	outw(reg, ioaddr+0x10);
-	outw(value, ioaddr+0x12);
-
-	spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 wave_get_register(struct ess_state *s, u16 reg)
-{
-	long ioaddr = s->card->iobase;
-	unsigned long flags;
-	u16 value;
-	check_suspend(s->card);
-	
-	spin_lock_irqsave(&s->card->lock,flags);
-	outw(reg, ioaddr+0x10);
-	value=inw(ioaddr+0x12);
-	spin_unlock_irqrestore(&s->card->lock,flags);
-	
-	return value;
-}
-
-static void sound_reset(int ioaddr)
-{
-	outw(0x2000, 0x18+ioaddr);
-	udelay(1);
-	outw(0x0000, 0x18+ioaddr);
-	udelay(1);
-}
-
-/* sets the play formats of these apus, should be passed the already shifted format */
-static void set_apu_fmt(struct ess_state *s, int apu, int mode)
-{
-	int apu_fmt = 0x10;
-
-	if(!(mode&ESS_FMT_16BIT)) apu_fmt+=0x20; 
-	if((mode&ESS_FMT_STEREO)) apu_fmt+=0x10; 
-	s->apu_mode[apu]   = apu_fmt;
-	s->apu_mode[apu+1] = apu_fmt;
-}
-
-/* this only fixes the output apu mode to be later set by start_dac and
-	company.  output apu modes are set in ess_rec_setup */
-static void set_fmt(struct ess_state *s, unsigned char mask, unsigned char data)
-{
-	s->fmt = (s->fmt & mask) | data;
-	set_apu_fmt(s, 0, (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK);
-}
-
-/* this is off by a little bit.. */
-static u32 compute_rate(struct ess_state *s, u32 freq)
-{
-	u32 clock = clock_freq[s->card->card_type];     
-
-	freq = (freq * clocking)/48000;
-	
-	if (freq == 48000) 
-		return 0x10000;
-
-	return ((freq / clock) <<16 )+  
-		(((freq % clock) << 16) / clock);
-}
-
-static void set_dac_rate(struct ess_state *s, unsigned int rate)
-{
-	u32 freq;
-	int fmt = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
-
-	s->ratedac = rate;
-
-	if(! (fmt & ESS_FMT_16BIT) && !(fmt & ESS_FMT_STEREO))
-		rate >>= 1;
-
-/*	M_printk("computing dac rate %d with mode %d\n",rate,s->fmt);*/
-
-	freq = compute_rate(s, rate);
-	
-	/* Load the frequency, turn on 6dB */
-	apu_set_register(s, 0, 2,(apu_get_register(s, 0, 2)&0x00FF)|
-		( ((freq&0xFF)<<8)|0x10 ));
-	apu_set_register(s, 0, 3, freq>>8);
-	apu_set_register(s, 1, 2,(apu_get_register(s, 1, 2)&0x00FF)|
-		( ((freq&0xFF)<<8)|0x10 ));
-	apu_set_register(s, 1, 3, freq>>8);
-}
-
-static void set_adc_rate(struct ess_state *s, unsigned rate)
-{
-	u32 freq;
-
-	/* Sample Rate conversion APUs don't like 0x10000 for their rate */
-	if (rate > 47999)
-		rate = 47999;
-	if (rate < 4000)
-		rate = 4000;
-
-	s->rateadc = rate;
-
-	freq = compute_rate(s, rate);
-	
-	/* Load the frequency, turn on 6dB */
-	apu_set_register(s, 2, 2,(apu_get_register(s, 2, 2)&0x00FF)|
-		( ((freq&0xFF)<<8)|0x10 ));
-	apu_set_register(s, 2, 3, freq>>8);
-	apu_set_register(s, 3, 2,(apu_get_register(s, 3, 2)&0x00FF)|
-		( ((freq&0xFF)<<8)|0x10 ));
-	apu_set_register(s, 3, 3, freq>>8);
-
-	/* fix mixer rate at 48khz.  and its _must_ be 0x10000. */
-	freq = 0x10000;
-
-	apu_set_register(s, 4, 2,(apu_get_register(s, 4, 2)&0x00FF)|
-		( ((freq&0xFF)<<8)|0x10 ));
-	apu_set_register(s, 4, 3, freq>>8);
-	apu_set_register(s, 5, 2,(apu_get_register(s, 5, 2)&0x00FF)|
-		( ((freq&0xFF)<<8)|0x10 ));
-	apu_set_register(s, 5, 3, freq>>8);
-}
-
-/* Stop our host of recording apus */
-static inline void stop_adc(struct ess_state *s)
-{
-	/* XXX lets hope we don't have to lock around this */
-	if (! (s->enable & ADC_RUNNING)) return;
-
-	s->enable &= ~ADC_RUNNING;
-	apu_set_register(s, 2, 0, apu_get_register(s, 2, 0)&0xFF0F);
-	apu_set_register(s, 3, 0, apu_get_register(s, 3, 0)&0xFF0F);
-	apu_set_register(s, 4, 0, apu_get_register(s, 2, 0)&0xFF0F);
-	apu_set_register(s, 5, 0, apu_get_register(s, 3, 0)&0xFF0F);
-}	
-
-/* stop output apus */
-static void stop_dac(struct ess_state *s)
-{
-	/* XXX have to lock around this? */
-	if (! (s->enable & DAC_RUNNING)) return;
-
-	s->enable &= ~DAC_RUNNING;
-	apu_set_register(s, 0, 0, apu_get_register(s, 0, 0)&0xFF0F);
-	apu_set_register(s, 1, 0, apu_get_register(s, 1, 0)&0xFF0F);
-}	
-
-static void start_dac(struct ess_state *s)
-{
-	/* XXX locks? */
-	if (	(s->dma_dac.mapped || s->dma_dac.count > 0) && 
-		s->dma_dac.ready &&
-		(! (s->enable & DAC_RUNNING)) ) {
-
-		s->enable |= DAC_RUNNING;
-
-		apu_set_register(s, 0, 0, 
-			(apu_get_register(s, 0, 0)&0xFF0F)|s->apu_mode[0]);
-
-		if((s->fmt >> ESS_DAC_SHIFT)  & ESS_FMT_STEREO) 
-			apu_set_register(s, 1, 0, 
-				(apu_get_register(s, 1, 0)&0xFF0F)|s->apu_mode[1]);
-	}
-}	
-
-static void start_adc(struct ess_state *s)
-{
-	/* XXX locks? */
-	if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-	    && s->dma_adc.ready && (! (s->enable & ADC_RUNNING)) ) {
-
-		s->enable |= ADC_RUNNING;
-		apu_set_register(s, 2, 0, 
-			(apu_get_register(s, 2, 0)&0xFF0F)|s->apu_mode[2]);
-		apu_set_register(s, 4, 0, 
-			(apu_get_register(s, 4, 0)&0xFF0F)|s->apu_mode[4]);
-
-		if( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-			apu_set_register(s, 3, 0, 
-				(apu_get_register(s, 3, 0)&0xFF0F)|s->apu_mode[3]);
-			apu_set_register(s, 5, 0, 
-				(apu_get_register(s, 5, 0)&0xFF0F)|s->apu_mode[5]);
-		}
-			
-	}
-}	
-
-
-/*
- *	Native play back driver 
- */
-
-/* the mode passed should be already shifted and masked */
-static void 
-ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
-{
-	u32 pa;
-	u32 tmpval;
-	int high_apu = 0;
-	int channel;
-
-	M_printk("mode=%d rate=%d buf=%p len=%d.\n",
-		mode, rate, buffer, size);
-		
-	/* all maestro sizes are in 16bit words */
-	size >>=1;
-
-	if(mode&ESS_FMT_STEREO) {
-		high_apu++;
-		/* only 16/stereo gets size divided */
-		if(mode&ESS_FMT_16BIT)
-			size>>=1;
-	}
-	
-	for(channel=0; channel <= high_apu; channel++)
-	{
-		pa = virt_to_bus(buffer);
-
-		/* set the wavecache control reg */
-		tmpval = (pa - 0x10) & 0xFFF8;
-		if(!(mode & ESS_FMT_16BIT)) tmpval |= 4;
-		if(mode & ESS_FMT_STEREO) tmpval |= 2;
-		ess->apu_base[channel]=tmpval;
-		wave_set_register(ess, ess->apu[channel]<<3, tmpval);
-		
-		pa -= virt_to_bus(ess->card->dmapages);
-		pa>>=1; /* words */
-		
-		/* base offset of dma calcs when reading the pointer
-			on the left one */
-		if(!channel) ess->dma_dac.base = pa&0xFFFF;
-		
-		pa|=0x00400000;			/* System RAM */
-
-		/* XXX the 16bit here might not be needed.. */
-		if((mode & ESS_FMT_STEREO) && (mode & ESS_FMT_16BIT)) {
-			if(channel) 
-				pa|=0x00800000;			/* Stereo */
-			pa>>=1;
-		}
-			
-/* XXX think about endianess when writing these registers */
-		M_printk("maestro: ess_play_setup: APU[%d] pa = 0x%x\n", ess->apu[channel], pa);
-		/* start of sample */
-		apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8);
-		apu_set_register(ess, channel, 5, pa&0xFFFF);
-		/* sample end */
-		apu_set_register(ess, channel, 6, (pa+size)&0xFFFF);
-		/* setting loop len == sample len */
-		apu_set_register(ess, channel, 7, size);
-		
-		/* clear effects/env.. */
-		apu_set_register(ess, channel, 8, 0x0000);
-		/* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */
-		apu_set_register(ess, channel, 9, 0xD000);
-
-		/* clear routing stuff */
-		apu_set_register(ess, channel, 11, 0x0000);
-		/* dma on, no envelopes, filter to all 1s) */
-		apu_set_register(ess, channel, 0, 0x400F);
-		
-		if(mode&ESS_FMT_16BIT)
-			ess->apu_mode[channel]=0x10;
-		else
-			ess->apu_mode[channel]=0x30;
-
-		if(mode&ESS_FMT_STEREO) {
-			/* set panning: left or right */
-			apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0 : 0x10));
-			ess->apu_mode[channel] += 0x10;
-		} else
-			apu_set_register(ess, channel, 10, 0x8F08);
-	}
-	
-	/* clear WP interrupts */
-	outw(1, ess->card->iobase+0x04);
-	/* enable WP ints */
-	outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
-
-	/* go team! */
-	set_dac_rate(ess,rate);
-	start_dac(ess);
-}
-
-/*
- *	Native record driver 
- */
-
-/* again, passed mode is alrady shifted/masked */
-static void 
-ess_rec_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
-{
-	int apu_step = 2;
-	int channel;
-
-	M_printk("maestro: ess_rec_setup: mode=%d rate=%d buf=0x%p len=%d.\n",
-		mode, rate, buffer, size);
-		
-	/* all maestro sizes are in 16bit words */
-	size >>=1;
-
-	/* we're given the full size of the buffer, but
-	in stereo each channel will only use its half */
-	if(mode&ESS_FMT_STEREO) {
-		size >>=1; 
-		apu_step = 1;
-	}
-	
-	/* APU assignments: 2 = mono/left SRC
-	                    3 = right SRC
-	                    4 = mono/left Input Mixer
-	                    5 = right Input Mixer */
-	for(channel=2;channel<6;channel+=apu_step)
-	{
-		int i;
-		int bsize, route;
-		u32 pa;
-		u32 tmpval;
-
-		/* data seems to flow from the codec, through an apu into
-			the 'mixbuf' bit of page, then through the SRC apu
-			and out to the real 'buffer'.  ok.  sure.  */
-		
-		if(channel & 0x04) {
-			/* ok, we're an input mixer going from adc
-				through the mixbuf to the other apus */
-
-			if(!(channel & 0x01)) { 
-				pa = virt_to_bus(ess->mixbuf);
-			} else {
-				pa = virt_to_bus(ess->mixbuf + (PAGE_SIZE >> 4));
-			}
-
-			/* we source from a 'magic' apu */
-			bsize = PAGE_SIZE >> 5;	/* half of this channels alloc, in words */
-			route = 0x14 + (channel - 4); /* parallel in crap, see maestro reg 0xC [8-11] */
-			ess->apu_mode[channel] = 0x90;  /* Input Mixer */
-
-		} else {  
-			/* we're a rate converter taking
-				input from the input apus and outputing it to
-				system memory */
-			if(!(channel & 0x01))  {
-				pa = virt_to_bus(buffer);
-			} else {
-				/* right channel records its split half.
-				*2 accommodates for rampant shifting earlier */
-				pa = virt_to_bus(buffer + size*2);
-			}
-
-			ess->apu_mode[channel] = 0xB0;  /* Sample Rate Converter */
-
-			bsize = size; 
-			/* get input from inputing apu */
-			route = channel + 2;
-		}
-
-		M_printk("maestro: ess_rec_setup: getting pa 0x%x from %d\n",pa,channel);
-		
-		/* set the wavecache control reg */
-		tmpval = (pa - 0x10) & 0xFFF8;
-		ess->apu_base[channel]=tmpval;
-		wave_set_register(ess, ess->apu[channel]<<3, tmpval);
-		
-		pa -= virt_to_bus(ess->card->dmapages);
-		pa>>=1; /* words */
-		
-		/* base offset of dma calcs when reading the pointer
-			on this left one */
-		if(channel==2) ess->dma_adc.base = pa&0xFFFF;
-
-		pa|=0x00400000;			/* bit 22 -> System RAM */
-
-		M_printk("maestro: ess_rec_setup: APU[%d] pa = 0x%x size = 0x%x route = 0x%x\n", 
-			ess->apu[channel], pa, bsize, route);
-		
-		/* Begin loading the APU */		
-		for(i=0;i<15;i++)		/* clear all PBRs */
-			apu_set_register(ess, channel, i, 0x0000);
-			
-		apu_set_register(ess, channel, 0, 0x400F);
-
-		/* need to enable subgroups.. and we should probably
-			have different groups for different /dev/dsps..  */
- 		apu_set_register(ess, channel, 2, 0x8);
-				
-		/* Load the buffer into the wave engine */
-		apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8);
-		/* XXX reg is little endian.. */
-		apu_set_register(ess, channel, 5, pa&0xFFFF);
-		apu_set_register(ess, channel, 6, (pa+bsize)&0xFFFF);
-		apu_set_register(ess, channel, 7, bsize);
-				
-		/* clear effects/env.. */
-		apu_set_register(ess, channel, 8, 0x00F0);
-		
-		/* amplitude now?  sure.  why not.  */
-		apu_set_register(ess, channel, 9, 0x0000);
-
-		/* set filter tune, radius, polar pan */
-		apu_set_register(ess, channel, 10, 0x8F08);
-
-		/* route input */
-		apu_set_register(ess, channel, 11, route);
-	}
-	
-	/* clear WP interrupts */
-	outw(1, ess->card->iobase+0x04);
-	/* enable WP ints */
-	outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
-
-	/* let 'er rip */
-	set_adc_rate(ess,rate);
-	start_adc(ess);
-}
-/* --------------------------------------------------------------------- */
-
-static void set_dmaa(struct ess_state *s, unsigned int addr, unsigned int count)
-{
-	M_printk("set_dmaa??\n");
-}
-
-static void set_dmac(struct ess_state *s, unsigned int addr, unsigned int count)
-{
-	M_printk("set_dmac??\n");
-}
-
-/* Playback pointer */
-static inline unsigned get_dmaa(struct ess_state *s)
-{
-	int offset;
-
-	offset = apu_get_register(s,0,5);
-
-/*	M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base); */
-	
-	offset-=s->dma_dac.base;
-
-	return (offset&0xFFFE)<<1; /* hardware is in words */
-}
-
-/* Record pointer */
-static inline unsigned get_dmac(struct ess_state *s)
-{
-	int offset;
-
-	offset = apu_get_register(s,2,5);
-
-/*	M_printk("dmac: offset: %d, base: %d\n",offset,s->dma_adc.base); */
-	
-	/* The offset is an address not a position relative to base */
-	offset-=s->dma_adc.base;
-	
-	return (offset&0xFFFE)<<1; /* hardware is in words */
-}
-
-/*
- *	Meet Bob, the timer...
- */
-
-static irqreturn_t ess_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static void stop_bob(struct ess_state *s)
-{
-	/* Mask IDR 11,17 */
-	maestro_write(s,  0x11, maestro_read(s, 0x11)&~1);
-	maestro_write(s,  0x17, maestro_read(s, 0x17)&~1);
-}
-
-/* eventually we could be clever and limit bob ints
-	to the frequency at which our smallest duration
-	chunks may expire */
-#define ESS_SYSCLK	50000000
-static void start_bob(struct ess_state *s)
-{
-	int prescale;
-	int divide;
-	
-	/* XXX make freq selector much smarter, see calc_bob_rate */
-	int freq = 200; 
-	
-	/* compute ideal interrupt frequency for buffer size & play rate */
-	/* first, find best prescaler value to match freq */
-	for(prescale=5;prescale<12;prescale++)
-		if(freq > (ESS_SYSCLK>>(prescale+9)))
-			break;
-			
-	/* next, back off prescaler whilst getting divider into optimum range */
-	divide=1;
-	while((prescale > 5) && (divide<32))
-	{
-		prescale--;
-		divide <<=1;
-	}
-	divide>>=1;
-	
-	/* now fine-tune the divider for best match */
-	for(;divide<31;divide++)
-		if(freq >= ((ESS_SYSCLK>>(prescale+9))/(divide+1)))
-			break;
-	
-	/* divide = 0 is illegal, but don't let prescale = 4! */
-	if(divide == 0)
-	{
-		divide++;
-		if(prescale>5)
-			prescale--;
-	}
-
-	maestro_write(s, 6, 0x9000 | (prescale<<5) | divide); /* set reg */
-	
-	/* Now set IDR 11/17 */
-	maestro_write(s, 0x11, maestro_read(s, 0x11)|1);
-	maestro_write(s, 0x17, maestro_read(s, 0x17)|1);
-}
-/* --------------------------------------------------------------------- */
-
-/* this quickly calculates the frequency needed for bob
-	and sets it if its different than what bob is
-	currently running at.  its called often so 
-	needs to be fairly quick. */
-#define BOB_MIN 50
-#define BOB_MAX 400
-static void calc_bob_rate(struct ess_state *s) {
-#if 0 /* this thing tries to set the frequency of bob such that
-	there are 2 interrupts / buffer walked by the dac/adc.  That
-	is probably very wrong for people who actually care about 
-	mid buffer positioning.  it should be calculated as bytes/interrupt
-	and that needs to be decided :)  so for now just use the static 150
-	in start_bob.*/
-
-	unsigned int dac_rate=2,adc_rate=1,newrate;
-	static int israte=-1;
-
-	if (s->dma_dac.fragsize == 0) dac_rate = BOB_MIN;
-	else  {
-		dac_rate =	(2 * s->ratedac * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) /
-				(s->dma_dac.fragsize) ;
-	}
-		
-	if (s->dma_adc.fragsize == 0) adc_rate = BOB_MIN;
-	else {
-		adc_rate =	(2 * s->rateadc * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) /
-				(s->dma_adc.fragsize) ;
-	}
-
-	if(dac_rate > adc_rate) newrate = adc_rate;
-	else newrate=dac_rate;
-
-	if(newrate > BOB_MAX) newrate = BOB_MAX;
-	else {
-		if(newrate < BOB_MIN) 
-			newrate = BOB_MIN;
-	}
-
-	if( israte != newrate) {
-		printk("dac: %d  adc: %d rate: %d\n",dac_rate,adc_rate,israte);
-		israte=newrate;
-	}
-#endif
-
-}
-
-static int 
-prog_dmabuf(struct ess_state *s, unsigned rec)
-{
-	struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-	unsigned rate = rec ? s->rateadc : s->ratedac;
-	unsigned bytepersec;
-	unsigned bufs;
-	unsigned char fmt;
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	fmt = s->fmt;
-	if (rec) {
-		stop_adc(s);
-		fmt >>= ESS_ADC_SHIFT;
-	} else {
-		stop_dac(s);
-		fmt >>= ESS_DAC_SHIFT;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	fmt &= ESS_FMT_MASK;
-
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-
-	/* this algorithm is a little nuts.. where did /1000 come from? */
-	bytepersec = rate << sample_shift[fmt];
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < bytepersec)
-			db->fragshift = ld2(bytepersec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3; 
-	}
-	db->numfrag = bufs >> db->fragshift;
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->numfrag = bufs >> db->fragshift;
-	}
-	db->fragsize = 1 << db->fragshift;
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
-	db->fragsamples = db->fragsize >> sample_shift[fmt];
-	db->dmasize = db->numfrag << db->fragshift;
-
-	M_printk("maestro: setup oss: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize);
-
-	memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize);
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (rec) 
-		ess_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize);
-	else 
-		ess_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize);
-
-	spin_unlock_irqrestore(&s->lock, flags);
-	db->ready = 1;
-
-	return 0;
-}
-
-static __inline__ void 
-clear_advance(struct ess_state *s)
-{
-	unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
-	
-	unsigned char *buf = s->dma_dac.rawbuf;
-	unsigned bsize = s->dma_dac.dmasize;
-	unsigned bptr = s->dma_dac.swptr;
-	unsigned len = s->dma_dac.fragsize;
-	
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(buf + bptr, c, x);
-		/* account for wrapping? */
-		bptr = 0;
-		len -= x;
-	}
-	memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void 
-ess_update_ptr(struct ess_state *s)
-{
-	unsigned hwptr;
-	int diff;
-
-	/* update ADC pointer */
-	if (s->dma_adc.ready) {
-		/* oh boy should this all be re-written.  everything in the current code paths think
-		that the various counters/pointers are expressed in bytes to the user but we have
-		two apus doing stereo stuff so we fix it up here.. it propagates to all the various
-		counters from here.  */
-		if ( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-			hwptr = (get_dmac(s)*2) % s->dma_adc.dmasize;
-		} else {
-			hwptr = get_dmac(s) % s->dma_adc.dmasize;
-		}
-		diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-		s->dma_adc.hwptr = hwptr;
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-			wake_up(&s->dma_adc.wait);
-		if (!s->dma_adc.mapped) {
-			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-				/* FILL ME 
-				wrindir(s, SV_CIENABLE, s->enable); */
-				stop_adc(s); 
-				/* brute force everyone back in sync, sigh */
-				s->dma_adc.count = 0;
-				s->dma_adc.swptr = 0;
-				s->dma_adc.hwptr = 0;
-				s->dma_adc.error++;
-			}
-		}
-	}
-	/* update DAC pointer */
-	if (s->dma_dac.ready) {
-		hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
-		/* the apu only reports the length it has seen, not the
-			length of the memory that has been used (the WP
-			knows that) */
-		if ( ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK) == (ESS_FMT_STEREO|ESS_FMT_16BIT))
-			hwptr<<=1;
-
-		diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-/*		M_printk("updating dac: hwptr: %d diff: %d\n",hwptr,diff);*/
-		s->dma_dac.hwptr = hwptr;
-		s->dma_dac.total_bytes += diff;
-		if (s->dma_dac.mapped) {
-			s->dma_dac.count += diff;
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) {
-				wake_up(&s->dma_dac.wait);
-			}
-		} else {
-			s->dma_dac.count -= diff;
-/*			M_printk("maestro: ess_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); */
-			if (s->dma_dac.count <= 0) {
-				M_printk("underflow! diff: %d count: %d hw: %d sw: %d\n", diff, s->dma_dac.count, 
-					hwptr, s->dma_dac.swptr);
-				/* FILL ME 
-				wrindir(s, SV_CIENABLE, s->enable); */
-				/* XXX how on earth can calling this with the lock held work.. */
-				stop_dac(s);
-				/* brute force everyone back in sync, sigh */
-				s->dma_dac.count = 0; 
-				s->dma_dac.swptr = hwptr; 
-				s->dma_dac.error++;
-			} else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-				clear_advance(s);
-				s->dma_dac.endcleared = 1;
-			}
-			if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) {
-				wake_up(&s->dma_dac.wait);
-/*				printk("waking up DAC count: %d sw: %d hw: %d\n",s->dma_dac.count, s->dma_dac.swptr, 
-					hwptr);*/
-			}
-		}
-	}
-}
-
-static irqreturn_t
-ess_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct ess_state *s;
-        struct ess_card *c = (struct ess_card *)dev_id;
-	int i;
-	u32 event;
-
-	if ( ! (event = inb(c->iobase+0x1A)) )
-		return IRQ_NONE;
-
-	outw(inw(c->iobase+4)&1, c->iobase+4);
-
-/*	M_printk("maestro int: %x\n",event);*/
-	if(event&(1<<6))
-	{
-		int x;
-		enum {UP_EVT, DOWN_EVT, MUTE_EVT} vol_evt;
-		int volume;
-
-		/* Figure out which volume control button was pushed,
-		   based on differences from the default register
-		   values. */
-		x = inb(c->iobase+0x1c);
-		if (x&1) vol_evt = MUTE_EVT;
-		else if (((x>>1)&7) > 4) vol_evt = UP_EVT;
-		else vol_evt = DOWN_EVT;
-
-		/* Reset the volume control registers. */
-		outb(0x88, c->iobase+0x1c);
-		outb(0x88, c->iobase+0x1d);
-		outb(0x88, c->iobase+0x1e);
-		outb(0x88, c->iobase+0x1f);
-
-		/* Deal with the button press in a hammer-handed
-		   manner by adjusting the master mixer volume. */
-		volume = c->mix.mixer_state[0] & 0xff;
-		if (vol_evt == UP_EVT) {
-			volume += 5;
-			if (volume > 100)
-				volume = 100;
-		}
-		else if (vol_evt == DOWN_EVT) {
-			volume -= 5;
-			if (volume < 0)
-				volume = 0;
-		} else {
-			/* vol_evt == MUTE_EVT */
-			if (volume == 0)
-				volume = c->dock_mute_vol;
-			else {
-				c->dock_mute_vol = volume;
-				volume = 0;
-			}
-		}
-		set_mixer (c, 0, (volume << 8) | volume);
-	}
-
-	/* Ack all the interrupts. */
-	outb(0xFF, c->iobase+0x1A);
-		
-	/*
-	 *	Update the pointers for all APU's we are running.
-	 */
-	for(i=0;i<NR_DSPS;i++)
-	{
-		s=&c->channels[i];
-		if(s->dev_audio == -1)
-			break;
-		spin_lock(&s->lock);
-		ess_update_ptr(s);
-		spin_unlock(&s->lock);
-	}
-	return IRQ_HANDLED;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "maestro: invalid magic value in %s\n";
-
-#define VALIDATE_MAGIC(FOO,MAG)                         \
-({                                                \
-	if (!(FOO) || (FOO)->magic != MAG) { \
-		printk(invalid_magic,__FUNCTION__);            \
-		return -ENXIO;                    \
-	}                                         \
-})
-
-#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,ESS_STATE_MAGIC)
-#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,ESS_CARD_MAGIC)
-
-static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val ) 
-{
-	unsigned int left,right;
-	/* cleanse input a little */
-	right = ((val >> 8)  & 0xff) ;
-	left = (val  & 0xff) ;
-
-	if(right > 100) right = 100;
-	if(left > 100) left = 100;
-
-	card->mix.mixer_state[mixer]=(right << 8) | left;
-	card->mix.write_mixer(card,mixer,left,right);
-}
-
-static void
-mixer_push_state(struct ess_card *card)
-{
-	int i;
-	for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) {
-		if( ! supported_mixer(card,i)) continue;
-
-		set_mixer(card,i,card->mix.mixer_state[i]);
-	}
-}
-
-static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg)
-{
-	int i, val=0;
-	unsigned long flags;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_CARD(card);
-        if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		memset(&info, 0, sizeof(info));
-		strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
-		strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
-		info.modify_counter = card->mix.modcnt;
-		if (copy_to_user(argp, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == SOUND_OLD_MIXER_INFO) {
-		_old_mixer_info info;
-		memset(&info, 0, sizeof(info));
-		strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
-		strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
-		if (copy_to_user(argp, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, p);
-
-	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-
-        if (_IOC_DIR(cmd) == _IOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* give them the current record source */
-
-			if(!card->mix.recmask_io) {
-				val = 0;
-			} else {
-                               spin_lock_irqsave(&card->lock, flags);
-				val = card->mix.recmask_io(card,1,0);
-                               spin_unlock_irqrestore(&card->lock, flags);
-			}
-			break;
-			
-                case SOUND_MIXER_DEVMASK: /* give them the supported mixers */
-			val = card->mix.supported_mixers;
-			break;
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-			val = card->mix.record_sources;
-			break;
-			
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-			val = card->mix.stereo_mixers;
-			break;
-			
-                case SOUND_MIXER_CAPS:
-			val = SOUND_CAP_EXCL_INPUT;
-			break;
-
-		default: /* read a specific mixer */
-			i = _IOC_NR(cmd);
-
-			if ( ! supported_mixer(card,i)) 
-				return -EINVAL;
-
-			/* do we ever want to touch the hardware? */
-/*                     spin_lock_irqsave(&card->lock, flags);
-			val = card->mix.read_mixer(card,i);
-                       spin_unlock_irqrestore(&card->lock, flags);*/
-
-			val = card->mix.mixer_state[i];
-/*			M_printk("returned 0x%x for mixer %d\n",val,i);*/
-
-			break;
-		}
-		return put_user(val, p);
-	}
-	
-        if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
-		return -EINVAL;
-	
-	card->mix.modcnt++;
-
-	if (get_user(val, p))
-		return -EFAULT;
-
-	switch (_IOC_NR(cmd)) {
-	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-
-		if (!card->mix.recmask_io) return -EINVAL;
-		if(!val) return 0;
-		if(! (val &= card->mix.record_sources)) return -EINVAL;
-
-               spin_lock_irqsave(&card->lock, flags);
-		card->mix.recmask_io(card,0,val);
-               spin_unlock_irqrestore(&card->lock, flags);
-		return 0;
-
-	default:
-		i = _IOC_NR(cmd);
-
-		if ( ! supported_mixer(card,i)) 
-			return -EINVAL;
-
-               spin_lock_irqsave(&card->lock, flags);
-		set_mixer(card,i,val);
-               spin_unlock_irqrestore(&card->lock, flags);
-
-		return 0;
-	}
-}
-
-/* --------------------------------------------------------------------- */
-static int ess_open_mixdev(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	struct ess_card *card = NULL;
-	struct pci_dev *pdev = NULL;
-	struct pci_driver *drvr;
-
-	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-		drvr = pci_dev_driver (pdev);
-		if (drvr == &maestro_pci_driver) {
-			card = (struct ess_card*)pci_get_drvdata (pdev);
-			if (!card)
-				continue;
-			if (card->dev_mixer == minor)
-				break;
-		}
-	}
-	if (!card)
-		return -ENODEV;
-	file->private_data = card;
-	return nonseekable_open(inode, file);
-}
-
-static int ess_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct ess_card *card = (struct ess_card *)file->private_data;
-
-	VALIDATE_CARD(card);
-	
-	return 0;
-}
-
-static int ess_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct ess_card *card = (struct ess_card *)file->private_data;
-
-	VALIDATE_CARD(card);
-
-	return mixer_ioctl(card, cmd, arg);
-}
-
-static /*const*/ struct file_operations ess_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= ess_ioctl_mixdev,
-	.open		= ess_open_mixdev,
-	.release	= ess_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct ess_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	unsigned long flags;
-	int count;
-	signed long tmo;
-
-	if (s->dma_dac.mapped || !s->dma_dac.ready)
-		return 0;
-	current->state = TASK_INTERRUPTIBLE;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-		/* XXX uhm.. questionable locking*/
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-			current->state = TASK_RUNNING;
-                        return -EBUSY;
-                }
-		tmo = (count * HZ) / s->ratedac;
-		tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];
-		/* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
-			or something.  who cares. - zach */
-		if (!schedule_timeout(tmo ? tmo : 1) && tmo)
-			M_printk(KERN_DEBUG "maestro: dma timed out?? %ld\n",jiffies);
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-	current->state = TASK_RUNNING;
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/* Zach sez: "god this is gross.." */
-static int 
-comb_stereo(unsigned char *real_buffer,unsigned char  *tmp_buffer, int offset, 
-	int count, int bufsize)
-{  
-	/* No such thing as stereo recording, so we
-	use dual input mixers.  which means we have to 
-	combine mono to stereo buffer.  yuck. 
-
-	but we don't have to be able to work a byte at a time..*/
-
-	unsigned char *so,*left,*right;
-	int i;
-
-	so = tmp_buffer;
-	left = real_buffer + offset;
-	right = real_buffer + bufsize/2 + offset;
-
-/*	M_printk("comb_stereo writing %d to %p from %p and %p, offset: %d size: %d\n",count/2, tmp_buffer,left,right,offset,bufsize);*/
-
-	for(i=count/4; i ; i--) {
-		(*(so+2)) = *(right++);
-		(*(so+3)) = *(right++);
-		(*so) = *(left++);
-		(*(so+1)) = *(left++);
-		so+=4;
-	}
-
-	return 0;
-}
-
-/* in this loop, dma_adc.count signifies the amount of data thats waiting
-	to be copied to the user's buffer.  it is filled by the interrupt
-	handler and drained by this loop. */
-static ssize_t 
-ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct ess_state *s = (struct ess_state *)file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-	unsigned char *combbuf = NULL;
-	
-	VALIDATE_STATE(s);
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	if(!(combbuf = kmalloc(count,GFP_KERNEL)))
-		return -ENOMEM;
-	ret = 0;
-
-	calc_bob_rate(s);
-
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		/* remember, all these things are expressed in bytes to be
-			sent to the user.. hence the evil / 2 down below */
-		swptr = s->dma_adc.swptr;
-		cnt = s->dma_adc.dmasize-swptr;
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-
-		if (cnt > count)
-			cnt = count;
-
-		if ( cnt > 0 ) cnt &= ~3;
-
-		if (cnt <= 0) {
-			start_adc(s);
-			if (file->f_flags & O_NONBLOCK) 
-			{
-				ret = ret ? ret : -EAGAIN;
-				goto rec_return_free;
-			}
-			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
-				if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-				       s->dma_adc.hwptr, s->dma_adc.swptr);
-				stop_adc(s);
-				spin_lock_irqsave(&s->lock, flags);
-				set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-				/* program enhanced mode registers */
-				/* FILL ME */
-/*				wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
-				wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); */
-				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (signal_pending(current)) 
-			{
-				ret = ret ? ret : -ERESTARTSYS;
-				goto rec_return_free;
-			}
-			continue;
-		}
-	
-		if(s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-			/* swptr/2 so that we know the real offset in each apu's buffer */
-			comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize);
-			if (copy_to_user(buffer, combbuf, cnt)) {
-				ret = ret ? ret : -EFAULT;
-				goto rec_return_free;
-			}
-		} else  {
-			if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-				ret = ret ? ret : -EFAULT;
-				goto rec_return_free;
-			}
-		}
-
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		start_adc(s);
-	}
-
-rec_return_free:
-	kfree(combbuf);
-	return ret;
-}
-
-static ssize_t 
-ess_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct ess_state *s = (struct ess_state *)file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-	
-	VALIDATE_STATE(s);
-	if (s->dma_dac.mapped)
-		return -ENXIO;
-	if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-
-	calc_bob_rate(s);
-
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-
-		if (s->dma_dac.count < 0) {
-			s->dma_dac.count = 0;
-			s->dma_dac.swptr = s->dma_dac.hwptr;
-		}
-		swptr = s->dma_dac.swptr;
-
-		cnt = s->dma_dac.dmasize-swptr;
-
-		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-			cnt = s->dma_dac.dmasize - s->dma_dac.count;
-
-		spin_unlock_irqrestore(&s->lock, flags);
-
-		if (cnt > count)
-			cnt = count;
-
-		if (cnt <= 0) {
-			start_dac(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if(!ret) ret = -EAGAIN;
-				goto return_free;
-			}
-			if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
-				if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-				       s->dma_dac.hwptr, s->dma_dac.swptr);
-				stop_dac(s);
-				spin_lock_irqsave(&s->lock, flags);
-				set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-				/* program enhanced mode registers */
-/*				wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
-				wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1); */
-				/* FILL ME */
-				s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (signal_pending(current)) {
-				if (!ret) ret = -ERESTARTSYS;
-				goto return_free;
-			}
-			continue;
-		}
-		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-			if (!ret) ret = -EFAULT;
-			goto return_free;
-		}
-/*		printk("wrote %d bytes at sw: %d cnt: %d while hw: %d\n",cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);*/
-
-		swptr = (swptr + cnt) % s->dma_dac.dmasize;
-
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac.swptr = swptr;
-		s->dma_dac.count += cnt;
-		s->dma_dac.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		start_dac(s);
-	}
-return_free:
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int ess_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct ess_state *s = (struct ess_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-
-/* In 0.14 prog_dmabuf always returns success anyway ... */
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready && prog_dmabuf(s, 0)) 
-			return 0;
-	}
-	if (file->f_mode & FMODE_READ) {
-	  	if (!s->dma_adc.ready && prog_dmabuf(s, 1))
-			return 0;
-	}
-
-	if (file->f_mode & FMODE_WRITE)
-		poll_wait(file, &s->dma_dac.wait, wait);
-	if (file->f_mode & FMODE_READ)
-		poll_wait(file, &s->dma_adc.wait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	ess_update_ptr(s);
-	if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int ess_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct ess_state *s = (struct ess_state *)file->private_data;
-	struct dmabuf *db;
-	int ret = -EINVAL;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf(s, 1)) != 0)
-			goto out;
-		db = &s->dma_dac;
-	} else 
-#if 0
-	/* if we can have the wp/wc do the combining
-		we can turn this back on.  */
-	      if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf(s, 0)) != 0)
-			goto out;
-		db = &s->dma_adc;
-	} else  
-#endif
-		goto out;
-	ret = -EINVAL;
-	if (vma->vm_pgoff != 0)
-		goto out;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder))
-		goto out;
-	ret = -EAGAIN;
-	if (remap_pfn_range(vma, vma->vm_start,
-			virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-			size, vma->vm_page_prot))
-		goto out;
-	db->mapped = 1;
-	ret = 0;
-out:
-	unlock_kernel();
-	return ret;
-}
-
-static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct ess_state *s = (struct ess_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int val, mapped, ret;
-	unsigned char fmtm, fmtd;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-/*	printk("maestro: ess_ioctl: cmd %d\n", cmd);*/
-	
-	VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s, file->f_flags & O_NONBLOCK);
-		return 0;
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		/* XXX fix */
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq(s->card->pcidev->irq);
-			s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->card->pcidev->irq);
-			s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				set_adc_rate(s, val);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				set_dac_rate(s, val);
-			}
-		}
-		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-		
-        case SNDCTL_DSP_STEREO:
-		if (get_user(val, p))
-			return -EFAULT;
-		fmtd = 0;
-		fmtm = ~0;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ready = 0;
-			if (val)
-				fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-			else
-				fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.ready = 0;
-			if (val)
-				fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-			else
-				fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-		}
-		set_fmt(s, fmtm, fmtd);
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			fmtd = 0;
-			fmtm = ~0;
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val >= 2)
-					fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-				else
-					fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val >= 2)
-					fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-				else
-					fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-			}
-			set_fmt(s, fmtm, fmtd);
-		}
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-					   : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-		
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_U8|AFMT_S16_LE, p);
-		
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			fmtd = 0;
-			fmtm = ~0;
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-	/* fixed at 16bit for now */
-				fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-#if 0
-				if (val == AFMT_S16_LE)
-					fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-				else
-					fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);
-#endif
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val == AFMT_S16_LE)
-					fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-				else
-					fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);
-			}
-			set_fmt(s, fmtm, fmtd);
-		}
- 		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
-			(ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-			: (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
-				AFMT_S16_LE : 
-				AFMT_U8, 
-			p);
-		
-	case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING))
-			val |= PCM_ENABLE_INPUT;
-		if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, p);
-		
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-					return ret;
-				start_adc(s);
-			} else
-				stop_adc(s);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-					return ret;
-				start_dac(s);
-			} else
-				stop_dac(s);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-			return ret;
-		spin_lock_irqsave(&s->lock, flags);
-		ess_update_ptr(s);
-		abinfo.fragsize = s->dma_dac.fragsize;
-                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-			return ret;
-		spin_lock_irqsave(&s->lock, flags);
-		ess_update_ptr(s);
-		abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-		
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-			return ret;
-		spin_lock_irqsave(&s->lock, flags);
-		ess_update_ptr(s);
-                val = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return put_user(val, p);
-
-        case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-			return ret;
-		spin_lock_irqsave(&s->lock, flags);
-		ess_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-			return ret;
-		spin_lock_irqsave(&s->lock, flags);
-		ess_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-                cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= s->dma_dac.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf(s, 0)))
-				return val;
-			return put_user(s->dma_dac.fragsize, p);
-		}
-		if ((val = prog_dmabuf(s, 1)))
-			return val;
-		return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		M_printk("maestro: SETFRAGMENT: %0x\n",val);
-		if (file->f_mode & FMODE_READ) {
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			s->dma_dac.ossfragshift = val & 0xffff;
-			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac.ossfragshift < 4)
-				s->dma_dac.ossfragshift = 4;
-			if (s->dma_dac.ossfragshift > 15)
-				s->dma_dac.ossfragshift = 15;
-			if (s->dma_dac.ossmaxfrags < 4)
-				s->dma_dac.ossmaxfrags = 4;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE)
-			s->dma_dac.subdivision = val;
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-					   : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-					   : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-	return -EINVAL;
-}
-
-static void
-set_base_registers(struct ess_state *s,void *vaddr)
-{
-	unsigned long packed_phys = virt_to_bus(vaddr)>>12;
-	wave_set_register(s, 0x01FC , packed_phys);
-	wave_set_register(s, 0x01FD , packed_phys);
-	wave_set_register(s, 0x01FE , packed_phys);
-	wave_set_register(s, 0x01FF , packed_phys);
-}
-
-/* 
- * this guy makes sure we're in the right power
- * state for what we want to be doing 
- */
-static void maestro_power(struct ess_card *card, int tostate)
-{
-	u16 active_mask = acpi_state_mask[tostate];
-	u8 state;
-
-	if(!use_pm) return;
-
-	pci_read_config_byte(card->pcidev, card->power_regs+0x4, &state);
-	state&=3;
-
-	/* make sure we're in the right state */
-	if(state != tostate) {
-		M_printk(KERN_WARNING "maestro: dev %02x:%02x.%x switching from D%d to D%d\n",
-			card->pcidev->bus->number, 
-			PCI_SLOT(card->pcidev->devfn),
-			PCI_FUNC(card->pcidev->devfn),
-			state,tostate);
-		pci_write_config_byte(card->pcidev, card->power_regs+0x4, tostate);
-	}
-
-	/* and make sure the units we care about are on 
-		XXX we might want to do this before state flipping? */
-	pci_write_config_word(card->pcidev, 0x54, ~ active_mask);
-	pci_write_config_word(card->pcidev, 0x56, ~ active_mask);
-}
-
-/* we allocate a large power of two for all our memory.
-	this is cut up into (not to scale :):
-	|silly fifo word	| 512byte mixbuf per adc	| dac/adc * channels |
-*/
-static int
-allocate_buffers(struct ess_state *s)
-{
-	void *rawbuf=NULL;
-	int order,i;
-	struct page *page, *pend;
-
-	/* alloc as big a chunk as we can */
-	for (order = (dsps_order + (16-PAGE_SHIFT) + 1); order >= (dsps_order + 2 + 1); order--)
-		if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order)))
-			break;
-
-	if (!rawbuf)
-		return 1;
-
-	M_printk("maestro: allocated %ld (%d) bytes at %p\n",PAGE_SIZE<<order,order, rawbuf);
-
-	if ((virt_to_bus(rawbuf) + (PAGE_SIZE << order) - 1) & ~((1<<28)-1))  {
-		printk(KERN_ERR "maestro: DMA buffer beyond 256MB! busaddr 0x%lx  size %ld\n",
-			virt_to_bus(rawbuf), PAGE_SIZE << order);
-		kfree(rawbuf);
-		return 1;
-	}
-
-	s->card->dmapages = rawbuf;
-	s->card->dmaorder = order;
-
-	for(i=0;i<NR_DSPS;i++) {
-		struct ess_state *ess = &s->card->channels[i];
-
-		if(ess->dev_audio == -1)
-			continue;
-
-		ess->dma_dac.ready = s->dma_dac.mapped = 0;
-		ess->dma_adc.ready = s->dma_adc.mapped = 0;
-		ess->dma_adc.buforder = ess->dma_dac.buforder = order - 1 - dsps_order - 1;
-
-		/* offset dac and adc buffers starting half way through and then at each [da][ad]c's
-			order's intervals.. */
-		ess->dma_dac.rawbuf = rawbuf + (PAGE_SIZE<<(order-1)) + (i * ( PAGE_SIZE << (ess->dma_dac.buforder + 1 )));
-		ess->dma_adc.rawbuf = ess->dma_dac.rawbuf + ( PAGE_SIZE << ess->dma_dac.buforder);
-		/* offset mixbuf by a mixbuf so that the lame status fifo can
-			happily scribble away.. */ 
-		ess->mixbuf = rawbuf + (512 * (i+1));
-
-		M_printk("maestro: setup apu %d: dac: %p adc: %p mix: %p\n",i,ess->dma_dac.rawbuf,
-			ess->dma_adc.rawbuf, ess->mixbuf);
-
-	}
-
-	/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-	pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-	for (page = virt_to_page(rawbuf); page <= pend; page++)
-		SetPageReserved(page);
-
-	return 0;
-} 
-static void
-free_buffers(struct ess_state *s)
-{
-	struct page *page, *pend;
-
-	s->dma_dac.rawbuf = s->dma_adc.rawbuf = NULL;
-	s->dma_dac.mapped = s->dma_adc.mapped = 0;
-	s->dma_dac.ready = s->dma_adc.ready = 0;
-
-	M_printk("maestro: freeing %p\n",s->card->dmapages);
-	/* undo marking the pages as reserved */
-
-	pend = virt_to_page(s->card->dmapages + (PAGE_SIZE << s->card->dmaorder) - 1);
-	for (page = virt_to_page(s->card->dmapages); page <= pend; page++)
-		ClearPageReserved(page);
-
-	free_pages((unsigned long)s->card->dmapages,s->card->dmaorder);
-	s->card->dmapages = NULL;
-}
-
-static int 
-ess_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	struct ess_state *s = NULL;
-	unsigned char fmtm = ~0, fmts = 0;
-	struct pci_dev *pdev = NULL;
-	/*
-	 *	Scan the cards and find the channel. We only
-	 *	do this at open time so it is ok
-	 */
-
-	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-		struct ess_card *c;
-		struct pci_driver *drvr;
-
-		drvr = pci_dev_driver (pdev);
-		if (drvr == &maestro_pci_driver) {
-			int i;
-			struct ess_state *sp;
-
-			c = (struct ess_card*)pci_get_drvdata (pdev);
-			if (!c)
-				continue;
-			for(i=0;i<NR_DSPS;i++)
-			{
-				sp=&c->channels[i];
-				if(sp->dev_audio < 0)
-					continue;
-				if((sp->dev_audio ^ minor) & ~0xf)
-					continue;
-				s=sp;
-			}
-		}
-	}
-	if (!s)
-		return -ENODEV;
-
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & file->f_mode) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EWOULDBLOCK;
-		}
-		mutex_unlock(&s->open_mutex);
-		interruptible_sleep_on(&s->open_wait);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-
-	/* under semaphore.. */
-	if ((s->card->dmapages==NULL) && allocate_buffers(s)) {
-		mutex_unlock(&s->open_mutex);
-		return -ENOMEM;
-	}
-
-	/* we're covered by the open_mutex */
-	if( ! s->card->dsps_open )  {
-		maestro_power(s->card,ACPI_D0);
-		start_bob(s);
-	}
-	s->card->dsps_open++;
-	M_printk("maestro: open, %d bobs now\n",s->card->dsps_open);
-
-	/* ok, lets write WC base regs now that we've 
-		powered up the chip */
-	M_printk("maestro: writing 0x%lx (bus 0x%lx) to the wp\n",virt_to_bus(s->card->dmapages),
-		((virt_to_bus(s->card->dmapages))&0xFFE00000)>>12);
-	set_base_registers(s,s->card->dmapages);
-
-	if (file->f_mode & FMODE_READ) {
-/*
-		fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; */
-
-		fmtm &= ~((ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-		fmts = (ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT;
-
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-		set_adc_rate(s, 8000);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-
-		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-		set_dac_rate(s, 8000);
-	}
-	set_fmt(s, fmtm, fmts);
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int 
-ess_release(struct inode *inode, struct file *file)
-{
-	struct ess_state *s = (struct ess_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-	}
-		
-	s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-	/* we're covered by the open_mutex */
-	M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1);
-	if( --s->card->dsps_open <= 0) {
-		s->card->dsps_open = 0;
-		stop_bob(s);
-		free_buffers(s);
-		maestro_power(s->card,ACPI_D2);
-	}
-	mutex_unlock(&s->open_mutex);
-	wake_up(&s->open_wait);
-	unlock_kernel();
-	return 0;
-}
-
-static struct file_operations ess_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= ess_read,
-	.write		= ess_write,
-	.poll		= ess_poll,
-	.ioctl		= ess_ioctl,
-	.mmap		= ess_mmap,
-	.open		= ess_open,
-	.release	= ess_release,
-};
-
-static int
-maestro_config(struct ess_card *card) 
-{
-	struct pci_dev *pcidev = card->pcidev;
-	struct ess_state *ess = &card->channels[0];
-	int apu,iobase  = card->iobase;
-	u16 w;
-	u32 n;
-
-	/* We used to muck around with pci config space that
-	 * we had no business messing with.  We don't know enough
-	 * about the machine to know which DMA mode is appropriate, 
-	 * etc.  We were guessing wrong on some machines and making
-	 * them unhappy.  We now trust in the BIOS to do things right,
-	 * which almost certainly means a new host of problems will
-	 * arise with broken BIOS implementations.  screw 'em. 
-	 * We're already intolerant of machines that don't assign
-	 * IRQs.
-	 */
-	
-	/* do config work at full power */
-	maestro_power(card,ACPI_D0);
-	 
-	pci_read_config_word(pcidev, 0x50, &w);
-
-	w&=~(1<<5);			/* Don't swap left/right (undoc)*/
-	
-	pci_write_config_word(pcidev, 0x50, w);
-	
-	pci_read_config_word(pcidev, 0x52, &w);
-	w&=~(1<<15);		/* Turn off internal clock multiplier */
-	/* XXX how do we know which to use? */
-	w&=~(1<<14);		/* External clock */
-	
-	w|= (1<<7);		/* Hardware volume control on */
-	w|= (1<<6);		/* Debounce off: easier to push the HWV buttons. */
-	w&=~(1<<5);		/* GPIO 4:5 */
-	w|= (1<<4);             /* Disconnect from the CHI.  Enabling this made a dell 7500 work. */
-	w&=~(1<<2);		/* MIDI fix off (undoc) */
-	w&=~(1<<1);		/* reserved, always write 0 */
-	pci_write_config_word(pcidev, 0x52, w);
-	
-	/*
-	 *	Legacy mode
-	 */
-
-	pci_read_config_word(pcidev, 0x40, &w);
-	w|=(1<<15);	/* legacy decode off */
-	w&=~(1<<14);	/* Disable SIRQ */
-	w&=~(0x1f);	/* disable mpu irq/io, game port, fm, SB */
-	 
-	pci_write_config_word(pcidev, 0x40, w);
-
-	/* Set up 978 docking control chip. */
-	pci_read_config_word(pcidev, 0x58, &w);
-	w|=1<<2;	/* Enable 978. */
-	w|=1<<3;	/* Turn on 978 hardware volume control. */
-	w&=~(1<<11);	/* Turn on 978 mixer volume control. */
-	pci_write_config_word(pcidev, 0x58, w);
-	
-	sound_reset(iobase);
-
-	/*
-	 *	Ring Bus Setup
-	 */
-
-	/* setup usual 0x34 stuff.. 0x36 may be chip specific */
-        outw(0xC090, iobase+0x34); /* direct sound, stereo */
-        udelay(20);
-        outw(0x3000, iobase+0x36); /* direct sound, stereo */
-        udelay(20);
-
-
-	/*
-	 *	Reset the CODEC
-	 */
-	 
-	maestro_ac97_reset(iobase,pcidev);
-	
-	/*
-	 *	Ring Bus Setup
-	 */
-	 	 
-	n=inl(iobase+0x34);
-	n&=~0xF000;
-	n|=12<<12;		/* Direct Sound, Stereo */
-	outl(n, iobase+0x34);
-
-	n=inl(iobase+0x34);
-	n&=~0x0F00;		/* Modem off */
-	outl(n, iobase+0x34);
-
-	n=inl(iobase+0x34);
-	n&=~0x00F0;
-	n|=9<<4;		/* DAC, Stereo */
-	outl(n, iobase+0x34);
-	
-	n=inl(iobase+0x34);
-	n&=~0x000F;		/* ASSP off */
-	outl(n, iobase+0x34);
-	
-	n=inl(iobase+0x34);
-	n|=(1<<29);		/* Enable ring bus */
-	outl(n, iobase+0x34);
-	
-	n=inl(iobase+0x34);
-	n|=(1<<28);		/* Enable serial bus */
-	outl(n, iobase+0x34);
-	
-	n=inl(iobase+0x34);
-	n&=~0x00F00000;		/* MIC off */
-	outl(n, iobase+0x34);
-	
-	n=inl(iobase+0x34);
-	n&=~0x000F0000;		/* I2S off */
-	outl(n, iobase+0x34);
-	
-
-	w=inw(iobase+0x18);
-	w&=~(1<<7);		/* ClkRun off */
-	outw(w, iobase+0x18);
-
-	w=inw(iobase+0x18);
-	w&=~(1<<6);		/* Hardware volume control interrupt off... for now. */
-	outw(w, iobase+0x18);
-	
-	w=inw(iobase+0x18);
-	w&=~(1<<4);		/* ASSP irq off */
-	outw(w, iobase+0x18);
-	
-	w=inw(iobase+0x18);
-	w&=~(1<<3);		/* ISDN irq off */
-	outw(w, iobase+0x18);
-	
-	w=inw(iobase+0x18);
-	w|=(1<<2);		/* Direct Sound IRQ on */
-	outw(w, iobase+0x18);
-
-	w=inw(iobase+0x18);
-	w&=~(1<<1);		/* MPU401 IRQ off */
-	outw(w, iobase+0x18);
-
-	w=inw(iobase+0x18);
-	w|=(1<<0);		/* SB IRQ on */
-	outw(w, iobase+0x18);
-
-	/* Set hardware volume control registers to midpoints.
-	   We can tell which button was pushed based on how they change. */
-	outb(0x88, iobase+0x1c);
-	outb(0x88, iobase+0x1d);
-	outb(0x88, iobase+0x1e);
-	outb(0x88, iobase+0x1f);
-
-	/* it appears some maestros (dell 7500) only work if these are set,
-		regardless of whether we use the assp or not. */
-
-	outb(0, iobase+0xA4); 
-	outb(3, iobase+0xA2); 
-	outb(0, iobase+0xA6);
-	
-	for(apu=0;apu<16;apu++)
-	{
-		/* Write 0 into the buffer area 0x1E0->1EF */
-		outw(0x01E0+apu, 0x10+iobase);
-		outw(0x0000, 0x12+iobase);
-	
-		/*
-		 * The 1.10 test program seem to write 0 into the buffer area
-		 * 0x1D0-0x1DF too.
-		 */
-		outw(0x01D0+apu, 0x10+iobase);
-		outw(0x0000, 0x12+iobase);
-	}
-
-#if 1
-	wave_set_register(ess, IDR7_WAVE_ROMRAM, 
-		(wave_get_register(ess, IDR7_WAVE_ROMRAM)&0xFF00));
-	wave_set_register(ess, IDR7_WAVE_ROMRAM,
-		wave_get_register(ess, IDR7_WAVE_ROMRAM)|0x100);
-	wave_set_register(ess, IDR7_WAVE_ROMRAM,
-		wave_get_register(ess, IDR7_WAVE_ROMRAM)&~0x200);
-	wave_set_register(ess, IDR7_WAVE_ROMRAM,
-		wave_get_register(ess, IDR7_WAVE_ROMRAM)|~0x400);
-#else		
-	maestro_write(ess, IDR7_WAVE_ROMRAM, 
-		(maestro_read(ess, IDR7_WAVE_ROMRAM)&0xFF00));
-	maestro_write(ess, IDR7_WAVE_ROMRAM,
-		maestro_read(ess, IDR7_WAVE_ROMRAM)|0x100);
-	maestro_write(ess, IDR7_WAVE_ROMRAM,
-		maestro_read(ess, IDR7_WAVE_ROMRAM)&~0x200);
-	maestro_write(ess, IDR7_WAVE_ROMRAM,
-		maestro_read(ess, IDR7_WAVE_ROMRAM)|0x400);
-#endif
-	
-	maestro_write(ess, IDR2_CRAM_DATA, 0x0000);
-	maestro_write(ess, 0x08, 0xB004);
-	/* Now back to the DirectSound stuff */
-	maestro_write(ess, 0x09, 0x001B);
-	maestro_write(ess, 0x0A, 0x8000);
-	maestro_write(ess, 0x0B, 0x3F37);
-	maestro_write(ess, 0x0C, 0x0098);
-	
-	/* parallel out ?? */
-	maestro_write(ess, 0x0C, 
-		(maestro_read(ess, 0x0C)&~0xF000)|0x8000); 
-	/* parallel in, has something to do with recording :) */
-	maestro_write(ess, 0x0C, 
-		(maestro_read(ess, 0x0C)&~0x0F00)|0x0500);
-
-	maestro_write(ess, 0x0D, 0x7632);
-			
-	/* Wave cache control on - test off, sg off, 
-		enable, enable extra chans 1Mb */
-
-	outw(inw(0x14+iobase)|(1<<8),0x14+iobase);
-	outw(inw(0x14+iobase)&0xFE03,0x14+iobase);
-	outw((inw(0x14+iobase)&0xFFFC), 0x14+iobase);
-	outw(inw(0x14+iobase)|(1<<7),0x14+iobase);
-
-	outw(0xA1A0, 0x14+iobase);      /* 0300 ? */
-
-	/* Now clear the APU control ram */	
-	for(apu=0;apu<NR_APUS;apu++)
-	{
-		for(w=0;w<NR_APU_REGS;w++)
-			apu_set_register(ess, apu|ESS_CHAN_HARD, w, 0);
-		
-	}
-
-	return 0;
-	
-}
-
-/* this guy tries to find the pci power management
- * register bank.  this should really be in core
- * code somewhere.  1 on success. */
-static int
-parse_power(struct ess_card *card, struct pci_dev *pcidev)
-{
-	u32 n;
-	u16 w;
-	u8 next;
-	int max = 64;  /* an a 8bit guy pointing to 32bit guys
-				can only express so much. */
-
-	card->power_regs = 0;
-
-	/* check to see if we have a capabilities list in
-		the config register */
-	pci_read_config_word(pcidev, PCI_STATUS, &w);
-	if(!(w & PCI_STATUS_CAP_LIST)) return 0;
-
-	/* walk the list, starting at the head. */
-	pci_read_config_byte(pcidev,PCI_CAPABILITY_LIST,&next);
-
-	while(next && max--) {
-		pci_read_config_dword(pcidev, next & ~3, &n);
-		if((n & 0xff) == PCI_CAP_ID_PM) {
-			card->power_regs = next;
-			break;
-		}
-		next = ((n>>8) & 0xff);
-	}
-
-	return card->power_regs ? 1 : 0;
-}
-
-static int __init
-maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
-{
-	int card_type = pdid->driver_data;
-	u32 n;
-	int iobase;
-	int i, ret;
-	struct ess_card *card;
-	struct ess_state *ess;
-	int num = 0;
-
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
-	static int printed_version;
-	if (!printed_version++)
-		printk(version);
-#endif
-
-	/* don't pick up weird modem maestros */
-	if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
-		return -ENODEV;
-
-
-	if ((ret=pci_enable_device(pcidev)))
-		return ret;
-			
-	iobase = pci_resource_start(pcidev,0);
-	if (!iobase || !(pci_resource_flags(pcidev, 0 ) & IORESOURCE_IO))
-		return -ENODEV;
-
-	if(pcidev->irq == 0)
-		return -ENODEV;
-
-	/* stake our claim on the iospace */
-	if( request_region(iobase, 256, card_names[card_type]) == NULL )
-	{
-		printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase);
-		return -EBUSY;
-	}
-
-	/* just to be sure */
-	pci_set_master(pcidev);
-
-	card = kmalloc(sizeof(struct ess_card), GFP_KERNEL);
-	if(card == NULL)
-	{
-		printk(KERN_WARNING "maestro: out of memory\n");
-		release_region(iobase, 256);
-		return -ENOMEM;
-	}
-	
-	memset(card, 0, sizeof(*card));
-	card->pcidev = pcidev;
-
-	card->iobase = iobase;
-	card->card_type = card_type;
-	card->irq = pcidev->irq;
-	card->magic = ESS_CARD_MAGIC;
-	spin_lock_init(&card->lock);
-	init_waitqueue_head(&card->suspend_queue);
-
-	card->dock_mute_vol = 50;
-	
-	/* init our groups of 6 apus */
-	for(i=0;i<NR_DSPS;i++)
-	{
-		struct ess_state *s=&card->channels[i];
-
-		s->index = i;
-
-		s->card = card;
-		init_waitqueue_head(&s->dma_adc.wait);
-		init_waitqueue_head(&s->dma_dac.wait);
-		init_waitqueue_head(&s->open_wait);
-		spin_lock_init(&s->lock);
-		mutex_init(&s->open_mutex);
-		s->magic = ESS_STATE_MAGIC;
-		
-		s->apu[0] = 6*i;
-		s->apu[1] = (6*i)+1;
-		s->apu[2] = (6*i)+2;
-		s->apu[3] = (6*i)+3;
-		s->apu[4] = (6*i)+4;
-		s->apu[5] = (6*i)+5;
-		
-		if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-			printk("maestro: BOTCH!\n");
-		/* register devices */
-		if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0)
-			break;
-	}
-	
-	num = i;
-	
-	/* clear the rest if we ran out of slots to register */
-	for(;i<NR_DSPS;i++)
-	{
-		struct ess_state *s=&card->channels[i];
-		s->dev_audio = -1;
-	}
-	
-	ess = &card->channels[0];
-
-	/*
-	 *	Ok card ready. Begin setup proper
-	 */
-
-	printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", 
-		card_names[card_type],iobase,card->irq);
-	pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n);
-	printk(KERN_INFO "maestro:  subvendor id: 0x%08x\n",n); 
-
-	/* turn off power management unless:
-	 *	- the user explicitly asks for it
-	 * 		or
-	 *		- we're not a 2e, lesser chipps seem to have problems.
-	 *		- we're not on our _very_ small whitelist.  some implemenetations
-	 *			really don't like the pm code, others require it.
-	 *			feel free to expand this as required.
-	 */
-#define SUBSYSTEM_VENDOR(x) (x&0xffff)
-	if(	(use_pm != 1) && 
-		((card_type != TYPE_MAESTRO2E)	|| (SUBSYSTEM_VENDOR(n) != 0x1028)))
-			use_pm = 0;
-
-	if(!use_pm) 
-		printk(KERN_INFO "maestro: not attempting power management.\n");
-	else {
-		if(!parse_power(card,pcidev)) 
-			printk(KERN_INFO "maestro: no PCI power management interface found.\n");
-		else {
-			pci_read_config_dword(pcidev, card->power_regs, &n);
-			printk(KERN_INFO "maestro: PCI power management capability: 0x%x\n",n>>16);
-		}	
-	}
-
-	maestro_config(card);
-
-	if(maestro_ac97_get(card, 0x00)==0x0080) {
-		printk(KERN_ERR "maestro: my goodness!  you seem to have a pt101 codec, which is quite rare.\n"
-				"\tyou should tell someone about this.\n");
-	} else {
-		maestro_ac97_init(card);
-	}
-
-	if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) {
-		printk("maestro: couldn't register mixer!\n");
-	} else {
-		memcpy(card->mix.mixer_state,mixer_defaults,sizeof(card->mix.mixer_state));
-		mixer_push_state(card);
-	}
-	
-	if((ret=request_irq(card->irq, ess_interrupt, IRQF_SHARED, card_names[card_type], card)))
-	{
-		printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq);
-		unregister_sound_mixer(card->dev_mixer);
-		for(i=0;i<NR_DSPS;i++)
-		{
-			struct ess_state *s = &card->channels[i];
-			if(s->dev_audio != -1)
-				unregister_sound_dsp(s->dev_audio);
-		}
-		release_region(card->iobase, 256);		
-		unregister_reboot_notifier(&maestro_nb);
-		kfree(card);
-		return ret;
-	}
-
-	/* Turn on hardware volume control interrupt.
-	   This has to come after we grab the IRQ above,
-	   or a crash will result on installation if a button has been pressed,
-	   because in that case we'll get an immediate interrupt. */
-	n = inw(iobase+0x18);
-	n|=(1<<6);
-	outw(n, iobase+0x18);
-
-	pci_set_drvdata(pcidev,card);
-	/* now go to sleep 'till something interesting happens */
-	maestro_power(card,ACPI_D2);
-
-	printk(KERN_INFO "maestro: %d channels configured.\n", num);
-	return 0;
-}
-
-static void maestro_remove(struct pci_dev *pcidev) {
-	struct ess_card *card = pci_get_drvdata(pcidev);
-	int i;
-	u32 n;
-	
-	/* XXX maybe should force stop bob, but should be all 
-		stopped by _release by now */
-
-	/* Turn off hardware volume control interrupt.
-	   This has to come before we leave the IRQ below,
-	   or a crash results if a button is pressed ! */
-	n = inw(card->iobase+0x18);
-	n&=~(1<<6);
-	outw(n, card->iobase+0x18);
-
-	free_irq(card->irq, card);
-	unregister_sound_mixer(card->dev_mixer);
-	for(i=0;i<NR_DSPS;i++)
-	{
-		struct ess_state *ess = &card->channels[i];
-		if(ess->dev_audio != -1)
-			unregister_sound_dsp(ess->dev_audio);
-	}
-	/* Goodbye, Mr. Bond. */
-	maestro_power(card,ACPI_D3);
- 	release_region(card->iobase, 256);
-	kfree(card);
-	pci_set_drvdata(pcidev,NULL);
-}
-
-static struct pci_device_id maestro_pci_tbl[] = {
-	{PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2},
-	{PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2E},
-	{PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO},
-	{0,}
-};
-MODULE_DEVICE_TABLE(pci, maestro_pci_tbl);
-
-static struct pci_driver maestro_pci_driver = {
-	.name	  = "maestro",
-	.id_table = maestro_pci_tbl,
-	.probe	  = maestro_probe,
-	.remove	  = maestro_remove,
-};
-
-static int __init init_maestro(void)
-{
-	int rc;
-
-	rc = pci_register_driver(&maestro_pci_driver);
-	if (rc < 0)
-		return rc;
-
-	if (register_reboot_notifier(&maestro_nb))
-		printk(KERN_WARNING "maestro: reboot notifier registration failed; may not reboot properly.\n");
-#ifdef MODULE
-	printk(version);
-#endif
-	if (dsps_order < 0)   {
-		dsps_order = 1;
-		printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
-	}
-	else if (dsps_order > MAX_DSP_ORDER)  {
-		dsps_order = MAX_DSP_ORDER;
-		printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
-	}
-	return 0;
-}
-
-static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf)
-{
-	/* this notifier is called when the kernel is really shut down. */
-	M_printk("maestro: shutting down\n");
-	/* this will remove all card instances too */
-	pci_unregister_driver(&maestro_pci_driver);
-	/* XXX dunno about power management */
-	return NOTIFY_OK;
-}
-
-/* --------------------------------------------------------------------- */
-
-
-static void cleanup_maestro(void) {
-	M_printk("maestro: unloading\n");
-	pci_unregister_driver(&maestro_pci_driver);
-	unregister_reboot_notifier(&maestro_nb);
-}
-
-/* --------------------------------------------------------------------- */
-
-void
-check_suspend(struct ess_card *card)
-{
-	DECLARE_WAITQUEUE(wait, current);
-
-	if(!card->in_suspend) return;
-
-	card->in_suspend++;
-	add_wait_queue(&(card->suspend_queue), &wait);
-	current->state = TASK_UNINTERRUPTIBLE;
-	schedule();
-	remove_wait_queue(&(card->suspend_queue), &wait);
-	current->state = TASK_RUNNING;
-}
-
-module_init(init_maestro);
-module_exit(cleanup_maestro);
diff --git a/sound/oss/maestro.h b/sound/oss/maestro.h
deleted file mode 100644
index 023ec7f..0000000
--- a/sound/oss/maestro.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *	Registers for the ESS PCI cards
- */
- 
-/*
- *	Memory access
- */
- 
-#define ESS_MEM_DATA		0x00
-#define	ESS_MEM_INDEX		0x02
-
-/*
- *	AC-97 Codec port. Delay 1uS after each write. This is used to
- *	talk AC-97 (see intel.com). Write data then register.
- */
- 
-#define ESS_AC97_INDEX		0x30		/* byte wide */
-#define ESS_AC97_DATA		0x32
-
-/* 
- *	Reading is a bit different. You write register|0x80 to ubdex
- *	delay 1uS poll the low bit of index, when it clears read the
- *	data value.
- */
-
-/*
- *	Control port. Not yet fully understood
- *	The value 0xC090 gets loaded to it then 0x0000 and 0x2800
- *	to the data port. Then after 4uS the value 0x300 is written
- */
- 
-#define RING_BUS_CTRL_L		0x34
-#define RING_BUS_CTRL_H		0x36
-
-/*
- *	This is also used during setup. The value 0x17 is written to it
- */
- 
-#define ESS_SETUP_18		0x18
-
-/*
- *	And this one gets 0x000b
- */
- 
-#define ESS_SETUP_A2		0xA2
-
-/*
- *	And this 0x0000
- */
- 
-#define ESS_SETUP_A4		0xA4
-#define ESS_SETUP_A6		0xA6
-
-/*
- *	Stuff to do with Harpo - the wave stuff
- */
- 
-#define ESS_WAVETABLE_SIZE	0x14
-#define 	ESS_WAVETABLE_2M	0xA180
-
diff --git a/sound/oss/maestro3.c b/sound/oss/maestro3.c
deleted file mode 100644
index 5548e3c..0000000
--- a/sound/oss/maestro3.c
+++ /dev/null
@@ -1,2969 +0,0 @@
-/*****************************************************************************
- *
- *      ESS Maestro3/Allegro driver for Linux 2.4.x
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *    (c) Copyright 2000 Zach Brown <zab@zabbo.net>
- *
- * I need to thank many people for helping make this driver happen.  
- * As always, Eric Brombaugh was a hacking machine and killed many bugs
- * that I was too dumb to notice.  Howard Kim at ESS provided reference boards 
- * and as much docs as he could.  Todd and Mick at Dell tested snapshots on 
- * an army of laptops.  msw and deviant at Red Hat also humoured me by hanging
- * their laptops every few hours in the name of science.
- * 
- * Shouts go out to Mike "DJ XPCom" Ang.
- *
- * History
- *  v1.23 - Jun 5 2002 - Michael Olson <olson@cs.odu.edu>
- *   added a module option to allow selection of GPIO pin number 
- *   for external amp 
- *  v1.22 - Feb 28 2001 - Zach Brown <zab@zabbo.net>
- *   allocate mem at insmod/setup, rather than open
- *   limit pci dma addresses to 28bit, thanks guys.
- *  v1.21 - Feb 04 2001 - Zach Brown <zab@zabbo.net>
- *   fix up really dumb notifier -> suspend oops
- *  v1.20 - Jan 30 2001 - Zach Brown <zab@zabbo.net>
- *   get rid of pm callback and use pci_dev suspend/resume instead
- *   m3_probe cleanups, including pm oops think-o
- *  v1.10 - Jan 6 2001 - Zach Brown <zab@zabbo.net>
- *   revert to lame remap_page_range mmap() just to make it work
- *   record mmap fixed.
- *   fix up incredibly broken open/release resource management
- *   duh.  fix record format setting.
- *   add SMP locking and cleanup formatting here and there
- *  v1.00 - Dec 16 2000 - Zach Brown <zab@zabbo.net>
- *   port to sexy 2.4 interfaces
- *   properly align instance allocations so recording works
- *   clean up function namespace a little :/
- *   update PCI IDs based on mail from ESS
- *   arbitrarily bump version number to show its 2.4 now, 
- *      2.2 will stay 0., oss_audio port gets 2.
- *  v0.03 - Nov 05 2000 - Zach Brown <zab@zabbo.net>
- *   disable recording but allow dsp to be opened read 
- *   pull out most silly compat defines
- *  v0.02 - Nov 04 2000 - Zach Brown <zab@zabbo.net>
- *   changed clocking setup for m3, slowdown fixed.
- *   codec reset is hopefully reliable now
- *   rudimentary apm/power management makes suspend/resume work
- *  v0.01 - Oct 31 2000 - Zach Brown <zab@zabbo.net>
- *   first release
- *  v0.00 - Sep 09 2000 - Zach Brown <zab@zabbo.net>
- *   first pass derivation from maestro.c
- *
- * TODO
- *  in/out allocated contiguously so fullduplex mmap will work?
- *  no beep on init (mute)
- *  resetup msrc data memory if freq changes?
- *
- *  --
- *
- *  Allow me to ramble a bit about the m3 architecture.  The core of the
- *  chip is the 'assp', the custom ESS dsp that runs the show.  It has
- *  a small amount of code and data ram.  ESS drops binary dsp code images
- *  on our heads, but we don't get to see specs on the dsp.  
- *
- *  The constant piece of code on the dsp is the 'kernel'.  It also has a 
- *  chunk of the dsp memory that is statically set aside for its control
- *  info.  This is the KDATA defines in maestro3.h.  Part of its core
- *  data is a list of code addresses that point to the pieces of DSP code
- *  that it should walk through in its loop.  These other pieces of code
- *  do the real work.  The kernel presumably jumps into each of them in turn.
- *  These code images tend to have their own data area, and one can have
- *  multiple data areas representing different states for each of the 'client
- *  instance' code portions.  There is generally a list in the kernel data
- *  that points to the data instances for a given piece of code.
- *
- *  We've only been given the binary image for the 'minisrc', mini sample 
- *  rate converter.  This is rather annoying because it limits the work
- *  we can do on the dsp, but it also greatly simplifies the job of managing
- *  dsp data memory for the code and data for our playing streams :).  We
- *  statically allocate the minisrc code into a region we 'know' to be free
- *  based on the map of the binary kernel image we're loading.  We also 
- *  statically allocate the data areas for the maximum number of pcm streams
- *  we can be dealing with.  This max is set by the length of the static list
- *  in the kernel data that records the number of minisrc data regions we
- *  can have.  Thats right, all software dsp mixing with static code list
- *  limits.  Rock.
- *
- *  How sound goes in and out is still a relative mystery.  It appears
- *  that the dsp has the ability to get input and output through various
- *  'connections'.  To do IO from or to a connection, you put the address
- *  of the minisrc client area in the static kernel data lists for that 
- *  input or output.  so for pcm -> dsp -> mixer, we put the minisrc data
- *  instance in the DMA list and also in the list for the mixer.  I guess
- *  it Just Knows which is in/out, and we give some dma control info that
- *  helps.  There are all sorts of cool inputs/outputs that it seems we can't
- *  use without dsp code images that know how to use them.
- *
- *  So at init time we preload all the memory allocation stuff and set some
- *  system wide parameters.  When we really get a sound to play we build
- *  up its minisrc header (stream parameters, buffer addresses, input/output
- *  settings).  Then we throw its header on the various lists.  We also
- *  tickle some KDATA settings that ask the assp to raise clock interrupts
- *  and do some amount of software mixing before handing data to the ac97.
- *
- *  Sorry for the vague details.  Feel free to ask Eric or myself if you
- *  happen to be trying to use this driver elsewhere.  Please accept my
- *  apologies for the quality of the OSS support code, its passed through
- *  too many hands now and desperately wants to be rethought.
- */
-
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/reboot.h>
-#include <linux/spinlock.h>
-#include <linux/ac97_codec.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#include "maestro3.h"
-
-#define M_DEBUG 1
-
-#define DRIVER_VERSION      "1.23"
-#define M3_MODULE_NAME      "maestro3"
-#define PFX                 M3_MODULE_NAME ": "
-
-#define M3_STATE_MAGIC      0x734d724d
-#define M3_CARD_MAGIC       0x646e6f50
-
-#define ESS_FMT_STEREO      0x01
-#define ESS_FMT_16BIT       0x02
-#define ESS_FMT_MASK        0x03
-#define ESS_DAC_SHIFT       0   
-#define ESS_ADC_SHIFT       4
-
-#define DAC_RUNNING         1
-#define ADC_RUNNING         2
-
-#define SND_DEV_DSP16       5 
-   
-#ifdef M_DEBUG
-static int debug;
-#define DPMOD   1   /* per module load */
-#define DPSTR   2   /* per 'stream' */
-#define DPSYS   3   /* per syscall */
-#define DPCRAP  4   /* stuff the user shouldn't see unless they're really debuggin */
-#define DPINT   5   /* per interrupt, LOTS */
-#define DPRINTK(DP, args...) {if (debug >= (DP)) printk(KERN_DEBUG PFX args);}
-#else
-#define DPRINTK(x)
-#endif
-
-struct m3_list {
-    int curlen;
-    u16 mem_addr;
-    int max;
-};
-
-static int external_amp = 1;
-static int gpio_pin = -1;
-
-struct m3_state {
-    unsigned int magic;
-    struct m3_card *card;
-    unsigned char fmt, enable;
-
-    int index;
-
-    /* this locks around the oss state in the driver */
-	/* no, this lock is removed - only use card->lock */
-	/* otherwise: against what are you protecting on SMP 
-		when irqhandler uses s->lock
-		and m3_assp_read uses card->lock ?
-		*/
-    struct mutex open_mutex;
-    wait_queue_head_t open_wait;
-    mode_t open_mode;
-
-    int dev_audio;
-
-    struct assp_instance {
-        u16 code, data;
-    } dac_inst, adc_inst;
-
-    /* should be in dmabuf */
-    unsigned int rateadc, ratedac;
-
-    struct dmabuf {
-        void *rawbuf;
-        unsigned buforder;
-        unsigned numfrag;
-        unsigned fragshift;
-        unsigned hwptr, swptr;
-        unsigned total_bytes;
-        int count;
-        unsigned error; /* over/underrun */
-        wait_queue_head_t wait;
-        /* redundant, but makes calculations easier */
-        unsigned fragsize;
-        unsigned dmasize;
-        unsigned fragsamples;
-        /* OSS stuff */
-        unsigned mapped:1;
-        unsigned ready:1;    
-        unsigned endcleared:1;
-        unsigned ossfragshift;
-        int ossmaxfrags;
-        unsigned subdivision;
-        /* new in m3 */
-        int mixer_index, dma_index, msrc_index, adc1_index;
-        int in_lists;
-        /* 2.4.. */
-        dma_addr_t handle;
-
-    } dma_dac, dma_adc;
-};
-    
-struct m3_card {
-    unsigned int magic;
-
-    struct m3_card *next;
-
-    struct ac97_codec *ac97;
-    spinlock_t ac97_lock;
-
-    int card_type;
-
-#define NR_DSPS 1
-#define MAX_DSPS NR_DSPS
-    struct m3_state channels[MAX_DSPS];
-
-    /* this locks around the physical registers on the card */
-    spinlock_t lock;
-
-    /* hardware resources */
-    struct pci_dev *pcidev;
-    u32 iobase;
-    u32 irq;
-
-    int dacs_active;
-
-    int timer_users;
-
-    struct m3_list  msrc_list,
-                    mixer_list,
-                    adc1_list,
-                    dma_list;
-
-    /* for storing reset state..*/
-    u8 reset_state;
-
-    u16 *suspend_mem;
-    int in_suspend;
-    wait_queue_head_t suspend_queue;
-};
-
-/*
- * an arbitrary volume we set the internal
- * volume settings to so that the ac97 volume
- * range is a little less insane.  0x7fff is 
- * max.
- */
-#define ARB_VOLUME ( 0x6800 )
-
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-enum {
-    ESS_ALLEGRO,
-    ESS_MAESTRO3,
-    /*
-     * a maestro3 with 'hardware strapping', only
-     * found inside ESS?
-     */
-    ESS_MAESTRO3HW,
-};
-
-static char *card_names[] = {
-    [ESS_ALLEGRO] = "Allegro",
-    [ESS_MAESTRO3] = "Maestro3(i)",
-    [ESS_MAESTRO3HW] = "Maestro3(i)hw"
-};
-
-#ifndef PCI_VENDOR_ESS
-#define PCI_VENDOR_ESS      0x125D
-#endif
-
-#define M3_DEVICE(DEV, TYPE)			\
-{						\
-.vendor	     = PCI_VENDOR_ESS,			\
-.device	     = DEV,				\
-.subvendor   = PCI_ANY_ID,			\
-.subdevice   = PCI_ANY_ID,			\
-.class	     = PCI_CLASS_MULTIMEDIA_AUDIO << 8,	\
-.class_mask  = 0xffff << 8,			\
-.driver_data = TYPE,				\
-}
-
-static struct pci_device_id m3_id_table[] = {
-    M3_DEVICE(0x1988, ESS_ALLEGRO),
-    M3_DEVICE(0x1998, ESS_MAESTRO3),
-    M3_DEVICE(0x199a, ESS_MAESTRO3HW),
-    {0,}
-};
-
-MODULE_DEVICE_TABLE (pci, m3_id_table);
-
-/*
- * reports seem to indicate that the m3 is limited
- * to 28bit bus addresses.  aaaargggh...
- */
-#define M3_PCI_DMA_MASK 0x0fffffff
-
-static unsigned 
-ld2(unsigned int x)
-{
-    unsigned r = 0;
-    
-    if (x >= 0x10000) {
-        x >>= 16;
-        r += 16;
-    }
-    if (x >= 0x100) {
-        x >>= 8;
-        r += 8;
-    }
-    if (x >= 0x10) {
-        x >>= 4;
-        r += 4;
-    }
-    if (x >= 4) {
-        x >>= 2;
-        r += 2;
-    }
-    if (x >= 2)
-        r++;
-    return r;
-}
-
-static struct m3_card *devs;
-
-/*
- * I'm not very good at laying out functions in a file :)
- */
-static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf);
-static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state);
-static void check_suspend(struct m3_card *card);
-
-static struct notifier_block m3_reboot_nb = {
-	.notifier_call = m3_notifier,
-};
-
-static void m3_outw(struct m3_card *card,
-        u16 value, unsigned long reg)
-{
-    check_suspend(card);
-    outw(value, card->iobase + reg);
-}
-
-static u16 m3_inw(struct m3_card *card, unsigned long reg)
-{
-    check_suspend(card);
-    return inw(card->iobase + reg);
-}
-static void m3_outb(struct m3_card *card, 
-        u8 value, unsigned long reg)
-{
-    check_suspend(card);
-    outb(value, card->iobase + reg);
-}
-static u8 m3_inb(struct m3_card *card, unsigned long reg)
-{
-    check_suspend(card);
-    return inb(card->iobase + reg);
-}
-
-/*
- * access 16bit words to the code or data regions of the dsp's memory.
- * index addresses 16bit words.
- */
-static u16 __m3_assp_read(struct m3_card *card, u16 region, u16 index)
-{
-    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
-    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
-    return m3_inw(card, DSP_PORT_MEMORY_DATA);
-}
-static u16 m3_assp_read(struct m3_card *card, u16 region, u16 index)
-{
-    unsigned long flags;
-    u16 ret;
-
-    spin_lock_irqsave(&(card->lock), flags);
-    ret = __m3_assp_read(card, region, index);
-    spin_unlock_irqrestore(&(card->lock), flags);
-
-    return ret;
-}
-
-static void __m3_assp_write(struct m3_card *card, 
-        u16 region, u16 index, u16 data)
-{
-    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
-    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
-    m3_outw(card, data, DSP_PORT_MEMORY_DATA);
-}
-static void m3_assp_write(struct m3_card *card, 
-        u16 region, u16 index, u16 data)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&(card->lock), flags);
-    __m3_assp_write(card, region, index, data);
-    spin_unlock_irqrestore(&(card->lock), flags);
-}
-
-static void m3_assp_halt(struct m3_card *card)
-{
-    card->reset_state = m3_inb(card, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
-    mdelay(10);
-    m3_outb(card, card->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-static void m3_assp_continue(struct m3_card *card)
-{
-    m3_outb(card, card->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-/*
- * This makes me sad. the maestro3 has lists
- * internally that must be packed.. 0 terminates,
- * apparently, or maybe all unused entries have
- * to be 0, the lists have static lengths set
- * by the binary code images.
- */
-
-static int m3_add_list(struct m3_card *card,
-        struct m3_list *list, u16 val)
-{
-    DPRINTK(DPSTR, "adding val 0x%x to list 0x%p at pos %d\n",
-            val, list, list->curlen);
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            list->mem_addr + list->curlen,
-            val);
-
-    return list->curlen++;
-
-}
-
-static void m3_remove_list(struct m3_card *card,
-        struct m3_list *list, int index)
-{
-    u16  val;
-    int lastindex = list->curlen - 1;
-
-    DPRINTK(DPSTR, "removing ind %d from list 0x%p\n",
-            index, list);
-
-    if(index != lastindex) {
-        val = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                list->mem_addr + lastindex);
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-                list->mem_addr + index,
-                val);
-    }
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            list->mem_addr + lastindex,
-            0);
-
-    list->curlen--;
-}
-
-static void set_fmt(struct m3_state *s, unsigned char mask, unsigned char data)
-{
-    int tmp;
-
-    s->fmt = (s->fmt & mask) | data;
-
-    tmp = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
-
-    /* write to 'mono' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 1, 
-            (tmp & ESS_FMT_STEREO) ? 0 : 1);
-    /* write to '8bit' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 2, 
-            (tmp & ESS_FMT_16BIT) ? 0 : 1);
-
-    tmp = (s->fmt >> ESS_ADC_SHIFT) & ESS_FMT_MASK;
-
-    /* write to 'mono' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 1, 
-            (tmp & ESS_FMT_STEREO) ? 0 : 1);
-    /* write to '8bit' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 2, 
-            (tmp & ESS_FMT_16BIT) ? 0 : 1);
-}
-
-static void set_dac_rate(struct m3_state *s, unsigned int rate)
-{
-    u32 freq;
-
-    if (rate > 48000)
-        rate = 48000;
-    if (rate < 8000)
-        rate = 8000;
-
-    s->ratedac = rate;
-
-    freq = ((rate << 15) + 24000 ) / 48000;
-    if(freq) 
-        freq--;
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_FREQUENCY,
-            freq);
-}
-
-static void set_adc_rate(struct m3_state *s, unsigned int rate)
-{
-    u32 freq;
-
-    if (rate > 48000)
-        rate = 48000;
-    if (rate < 8000)
-        rate = 8000;
-
-    s->rateadc = rate;
-
-    freq = ((rate << 15) + 24000 ) / 48000;
-    if(freq) 
-        freq--;
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_FREQUENCY,
-            freq);
-}
-
-static void inc_timer_users(struct m3_card *card)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&card->lock, flags);
-    
-    card->timer_users++;
-    DPRINTK(DPSYS, "inc timer users now %d\n",
-            card->timer_users);
-    if(card->timer_users != 1) 
-        goto out;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_RELOAD,
-         240 ) ;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_CURRENT,
-         240 ) ;
-
-    m3_outw(card,  
-            m3_inw(card, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE,
-            HOST_INT_CTRL);
-out:
-    spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static void dec_timer_users(struct m3_card *card)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&card->lock, flags);
-
-    card->timer_users--;
-    DPRINTK(DPSYS, "dec timer users now %d\n",
-            card->timer_users);
-    if(card->timer_users > 0 ) 
-        goto out;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_RELOAD,
-         0 ) ;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_CURRENT,
-         0 ) ;
-
-    m3_outw(card,  m3_inw(card, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE,
-            HOST_INT_CTRL);
-out:
-    spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/*
- * {start,stop}_{adc,dac} should be called
- * while holding the 'state' lock and they
- * will try to grab the 'card' lock..
- */
-static void stop_adc(struct m3_state *s)
-{
-    if (! (s->enable & ADC_RUNNING)) 
-        return;
-
-    s->enable &= ~ADC_RUNNING;
-    dec_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_INSTANCE_READY, 0);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_ADC1_REQUEST, 0);
-}    
-
-static void stop_dac(struct m3_state *s)
-{
-    if (! (s->enable & DAC_RUNNING)) 
-        return;
-
-    DPRINTK(DPSYS, "stop_dac()\n");
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_INSTANCE_READY, 0);
-
-    s->enable &= ~DAC_RUNNING;
-    s->card->dacs_active--;
-    dec_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER, 
-            s->card->dacs_active ) ;
-}    
-
-static void start_dac(struct m3_state *s)
-{
-    if( (!s->dma_dac.mapped && s->dma_dac.count < 1) ||
-            !s->dma_dac.ready ||
-            (s->enable & DAC_RUNNING)) 
-        return;
-
-    DPRINTK(DPSYS, "start_dac()\n");
-
-    s->enable |= DAC_RUNNING;
-    s->card->dacs_active++;
-    inc_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_INSTANCE_READY, 1);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER, 
-            s->card->dacs_active ) ;
-}    
-
-static void start_adc(struct m3_state *s)
-{
-    if ((! s->dma_adc.mapped &&
-                s->dma_adc.count >= (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-        || !s->dma_adc.ready 
-        || (s->enable & ADC_RUNNING) ) 
-            return;
-
-    DPRINTK(DPSYS, "start_adc()\n");
-
-    s->enable |= ADC_RUNNING;
-    inc_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_ADC1_REQUEST, 1);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_INSTANCE_READY, 1);
-}    
-
-static struct play_vals {
-    u16 addr, val;
-} pv[] = {
-    {CDATA_LEFT_VOLUME, ARB_VOLUME},
-    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
-    {SRC3_DIRECTION_OFFSET, 0} ,
-    /* +1, +2 are stereo/16 bit */
-    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-    {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
-    {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
-    {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
-    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-    {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
-};
-
-
-/* the mode passed should be already shifted and masked */
-static void m3_play_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
-{
-    int dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
-    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
-    int dsp_in_buffer = s->dac_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
-    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
-    struct dmabuf *db = &s->dma_dac;
-    int i;
-
-    DPRINTK(DPSTR, "mode=%d rate=%d buf=%p len=%d.\n",
-        mode, rate, buffer, size);
-
-#define LO(x) ((x) & 0xffff)
-#define HI(x) LO((x) >> 16)
-
-    /* host dma buffer pointers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_ADDRL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_ADDRH,
-        HI(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
-        LO(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
-        HI(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_CURRENTL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_CURRENTH,
-        HI(virt_to_bus(buffer)));
-#undef LO
-#undef HI
-
-    /* dsp buffers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_BEGIN,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_END_PLUS_1,
-        dsp_in_buffer + (dsp_in_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_HEAD,
-        dsp_in_buffer);
-    
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_TAIL,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_BEGIN,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_END_PLUS_1,
-        dsp_out_buffer + (dsp_out_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_HEAD,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_TAIL,
-        dsp_out_buffer);
-
-    /*
-     * some per client initializers
-     */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 12,
-        s->dac_inst.data + 40 + 8);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 19,
-        s->dac_inst.code + MINISRC_COEF_LOC);
-
-    /* enable or disable low pass filter? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 22,
-        s->ratedac > 45000 ? 0xff : 0 );
-    
-    /* tell it which way dma is going? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_DMA_CONTROL,
-        DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
-    /*
-     * set an armload of static initializers
-     */
-    for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) 
-        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + pv[i].addr, pv[i].val);
-
-    /* 
-     * put us in the lists if we're not already there
-     */
-
-    if(db->in_lists == 0) {
-
-        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->mixer_index = m3_add_list(s->card, &s->card->mixer_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->in_lists = 1;
-    }
-
-    set_dac_rate(s,rate);
-    start_dac(s);
-}
-
-/*
- *    Native record driver 
- */
-static struct rec_vals {
-    u16 addr, val;
-} rv[] = {
-    {CDATA_LEFT_VOLUME, ARB_VOLUME},
-    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
-    {SRC3_DIRECTION_OFFSET, 1} ,
-    /* +1, +2 are stereo/16 bit */
-    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-    {SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
-    {SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
-    {SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
-    {SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
-    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-    {SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
-    {SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
-};
-
-/* again, passed mode is alrady shifted/masked */
-static void m3_rec_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
-{
-    int dsp_in_size = MINISRC_IN_BUFFER_SIZE + (0x10 * 2);
-    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
-    int dsp_in_buffer = s->adc_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
-    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
-    struct dmabuf *db = &s->dma_adc;
-    int i;
-
-    DPRINTK(DPSTR, "rec_setup mode=%d rate=%d buf=%p len=%d.\n",
-        mode, rate, buffer, size);
-
-#define LO(x) ((x) & 0xffff)
-#define HI(x) LO((x) >> 16)
-
-    /* host dma buffer pointers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_ADDRL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_ADDRH,
-        HI(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
-        LO(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
-        HI(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_CURRENTL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_CURRENTH,
-        HI(virt_to_bus(buffer)));
-#undef LO
-#undef HI
-
-    /* dsp buffers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_BEGIN,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_END_PLUS_1,
-        dsp_in_buffer + (dsp_in_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_HEAD,
-        dsp_in_buffer);
-    
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_TAIL,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_BEGIN,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_END_PLUS_1,
-        dsp_out_buffer + (dsp_out_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_HEAD,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_TAIL,
-        dsp_out_buffer);
-
-    /*
-     * some per client initializers
-     */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + SRC3_DIRECTION_OFFSET + 12,
-        s->adc_inst.data + 40 + 8);
-
-    /* tell it which way dma is going? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_DMA_CONTROL,
-        DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT + 
-        DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
-    /*
-     * set an armload of static initializers
-     */
-    for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) 
-        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + rv[i].addr, rv[i].val);
-
-    /* 
-     * put us in the lists if we're not already there
-     */
-
-    if(db->in_lists == 0) {
-
-        db->adc1_index = m3_add_list(s->card, &s->card->adc1_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->in_lists = 1;
-    }
-
-    set_adc_rate(s,rate);
-    start_adc(s);
-}
-/* --------------------------------------------------------------------- */
-
-static void set_dmaa(struct m3_state *s, unsigned int addr, unsigned int count)
-{
-    DPRINTK(DPINT,"set_dmaa??\n");
-}
-
-static void set_dmac(struct m3_state *s, unsigned int addr, unsigned int count)
-{
-    DPRINTK(DPINT,"set_dmac??\n");
-}
-
-static u32 get_dma_pos(struct m3_card *card,
-		       int instance_addr)
-{
-    u16 hi = 0, lo = 0;
-    int retry = 10;
-
-    /*
-     * try and get a valid answer
-     */
-    while(retry--) {
-        hi =  m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTH);
-
-        lo = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTL);
-
-        if(hi == m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTH))
-            break;
-    }
-    return lo | (hi<<16);
-}
-
-static u32 get_dmaa(struct m3_state *s)
-{
-    u32 offset;
-
-    offset = get_dma_pos(s->card, s->dac_inst.data) - 
-        virt_to_bus(s->dma_dac.rawbuf);
-
-    DPRINTK(DPINT,"get_dmaa: 0x%08x\n",offset);
-
-    return offset;
-}
-
-static u32 get_dmac(struct m3_state *s)
-{
-    u32 offset;
-
-    offset = get_dma_pos(s->card, s->adc_inst.data) -
-        virt_to_bus(s->dma_adc.rawbuf);
-
-    DPRINTK(DPINT,"get_dmac: 0x%08x\n",offset);
-
-    return offset;
-
-}
-
-static int 
-prog_dmabuf(struct m3_state *s, unsigned rec)
-{
-    struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-    unsigned rate = rec ? s->rateadc : s->ratedac;
-    unsigned bytepersec;
-    unsigned bufs;
-    unsigned char fmt;
-    unsigned long flags;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    fmt = s->fmt;
-    if (rec) {
-        stop_adc(s);
-        fmt >>= ESS_ADC_SHIFT;
-    } else {
-        stop_dac(s);
-        fmt >>= ESS_DAC_SHIFT;
-    }
-    fmt &= ESS_FMT_MASK;
-
-    db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-
-    bytepersec = rate << sample_shift[fmt];
-    bufs = PAGE_SIZE << db->buforder;
-    if (db->ossfragshift) {
-        if ((1000 << db->ossfragshift) < bytepersec)
-            db->fragshift = ld2(bytepersec/1000);
-        else
-            db->fragshift = db->ossfragshift;
-    } else {
-        db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-        if (db->fragshift < 3)
-            db->fragshift = 3; 
-    }
-    db->numfrag = bufs >> db->fragshift;
-    while (db->numfrag < 4 && db->fragshift > 3) {
-        db->fragshift--;
-        db->numfrag = bufs >> db->fragshift;
-    }
-    db->fragsize = 1 << db->fragshift;
-    if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-        db->numfrag = db->ossmaxfrags;
-    db->fragsamples = db->fragsize >> sample_shift[fmt];
-    db->dmasize = db->numfrag << db->fragshift;
-
-    DPRINTK(DPSTR,"prog_dmabuf: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize);
-
-    memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize);
-
-    if (rec) 
-        m3_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize);
-    else 
-        m3_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize);
-
-    db->ready = 1;
-
-    spin_unlock_irqrestore(&s->card->lock, flags);
-
-    return 0;
-}
-
-static void clear_advance(struct m3_state *s)
-{
-    unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
-    
-    unsigned char *buf = s->dma_dac.rawbuf;
-    unsigned bsize = s->dma_dac.dmasize;
-    unsigned bptr = s->dma_dac.swptr;
-    unsigned len = s->dma_dac.fragsize;
-    
-    if (bptr + len > bsize) {
-        unsigned x = bsize - bptr;
-        memset(buf + bptr, c, x);
-        /* account for wrapping? */
-        bptr = 0;
-        len -= x;
-    }
-    memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void m3_update_ptr(struct m3_state *s)
-{
-    unsigned hwptr;
-    int diff;
-
-    /* update ADC pointer */
-    if (s->dma_adc.ready) {
-        hwptr = get_dmac(s) % s->dma_adc.dmasize;
-        diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-        s->dma_adc.hwptr = hwptr;
-        s->dma_adc.total_bytes += diff;
-        s->dma_adc.count += diff;
-        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-            wake_up(&s->dma_adc.wait);
-        if (!s->dma_adc.mapped) {
-            if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                stop_adc(s); 
-                /* brute force everyone back in sync, sigh */
-                s->dma_adc.count = 0;
-                s->dma_adc.swptr = 0;
-                s->dma_adc.hwptr = 0;
-                s->dma_adc.error++;
-            }
-        }
-    }
-    /* update DAC pointer */
-    if (s->dma_dac.ready) {
-        hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
-        diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-
-        DPRINTK(DPINT,"updating dac: hwptr: %6d diff: %6d count: %6d\n",
-                hwptr,diff,s->dma_dac.count);
-
-        s->dma_dac.hwptr = hwptr;
-        s->dma_dac.total_bytes += diff;
-
-        if (s->dma_dac.mapped) {
-            
-            s->dma_dac.count += diff;
-            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) {
-                wake_up(&s->dma_dac.wait);
-            }
-        } else {
-
-            s->dma_dac.count -= diff;
-            
-            if (s->dma_dac.count <= 0) {
-                DPRINTK(DPCRAP,"underflow! diff: %d (0x%x) count: %d (0x%x) hw: %d (0x%x) sw: %d (0x%x)\n", 
-                        diff, diff, 
-                        s->dma_dac.count, 
-                        s->dma_dac.count, 
-                    hwptr, hwptr,
-                    s->dma_dac.swptr,
-                    s->dma_dac.swptr);
-                stop_dac(s);
-                /* brute force everyone back in sync, sigh */
-                s->dma_dac.count = 0; 
-                s->dma_dac.swptr = hwptr; 
-                s->dma_dac.error++;
-            } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                clear_advance(s);
-                s->dma_dac.endcleared = 1;
-            }
-            if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) {
-                wake_up(&s->dma_dac.wait);
-                DPRINTK(DPINT,"waking up DAC count: %d sw: %d hw: %d\n",
-                        s->dma_dac.count, s->dma_dac.swptr, hwptr);
-            }
-        }
-    }
-}
-
-static irqreturn_t m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-    struct m3_card *c = (struct m3_card *)dev_id;
-    struct m3_state *s = &c->channels[0];
-    u8 status;
-
-    status = inb(c->iobase+0x1A);
-
-    if(status == 0xff)
-	return IRQ_NONE;
-   
-    /* presumably acking the ints? */
-    outw(status, c->iobase+0x1A); 
-
-    if(c->in_suspend)
-        return IRQ_HANDLED;
-
-    /*
-     * ack an assp int if its running
-     * and has an int pending
-     */
-    if( status & ASSP_INT_PENDING) {
-        u8 ctl = inb(c->iobase + ASSP_CONTROL_B);
-        if( !(ctl & STOP_ASSP_CLOCK)) {
-            ctl = inb(c->iobase + ASSP_HOST_INT_STATUS );
-            if(ctl & DSP2HOST_REQ_TIMER) {
-                outb( DSP2HOST_REQ_TIMER, c->iobase + ASSP_HOST_INT_STATUS);
-                /* update adc/dac info if it was a timer int */
-                spin_lock(&c->lock);
-                m3_update_ptr(s);
-                spin_unlock(&c->lock);
-            }
-        }
-    }
-
-    /* XXX is this needed? */
-    if(status & 0x40) 
-        outb(0x40, c->iobase+0x1A);
-    return IRQ_HANDLED;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value in %s\n";
-
-#define VALIDATE_MAGIC(FOO,MAG)                         \
-({                                                \
-    if (!(FOO) || (FOO)->magic != MAG) { \
-        printk(invalid_magic,__FUNCTION__);            \
-        return -ENXIO;                    \
-    }                                         \
-})
-
-#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,M3_STATE_MAGIC)
-#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,M3_CARD_MAGIC)
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct m3_state *s, int nonblock)
-{
-    DECLARE_WAITQUEUE(wait,current);
-    unsigned long flags;
-    int count;
-    signed long tmo;
-
-    if (s->dma_dac.mapped || !s->dma_dac.ready)
-        return 0;
-    set_current_state(TASK_INTERRUPTIBLE);
-    add_wait_queue(&s->dma_dac.wait, &wait);
-    for (;;) {
-        spin_lock_irqsave(&s->card->lock, flags);
-        count = s->dma_dac.count;
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (count <= 0)
-            break;
-        if (signal_pending(current))
-            break;
-        if (nonblock) {
-            remove_wait_queue(&s->dma_dac.wait, &wait);
-            set_current_state(TASK_RUNNING);
-            return -EBUSY;
-        }
-        tmo = (count * HZ) / s->ratedac;
-        tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];
-        /* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
-            or something.  who cares. - zach */
-        if (!schedule_timeout(tmo ? tmo : 1) && tmo)
-            DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);
-    }
-    remove_wait_queue(&s->dma_dac.wait, &wait);
-    set_current_state(TASK_RUNNING);
-    if (signal_pending(current))
-            return -ERESTARTSYS;
-    return 0;
-}
-
-static ssize_t m3_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    ssize_t ret;
-    unsigned long flags;
-    unsigned swptr;
-    int cnt;
-    
-    VALIDATE_STATE(s);
-    if (s->dma_adc.mapped)
-        return -ENXIO;
-    if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-        return ret;
-    if (!access_ok(VERIFY_WRITE, buffer, count))
-        return -EFAULT;
-    ret = 0;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    while (count > 0) {
-        int timed_out;
-
-        swptr = s->dma_adc.swptr;
-        cnt = s->dma_adc.dmasize-swptr;
-        if (s->dma_adc.count < cnt)
-            cnt = s->dma_adc.count;
-
-        if (cnt > count)
-            cnt = count;
-
-        if (cnt <= 0) {
-            start_adc(s);
-            if (file->f_flags & O_NONBLOCK) 
-            {
-                ret = ret ? ret : -EAGAIN;
-                goto out;
-            }
-
-            spin_unlock_irqrestore(&s->card->lock, flags);
-            timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0;
-            spin_lock_irqsave(&s->card->lock, flags);
-
-            if(timed_out) {
-                printk("read: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
-                       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-                       s->dma_adc.hwptr, s->dma_adc.swptr);
-                stop_adc(s);
-                set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-                s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-            }
-            if (signal_pending(current)) 
-            {
-                ret = ret ? ret : -ERESTARTSYS;
-                goto out;
-            }
-            continue;
-        }
-    
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-            ret = ret ? ret : -EFAULT;
-            return ret;
-        }
-        spin_lock_irqsave(&s->card->lock, flags);
-
-        swptr = (swptr + cnt) % s->dma_adc.dmasize;
-        s->dma_adc.swptr = swptr;
-        s->dma_adc.count -= cnt;
-        count -= cnt;
-        buffer += cnt;
-        ret += cnt;
-        start_adc(s);
-    }
-
-out:
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return ret;
-}
-
-static ssize_t m3_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    ssize_t ret;
-    unsigned long flags;
-    unsigned swptr;
-    int cnt;
-    
-    VALIDATE_STATE(s);
-    if (s->dma_dac.mapped)
-        return -ENXIO;
-    if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-        return ret;
-    if (!access_ok(VERIFY_READ, buffer, count))
-        return -EFAULT;
-    ret = 0;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    while (count > 0) {
-        int timed_out;
-
-        if (s->dma_dac.count < 0) {
-            s->dma_dac.count = 0;
-            s->dma_dac.swptr = s->dma_dac.hwptr;
-        }
-        swptr = s->dma_dac.swptr;
-
-        cnt = s->dma_dac.dmasize-swptr;
-
-        if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-            cnt = s->dma_dac.dmasize - s->dma_dac.count;
-
-
-        if (cnt > count)
-            cnt = count;
-
-        if (cnt <= 0) {
-            start_dac(s);
-            if (file->f_flags & O_NONBLOCK) {
-                if(!ret) ret = -EAGAIN;
-                goto out;
-            }
-            spin_unlock_irqrestore(&s->card->lock, flags);
-            timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0;
-            spin_lock_irqsave(&s->card->lock, flags);
-            if(timed_out) {
-                DPRINTK(DPCRAP,"write: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
-                       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-                       s->dma_dac.hwptr, s->dma_dac.swptr);
-                stop_dac(s);
-                set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-                s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-            }
-            if (signal_pending(current)) {
-                if (!ret) ret = -ERESTARTSYS;
-                goto out;
-            }
-            continue;
-        }
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-            if (!ret) ret = -EFAULT;
-            return ret;
-        }
-        spin_lock_irqsave(&s->card->lock, flags);
-
-        DPRINTK(DPSYS,"wrote %6d bytes at sw: %6d cnt: %6d while hw: %6d\n",
-                cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);
-        
-        swptr = (swptr + cnt) % s->dma_dac.dmasize;
-
-        s->dma_dac.swptr = swptr;
-        s->dma_dac.count += cnt;
-        s->dma_dac.endcleared = 0;
-        count -= cnt;
-        buffer += cnt;
-        ret += cnt;
-        start_dac(s);
-    }
-out:
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return ret;
-}
-
-static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    unsigned long flags;
-    unsigned int mask = 0;
-
-    VALIDATE_STATE(s);
-    if (file->f_mode & FMODE_WRITE)
-        poll_wait(file, &s->dma_dac.wait, wait);
-    if (file->f_mode & FMODE_READ)
-        poll_wait(file, &s->dma_adc.wait, wait);
-
-    spin_lock_irqsave(&s->card->lock, flags);
-    m3_update_ptr(s);
-
-    if (file->f_mode & FMODE_READ) {
-        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-            mask |= POLLIN | POLLRDNORM;
-    }
-    if (file->f_mode & FMODE_WRITE) {
-        if (s->dma_dac.mapped) {
-            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                mask |= POLLOUT | POLLWRNORM;
-        } else {
-            if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                mask |= POLLOUT | POLLWRNORM;
-        }
-    }
-
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return mask;
-}
-
-static int m3_mmap(struct file *file, struct vm_area_struct *vma)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    unsigned long max_size, size, start, offset;
-    struct dmabuf *db;
-    int ret = -EINVAL;
-
-    VALIDATE_STATE(s);
-    if (vma->vm_flags & VM_WRITE) {
-        if ((ret = prog_dmabuf(s, 0)) != 0)
-            return ret;
-        db = &s->dma_dac;
-    } else 
-    if (vma->vm_flags & VM_READ) {
-        if ((ret = prog_dmabuf(s, 1)) != 0)
-            return ret;
-        db = &s->dma_adc;
-    } else  
-        return -EINVAL;
-
-    max_size = db->dmasize;
-
-    start = vma->vm_start;
-    offset = (vma->vm_pgoff << PAGE_SHIFT);
-    size = vma->vm_end - vma->vm_start;
-
-    if(size > max_size)
-        goto out;
-    if(offset > max_size - size)
-        goto out;
-
-    /*
-     * this will be ->nopage() once I can 
-     * ask Jeff what the hell I'm doing wrong.
-     */
-    ret = -EAGAIN;
-    if (remap_pfn_range(vma, vma->vm_start,
-			virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-			size, vma->vm_page_prot))
-        goto out;
-
-    db->mapped = 1;
-    ret = 0;
-
-out:
-    return ret;
-}
-
-/*
- * this function is a disaster..
- */
-#define get_user_ret(x, ptr,  ret) ({ if(get_user(x, ptr)) return ret; })
-static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-	struct m3_card *card=s->card;
-    unsigned long flags;
-    audio_buf_info abinfo;
-    count_info cinfo;
-    int val, mapped, ret;
-    unsigned char fmtm, fmtd;
-    void __user *argp = (void __user *)arg;
-    int __user *p = argp;
-
-    VALIDATE_STATE(s);
-
-    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-        ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-
-    DPRINTK(DPSYS,"m3_ioctl: cmd %d\n", cmd);
-
-    switch (cmd) {
-    case OSS_GETVERSION:
-        return put_user(SOUND_VERSION, p);
-
-    case SNDCTL_DSP_SYNC:
-        if (file->f_mode & FMODE_WRITE)
-            return drain_dac(s, file->f_flags & O_NONBLOCK);
-        return 0;
-        
-    case SNDCTL_DSP_SETDUPLEX:
-        /* XXX fix */
-        return 0;
-
-    case SNDCTL_DSP_GETCAPS:
-        return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-        
-    case SNDCTL_DSP_RESET:
-        spin_lock_irqsave(&card->lock, flags);
-        if (file->f_mode & FMODE_WRITE) {
-            stop_dac(s);
-            synchronize_irq(s->card->pcidev->irq);
-            s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-        }
-        if (file->f_mode & FMODE_READ) {
-            stop_adc(s);
-            synchronize_irq(s->card->pcidev->irq);
-            s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_SPEED:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val >= 0) {
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                set_adc_rate(s, val);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                set_dac_rate(s, val);
-            }
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-        
-    case SNDCTL_DSP_STEREO:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        fmtd = 0;
-        fmtm = ~0;
-        if (file->f_mode & FMODE_READ) {
-            stop_adc(s);
-            s->dma_adc.ready = 0;
-            if (val)
-                fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-            else
-                fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            stop_dac(s);
-            s->dma_dac.ready = 0;
-            if (val)
-                fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-            else
-                fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-        }
-        set_fmt(s, fmtm, fmtd);
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_CHANNELS:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val != 0) {
-            fmtd = 0;
-            fmtm = ~0;
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                if (val >= 2)
-                    fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                if (val >= 2)
-                    fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-            }
-            set_fmt(s, fmtm, fmtd);
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-        
-    case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-        return put_user(AFMT_U8|AFMT_S16_LE, p);
-        
-    case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val != AFMT_QUERY) {
-            fmtd = 0;
-            fmtm = ~0;
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                if (val == AFMT_S16_LE)
-                    fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                if (val == AFMT_S16_LE)
-                    fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);
-            }
-            set_fmt(s, fmtm, fmtd);
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
-            (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-            : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
-                AFMT_S16_LE : 
-                AFMT_U8, 
-            p);
-        
-    case SNDCTL_DSP_POST:
-        return 0;
-
-    case SNDCTL_DSP_GETTRIGGER:
-        val = 0;
-        if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING))
-            val |= PCM_ENABLE_INPUT;
-        if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
-            val |= PCM_ENABLE_OUTPUT;
-        return put_user(val, p);
-        
-    case SNDCTL_DSP_SETTRIGGER:
-        get_user_ret(val, p, -EFAULT);
-        if (file->f_mode & FMODE_READ) {
-            if (val & PCM_ENABLE_INPUT) {
-                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                    return ret;
-                start_adc(s);
-            } else
-                stop_adc(s);
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            if (val & PCM_ENABLE_OUTPUT) {
-                if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                    return ret;
-                start_dac(s);
-            } else
-                stop_dac(s);
-        }
-        return 0;
-
-    case SNDCTL_DSP_GETOSPACE:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        if (!(s->enable & DAC_RUNNING) && (val = prog_dmabuf(s, 0)) != 0)
-            return val;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        abinfo.fragsize = s->dma_dac.fragsize;
-        abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-        abinfo.fragstotal = s->dma_dac.numfrag;
-        abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-        spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-    case SNDCTL_DSP_GETISPACE:
-        if (!(file->f_mode & FMODE_READ))
-            return -EINVAL;
-        if (!(s->enable & ADC_RUNNING) && (val = prog_dmabuf(s, 1)) != 0)
-            return val;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        abinfo.fragsize = s->dma_adc.fragsize;
-        abinfo.bytes = s->dma_adc.count;
-        abinfo.fragstotal = s->dma_adc.numfrag;
-        abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-        spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-        
-    case SNDCTL_DSP_NONBLOCK:
-        file->f_flags |= O_NONBLOCK;
-        return 0;
-
-    case SNDCTL_DSP_GETODELAY:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        val = s->dma_dac.count;
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user(val, p);
-
-    case SNDCTL_DSP_GETIPTR:
-        if (!(file->f_mode & FMODE_READ))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        cinfo.bytes = s->dma_adc.total_bytes;
-        cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-        cinfo.ptr = s->dma_adc.hwptr;
-        if (s->dma_adc.mapped)
-            s->dma_adc.count &= s->dma_adc.fragsize-1;
-        spin_unlock_irqrestore(&card->lock, flags);
-	if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-		return -EFAULT;
-	return 0;
-
-    case SNDCTL_DSP_GETOPTR:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        cinfo.bytes = s->dma_dac.total_bytes;
-        cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-        cinfo.ptr = s->dma_dac.hwptr;
-        if (s->dma_dac.mapped)
-            s->dma_dac.count &= s->dma_dac.fragsize-1;
-        spin_unlock_irqrestore(&card->lock, flags);
-	if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-		return -EFAULT;
-	return 0;
-
-    case SNDCTL_DSP_GETBLKSIZE:
-        if (file->f_mode & FMODE_WRITE) {
-            if ((val = prog_dmabuf(s, 0)))
-                return val;
-            return put_user(s->dma_dac.fragsize, p);
-        }
-        if ((val = prog_dmabuf(s, 1)))
-            return val;
-        return put_user(s->dma_adc.fragsize, p);
-
-    case SNDCTL_DSP_SETFRAGMENT:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (file->f_mode & FMODE_READ) {
-            s->dma_adc.ossfragshift = val & 0xffff;
-            s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-            if (s->dma_adc.ossfragshift < 4)
-                s->dma_adc.ossfragshift = 4;
-            if (s->dma_adc.ossfragshift > 15)
-                s->dma_adc.ossfragshift = 15;
-            if (s->dma_adc.ossmaxfrags < 4)
-                s->dma_adc.ossmaxfrags = 4;
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            s->dma_dac.ossfragshift = val & 0xffff;
-            s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-            if (s->dma_dac.ossfragshift < 4)
-                s->dma_dac.ossfragshift = 4;
-            if (s->dma_dac.ossfragshift > 15)
-                s->dma_dac.ossfragshift = 15;
-            if (s->dma_dac.ossmaxfrags < 4)
-                s->dma_dac.ossmaxfrags = 4;
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_SUBDIVIDE:
-        if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-            (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-            return -EINVAL;
-                get_user_ret(val, p, -EFAULT);
-        if (val != 1 && val != 2 && val != 4)
-            return -EINVAL;
-        if (file->f_mode & FMODE_READ)
-            s->dma_adc.subdivision = val;
-        if (file->f_mode & FMODE_WRITE)
-            s->dma_dac.subdivision = val;
-        return 0;
-
-    case SOUND_PCM_READ_RATE:
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-    case SOUND_PCM_READ_CHANNELS:
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-
-    case SOUND_PCM_READ_BITS:
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
-
-    case SOUND_PCM_WRITE_FILTER:
-    case SNDCTL_DSP_SETSYNCRO:
-    case SOUND_PCM_READ_FILTER:
-        return -EINVAL;
-        
-    }
-    return -EINVAL;
-}
-
-static int
-allocate_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
-{
-    int order;
-
-    DPRINTK(DPSTR,"allocating for dmabuf %p\n", db);
-
-    /* 
-     * alloc as big a chunk as we can, start with 
-     * 64k 'cause we're insane.  based on order cause
-     * the amazingly complicated prog_dmabuf wants it.
-     *
-     * pci_alloc_sonsistent guarantees that it won't cross a natural
-     * boundary; the m3 hardware can't have dma cross a 64k bus
-     * address boundary.
-     */
-    for (order = 16-PAGE_SHIFT; order >= 1; order--) {
-        db->rawbuf = pci_alloc_consistent(pci_dev, PAGE_SIZE << order,
-                        &(db->handle));
-        if(db->rawbuf)
-            break;
-    }
-
-    if (!db->rawbuf)
-        return 1;
-
-    DPRINTK(DPSTR,"allocated %ld (%d) bytes at %p\n",
-            PAGE_SIZE<<order, order, db->rawbuf);
-
-    {
-        struct page *page, *pend;
-
-        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << order) - 1);
-        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-            SetPageReserved(page);
-    }
-
-
-    db->buforder = order;
-    db->ready = 0;
-    db->mapped = 0;
-
-    return 0;
-}
-
-static void
-nuke_lists(struct m3_card *card, struct dmabuf *db)
-{
-    m3_remove_list(card, &(card->dma_list), db->dma_index);
-    m3_remove_list(card, &(card->msrc_list), db->msrc_index);
-    db->in_lists = 0;
-}
-
-static void
-free_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
-{
-    if(db->rawbuf == NULL)
-        return;
-
-    DPRINTK(DPSTR,"freeing %p from dmabuf %p\n",db->rawbuf, db);
-
-    {
-        struct page *page, *pend;
-        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-            ClearPageReserved(page);
-    }
-
-
-    pci_free_consistent(pci_dev, PAGE_SIZE << db->buforder,
-            db->rawbuf, db->handle);
-
-    db->rawbuf = NULL;
-    db->buforder = 0;
-    db->mapped = 0;
-    db->ready = 0;
-}
-
-static int m3_open(struct inode *inode, struct file *file)
-{
-    unsigned int minor = iminor(inode);
-    struct m3_card *c;
-    struct m3_state *s = NULL;
-    int i;
-    unsigned char fmtm = ~0, fmts = 0;
-    unsigned long flags;
-
-    /*
-     *    Scan the cards and find the channel. We only
-     *    do this at open time so it is ok
-     */
-    for(c = devs ; c != NULL ; c = c->next) {
-
-        for(i=0;i<NR_DSPS;i++) {
-
-            if(c->channels[i].dev_audio < 0)
-                continue;
-            if((c->channels[i].dev_audio ^ minor) & ~0xf)
-                continue;
-
-            s = &c->channels[i];
-            break;
-        }
-    }
-        
-    if (!s)
-        return -ENODEV;
-        
-    VALIDATE_STATE(s);
-
-    file->private_data = s;
-
-    /* wait for device to become free */
-    mutex_lock(&s->open_mutex);
-    while (s->open_mode & file->f_mode) {
-        if (file->f_flags & O_NONBLOCK) {
-            mutex_unlock(&s->open_mutex);
-            return -EWOULDBLOCK;
-        }
-        mutex_unlock(&s->open_mutex);
-        interruptible_sleep_on(&s->open_wait);
-        if (signal_pending(current))
-            return -ERESTARTSYS;
-        mutex_lock(&s->open_mutex);
-    }
-    
-    spin_lock_irqsave(&c->lock, flags);
-
-    if (file->f_mode & FMODE_READ) {
-        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-        if ((minor & 0xf) == SND_DEV_DSP16)
-            fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; 
-
-        s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-        set_adc_rate(s, 8000);
-    }
-    if (file->f_mode & FMODE_WRITE) {
-        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
-        if ((minor & 0xf) == SND_DEV_DSP16)
-            fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-
-        s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-        set_dac_rate(s, 8000);
-    }
-    set_fmt(s, fmtm, fmts);
-    s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-
-    mutex_unlock(&s->open_mutex);
-    spin_unlock_irqrestore(&c->lock, flags);
-    return nonseekable_open(inode, file);
-}
-
-static int m3_release(struct inode *inode, struct file *file)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-	struct m3_card *card=s->card;
-    unsigned long flags;
-
-    VALIDATE_STATE(s);
-    if (file->f_mode & FMODE_WRITE)
-        drain_dac(s, file->f_flags & O_NONBLOCK);
-
-    mutex_lock(&s->open_mutex);
-    spin_lock_irqsave(&card->lock, flags);
-
-    if (file->f_mode & FMODE_WRITE) {
-        stop_dac(s);
-        if(s->dma_dac.in_lists) {
-            m3_remove_list(s->card, &(s->card->mixer_list), s->dma_dac.mixer_index);
-            nuke_lists(s->card, &(s->dma_dac));
-        }
-    }
-    if (file->f_mode & FMODE_READ) {
-        stop_adc(s);
-        if(s->dma_adc.in_lists) {
-            m3_remove_list(s->card, &(s->card->adc1_list), s->dma_adc.adc1_index);
-            nuke_lists(s->card, &(s->dma_adc));
-        }
-    }
-        
-    s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-
-    spin_unlock_irqrestore(&card->lock, flags);
-    mutex_unlock(&s->open_mutex);
-    wake_up(&s->open_wait);
-
-    return 0;
-}
-
-/*
- * Wait for the ac97 serial bus to be free.
- * return nonzero if the bus is still busy.
- */
-static int m3_ac97_wait(struct m3_card *card)
-{
-    int i = 10000;
-
-    while( (m3_inb(card, 0x30) & 1) && i--) ;
-
-    return i == 0;
-}
-
-static u16 m3_ac97_read(struct ac97_codec *codec, u8 reg)
-{
-    u16 ret = 0;
-    struct m3_card *card = codec->private_data;
-
-    spin_lock(&card->ac97_lock);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy reading reg 0x%x\n",reg);
-        goto out;
-    }
-
-    m3_outb(card, 0x80 | (reg & 0x7f), 0x30);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy finishing read reg 0x%x\n",reg);
-        goto out;
-    }
-
-    ret =  m3_inw(card, 0x32);
-    DPRINTK(DPCRAP,"reading 0x%04x from 0x%02x\n",ret, reg);
-
-out:
-    spin_unlock(&card->ac97_lock);
-    return ret;
-}
-
-static void m3_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
-{
-    struct m3_card *card = codec->private_data;
-
-    spin_lock(&card->ac97_lock);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy writing 0x%x to 0x%x\n",val, reg);
-        goto out;
-    }
-    DPRINTK(DPCRAP,"writing 0x%04x  to  0x%02x\n", val, reg);
-
-    m3_outw(card, val, 0x32);
-    m3_outb(card, reg & 0x7f, 0x30);
-out:
-    spin_unlock(&card->ac97_lock);
-}
-/* OSS /dev/mixer file operation methods */
-static int m3_open_mixdev(struct inode *inode, struct file *file)
-{
-    unsigned int minor = iminor(inode);
-    struct m3_card *card = devs;
-
-    for (card = devs; card != NULL; card = card->next) {
-        if((card->ac97 != NULL) && (card->ac97->dev_mixer == minor))
-                break;
-    }
-
-    if (!card) {
-        return -ENODEV;
-    }
-
-    file->private_data = card->ac97;
-
-    return nonseekable_open(inode, file);
-}
-
-static int m3_release_mixdev(struct inode *inode, struct file *file)
-{
-    return 0;
-}
-
-static int m3_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
-                                    unsigned long arg)
-{
-    struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
-
-    return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static struct file_operations m3_mixer_fops = {
-	.owner	 = THIS_MODULE,
-	.llseek  = no_llseek,
-	.ioctl	 = m3_ioctl_mixdev,
-	.open	 = m3_open_mixdev,
-	.release = m3_release_mixdev,
-};
-
-static void remote_codec_config(int io, int isremote)
-{
-    isremote = isremote ? 1 : 0;
-
-    outw(  (inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote,
-            io + RING_BUS_CTRL_B);
-    outw(  (inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote,
-            io + SDO_OUT_DEST_CTRL);
-    outw(  (inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote,
-            io + SDO_IN_DEST_CTRL);
-}
-
-/* 
- * hack, returns non zero on err 
- */
-static int try_read_vendor(struct m3_card *card)
-{
-    u16 ret;
-
-    if(m3_ac97_wait(card)) 
-        return 1;
-
-    m3_outb(card, 0x80 | (AC97_VENDOR_ID1 & 0x7f), 0x30);
-
-    if(m3_ac97_wait(card)) 
-        return 1;
-
-    ret =  m3_inw(card, 0x32);
-
-    return (ret == 0) || (ret == 0xffff);
-}
-
-static void m3_codec_reset(struct m3_card *card, int busywait)
-{
-    u16 dir;
-    int delay1 = 0, delay2 = 0, i;
-    int io = card->iobase;
-
-    switch (card->card_type) {
-        /*
-         * the onboard codec on the allegro seems 
-         * to want to wait a very long time before
-         * coming back to life 
-         */
-        case ESS_ALLEGRO:
-            delay1 = 50;
-            delay2 = 800;
-        break;
-        case ESS_MAESTRO3:
-        case ESS_MAESTRO3HW:
-            delay1 = 20;
-            delay2 = 500;
-        break;
-    }
-
-    for(i = 0; i < 5; i ++) {
-        dir = inw(io + GPIO_DIRECTION);
-        dir |= 0x10; /* assuming pci bus master? */
-
-        remote_codec_config(io, 0);
-
-        outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A);
-        udelay(20);
-
-        outw(dir & ~GPO_PRIMARY_AC97 , io + GPIO_DIRECTION);
-        outw(~GPO_PRIMARY_AC97 , io + GPIO_MASK);
-        outw(0, io + GPIO_DATA);
-        outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
-
-        if(busywait)  {
-            mdelay(delay1);
-        } else {
-            set_current_state(TASK_UNINTERRUPTIBLE);
-            schedule_timeout((delay1 * HZ) / 1000);
-        }
-
-        outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
-        udelay(5);
-        /* ok, bring back the ac-link */
-        outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
-        outw(~0, io + GPIO_MASK);
-
-        if(busywait) {
-            mdelay(delay2);
-        } else {
-            set_current_state(TASK_UNINTERRUPTIBLE);
-            schedule_timeout((delay2 * HZ) / 1000);
-        }
-        if(! try_read_vendor(card))
-            break;
-
-        delay1 += 10;
-        delay2 += 100;
-
-        DPRINTK(DPMOD, "retrying codec reset with delays of %d and %d ms\n",
-                delay1, delay2);
-    }
-
-#if 0
-    /* more gung-ho reset that doesn't
-     * seem to work anywhere :)
-     */
-    tmp = inw(io + RING_BUS_CTRL_A);
-    outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A);
-    mdelay(20);
-    outw(tmp, io + RING_BUS_CTRL_A);
-    mdelay(50);
-#endif
-}
-
-static int __devinit m3_codec_install(struct m3_card *card)
-{
-    struct ac97_codec *codec;
-
-    if ((codec = ac97_alloc_codec()) == NULL)
-        return -ENOMEM;
-
-    codec->private_data = card;
-    codec->codec_read = m3_ac97_read;
-    codec->codec_write = m3_ac97_write;
-    /* someday we should support secondary codecs.. */
-    codec->id = 0;
-
-    if (ac97_probe_codec(codec) == 0) {
-        printk(KERN_ERR PFX "codec probe failed\n");
-        ac97_release_codec(codec);
-        return -1;
-    }
-
-    if ((codec->dev_mixer = register_sound_mixer(&m3_mixer_fops, -1)) < 0) {
-        printk(KERN_ERR PFX "couldn't register mixer!\n");
-        ac97_release_codec(codec);
-        return -1;
-    }
-
-    card->ac97 = codec;
-
-    return 0;
-}
-
-
-#define MINISRC_LPF_LEN 10
-static u16 minisrc_lpf[MINISRC_LPF_LEN] = {
-    0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
-    0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
-};
-static void m3_assp_init(struct m3_card *card)
-{
-    int i;
-
-    /* zero kernel data */
-    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-                KDATA_BASE_ADDR + i, 0);
-
-    /* zero mixer data? */
-    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-                KDATA_BASE_ADDR2 + i, 0);
-
-    /* init dma pointer */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-            KDATA_CURRENT_DMA, 
-            KDATA_DMA_XFER0);
-
-    /* write kernel into code memory.. */
-    for(i = 0 ; i < sizeof(assp_kernel_image) / 2; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
-                REV_B_CODE_MEMORY_BEGIN + i, 
-                assp_kernel_image[i]);
-    }
-
-    /*
-     * We only have this one client and we know that 0x400
-     * is free in our kernel's mem map, so lets just
-     * drop it there.  It seems that the minisrc doesn't
-     * need vectors, so we won't bother with them..
-     */
-    for(i = 0 ; i < sizeof(assp_minisrc_image) / 2; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
-                0x400 + i, 
-                assp_minisrc_image[i]);
-    }
-
-    /*
-     * write the coefficients for the low pass filter?
-     */
-    for(i = 0; i < MINISRC_LPF_LEN ; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
-            0x400 + MINISRC_COEF_LOC + i,
-            minisrc_lpf[i]);
-    }
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
-        0x400 + MINISRC_COEF_LOC + MINISRC_LPF_LEN,
-        0x8000);
-
-    /*
-     * the minisrc is the only thing on
-     * our task list..
-     */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-            KDATA_TASK0, 
-            0x400);
-
-    /*
-     * init the mixer number..
-     */
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER,0);
-
-    /*
-     * EXTREME KERNEL MASTER VOLUME
-     */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_DAC_LEFT_VOLUME, ARB_VOLUME);
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME);
-
-    card->mixer_list.mem_addr = KDATA_MIXER_XFER0;
-    card->mixer_list.max = MAX_VIRTUAL_MIXER_CHANNELS;
-    card->adc1_list.mem_addr = KDATA_ADC1_XFER0;
-    card->adc1_list.max = MAX_VIRTUAL_ADC1_CHANNELS;
-    card->dma_list.mem_addr = KDATA_DMA_XFER0;
-    card->dma_list.max = MAX_VIRTUAL_DMA_CHANNELS;
-    card->msrc_list.mem_addr = KDATA_INSTANCE0_MINISRC;
-    card->msrc_list.max = MAX_INSTANCE_MINISRC;
-}
-
-static int setup_msrc(struct m3_card *card,
-        struct assp_instance *inst, int index)
-{
-    int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 + 
-            MINISRC_IN_BUFFER_SIZE / 2 +
-            1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1 );
-    int address, i;
-
-    /*
-     * the revb memory map has 0x1100 through 0x1c00
-     * free.  
-     */
-
-    /*
-     * align instance address to 256 bytes so that it's
-     * shifted list address is aligned.  
-     * list address = (mem address >> 1) >> 7;
-     */
-    data_bytes = (data_bytes + 255) & ~255;
-    address = 0x1100 + ((data_bytes/2) * index);
-
-    if((address + (data_bytes/2)) >= 0x1c00) {
-        printk(KERN_ERR PFX "no memory for %d bytes at ind %d (addr 0x%x)\n",
-                data_bytes, index, address);
-        return -1;
-    }
-
-    for(i = 0; i < data_bytes/2 ; i++) 
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-                address + i, 0);
-
-    inst->code = 0x400;
-    inst->data = address;
-
-    return 0;
-}
-
-static int m3_assp_client_init(struct m3_state *s)
-{
-    setup_msrc(s->card, &(s->dac_inst), s->index * 2);
-    setup_msrc(s->card, &(s->adc_inst), (s->index * 2) + 1);
-
-    return 0;
-}
-
-static void m3_amp_enable(struct m3_card *card, int enable)
-{
-    /* 
-     * this works for the reference board, have to find
-     * out about others
-     *
-     * this needs more magic for 4 speaker, but..
-     */
-    int io = card->iobase;
-    u16 gpo, polarity_port, polarity;
-
-    if(!external_amp)
-        return;
-
-    if (gpio_pin >= 0  && gpio_pin <= 15) {
-        polarity_port = 0x1000 + (0x100 * gpio_pin);
-    } else {
-        switch (card->card_type) {
-            case ESS_ALLEGRO:
-                polarity_port = 0x1800;
-                break;
-            default:
-                polarity_port = 0x1100;
-                /* Panasonic toughbook CF72 has to be different... */
-                if(card->pcidev->subsystem_vendor == 0x10F7 && card->pcidev->subsystem_device == 0x833D)
-                	polarity_port = 0x1D00;
-                break;
-        }
-    }
-
-    gpo = (polarity_port >> 8) & 0x0F;
-    polarity = polarity_port >> 12;
-    if ( enable )
-        polarity = !polarity;
-    polarity = polarity << gpo;
-    gpo = 1 << gpo;
-
-    outw(~gpo , io + GPIO_MASK);
-
-    outw( inw(io + GPIO_DIRECTION) | gpo ,
-            io + GPIO_DIRECTION);
-
-    outw( (GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity) ,
-            io + GPIO_DATA);
-
-    outw(0xffff , io + GPIO_MASK);
-}
-
-static int
-maestro_config(struct m3_card *card) 
-{
-    struct pci_dev *pcidev = card->pcidev;
-    u32 n;
-    u8  t; /* makes as much sense as 'n', no? */
-
-    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
-    n &= REDUCED_DEBOUNCE;
-    n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
-    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
-    outb(RESET_ASSP, card->iobase + ASSP_CONTROL_B);
-    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
-    n &= ~INT_CLK_SELECT;
-    if(card->card_type >= ESS_MAESTRO3)  {
-        n &= ~INT_CLK_MULT_ENABLE; 
-        n |= INT_CLK_SRC_NOT_PCI;
-    }
-    n &=  ~( CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2 );
-    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
-    if(card->card_type <= ESS_ALLEGRO) {
-        pci_read_config_dword(pcidev, PCI_USER_CONFIG, &n);
-        n |= IN_CLK_12MHZ_SELECT;
-        pci_write_config_dword(pcidev, PCI_USER_CONFIG, n);
-    }
-
-    t = inb(card->iobase + ASSP_CONTROL_A);
-    t &= ~( DSP_CLK_36MHZ_SELECT  | ASSP_CLK_49MHZ_SELECT);
-    t |= ASSP_CLK_49MHZ_SELECT;
-    t |= ASSP_0_WS_ENABLE; 
-    outb(t, card->iobase + ASSP_CONTROL_A);
-
-    outb(RUN_ASSP, card->iobase + ASSP_CONTROL_B); 
-
-    return 0;
-} 
-
-static void m3_enable_ints(struct m3_card *card)
-{
-    unsigned long io = card->iobase;
-
-    outw(ASSP_INT_ENABLE, io + HOST_INT_CTRL);
-    outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
-            io + ASSP_CONTROL_C);
-}
-
-static struct file_operations m3_audio_fops = {
-	.owner	 = THIS_MODULE,
-	.llseek	 = no_llseek,
-	.read	 = m3_read,
-	.write	 = m3_write,
-	.poll	 = m3_poll,
-	.ioctl	 = m3_ioctl,
-	.mmap	 = m3_mmap,
-	.open	 = m3_open,
-	.release = m3_release,
-};
-
-#ifdef CONFIG_PM
-static int alloc_dsp_suspendmem(struct m3_card *card)
-{
-    int len = sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
-
-    if( (card->suspend_mem = vmalloc(len)) == NULL)
-        return 1;
-
-    return 0;
-}
-
-#else
-#define alloc_dsp_suspendmem(args...) 0
-#endif
-
-/*
- * great day!  this function is ugly as hell.
- */
-static int __devinit m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
-{
-    u32 n;
-    int i;
-    struct m3_card *card = NULL;
-    int ret = 0;
-    int card_type = pci_id->driver_data;
-
-    DPRINTK(DPMOD, "in maestro_install\n");
-
-    if (pci_enable_device(pci_dev))
-        return -EIO;
-
-    if (pci_set_dma_mask(pci_dev, M3_PCI_DMA_MASK)) {
-        printk(KERN_ERR PFX "architecture does not support limiting to 28bit PCI bus addresses\n");
-        return -ENODEV;
-    }
-        
-    pci_set_master(pci_dev);
-
-    if( (card = kmalloc(sizeof(struct m3_card), GFP_KERNEL)) == NULL) {
-        printk(KERN_WARNING PFX "out of memory\n");
-        return -ENOMEM;
-    }
-    memset(card, 0, sizeof(struct m3_card));
-    card->pcidev = pci_dev;
-    init_waitqueue_head(&card->suspend_queue);
-
-    if ( ! request_region(pci_resource_start(pci_dev, 0),
-                pci_resource_len (pci_dev, 0), M3_MODULE_NAME)) {
-
-        printk(KERN_WARNING PFX "unable to reserve I/O space.\n");
-        ret = -EBUSY;
-        goto out;
-    }
-
-    card->iobase = pci_resource_start(pci_dev, 0);
-
-    if(alloc_dsp_suspendmem(card)) {
-        printk(KERN_WARNING PFX "couldn't alloc %d bytes for saving dsp state on suspend\n",
-                REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
-        ret = -ENOMEM;
-        goto out;
-    }
-
-    card->card_type = card_type;
-    card->irq = pci_dev->irq;
-    card->next = devs;
-    card->magic = M3_CARD_MAGIC;
-    spin_lock_init(&card->lock);
-    spin_lock_init(&card->ac97_lock);
-    devs = card;
-    for(i = 0; i<NR_DSPS; i++) {
-        struct m3_state *s = &(card->channels[i]);
-        s->dev_audio = -1;
-    }
-
-    printk(KERN_INFO PFX "Configuring ESS %s found at IO 0x%04X IRQ %d\n", 
-        card_names[card->card_type], card->iobase, card->irq);
-
-    pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &n);
-    printk(KERN_INFO PFX " subvendor id: 0x%08x\n",n); 
-
-    maestro_config(card);
-    m3_assp_halt(card);
-
-    m3_codec_reset(card, 0);
-
-    if(m3_codec_install(card))  {
-        ret = -EIO; 
-        goto out;
-    }
-
-    m3_assp_init(card);
-    m3_amp_enable(card, 1);
-    
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s=&card->channels[i];
-
-        s->index = i;
-
-        s->card = card;
-        init_waitqueue_head(&s->dma_adc.wait);
-        init_waitqueue_head(&s->dma_dac.wait);
-        init_waitqueue_head(&s->open_wait);
-        mutex_init(&(s->open_mutex));
-        s->magic = M3_STATE_MAGIC;
-
-        m3_assp_client_init(s);
-        
-        if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-            printk(KERN_WARNING PFX "initing a dsp device that is already in use?\n");
-        /* register devices */
-        if ((s->dev_audio = register_sound_dsp(&m3_audio_fops, -1)) < 0) {
-            break;
-        }
-
-        if( allocate_dmabuf(card->pcidev, &(s->dma_adc)) ||
-                allocate_dmabuf(card->pcidev, &(s->dma_dac)))  { 
-            ret = -ENOMEM;
-            goto out;
-        }
-    }
-    
-    if(request_irq(card->irq, m3_interrupt, IRQF_SHARED, card_names[card->card_type], card)) {
-
-        printk(KERN_ERR PFX "unable to allocate irq %d,\n", card->irq);
-
-        ret = -EIO;
-        goto out;
-    }
-
-    pci_set_drvdata(pci_dev, card);
-    
-    m3_enable_ints(card);
-    m3_assp_continue(card);
-
-out:
-    if(ret) {
-        if(card->iobase)
-            release_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-        vfree(card->suspend_mem);
-        if(card->ac97) {
-            unregister_sound_mixer(card->ac97->dev_mixer);
-            kfree(card->ac97);
-        }
-        for(i=0;i<NR_DSPS;i++)
-        {
-            struct m3_state *s = &card->channels[i];
-            if(s->dev_audio != -1)
-                unregister_sound_dsp(s->dev_audio);
-        }
-        kfree(card);
-    }
-
-    return ret; 
-}
-
-static void m3_remove(struct pci_dev *pci_dev)
-{
-    struct m3_card *card;
-
-    unregister_reboot_notifier(&m3_reboot_nb);
-
-    while ((card = devs)) {
-        int i;
-        devs = devs->next;
-    
-        free_irq(card->irq, card);
-        unregister_sound_mixer(card->ac97->dev_mixer);
-        kfree(card->ac97);
-
-        for(i=0;i<NR_DSPS;i++)
-        {
-            struct m3_state *s = &card->channels[i];
-            if(s->dev_audio < 0)
-                continue;
-
-            unregister_sound_dsp(s->dev_audio);
-            free_dmabuf(card->pcidev, &s->dma_adc);
-            free_dmabuf(card->pcidev, &s->dma_dac);
-        }
-
-        release_region(card->iobase, 256);
-        vfree(card->suspend_mem);
-        kfree(card);
-    }
-    devs = NULL;
-}
-
-/*
- * some bioses like the sound chip to be powered down
- * at shutdown.  We're just calling _suspend to
- * achieve that..
- */
-static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf)
-{
-    struct m3_card *card;
-
-    DPRINTK(DPMOD, "notifier suspending all cards\n");
-
-    for(card = devs; card != NULL; card = card->next) {
-        if(!card->in_suspend)
-            m3_suspend(card->pcidev, PMSG_SUSPEND); /* XXX legal? */
-    }
-    return 0;
-}
-
-static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state)
-{
-    unsigned long flags;
-    int i;
-    struct m3_card *card = pci_get_drvdata(pci_dev);
-
-    /* must be a better way.. */
-	spin_lock_irqsave(&card->lock, flags);
-
-    DPRINTK(DPMOD, "pm in dev %p\n",card);
-
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s = &card->channels[i];
-
-        if(s->dev_audio == -1)
-            continue;
-
-        DPRINTK(DPMOD, "stop_adc/dac() device %d\n",i);
-        stop_dac(s);
-        stop_adc(s);
-    }
-
-    mdelay(10); /* give the assp a chance to idle.. */
-
-    m3_assp_halt(card);
-
-    if(card->suspend_mem) {
-        int index = 0;
-
-        DPRINTK(DPMOD, "saving code\n");
-        for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
-            card->suspend_mem[index++] = 
-                m3_assp_read(card, MEMTYPE_INTERNAL_CODE, i);
-        DPRINTK(DPMOD, "saving data\n");
-        for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
-            card->suspend_mem[index++] = 
-                m3_assp_read(card, MEMTYPE_INTERNAL_DATA, i);
-    }
-
-    DPRINTK(DPMOD, "powering down apci regs\n");
-    m3_outw(card, 0xffff, 0x54);
-    m3_outw(card, 0xffff, 0x56);
-
-    card->in_suspend = 1;
-
-    spin_unlock_irqrestore(&card->lock, flags);
-
-    return 0;
-}
-
-static int m3_resume(struct pci_dev *pci_dev)
-{
-    unsigned long flags;
-    int index;
-    int i;
-    struct m3_card *card = pci_get_drvdata(pci_dev);
-
-	spin_lock_irqsave(&card->lock, flags);
-    card->in_suspend = 0;
-
-    DPRINTK(DPMOD, "resuming\n");
-
-    /* first lets just bring everything back. .*/
-
-    DPRINTK(DPMOD, "bringing power back on card 0x%p\n",card);
-    m3_outw(card, 0, 0x54);
-    m3_outw(card, 0, 0x56);
-
-    DPRINTK(DPMOD, "restoring pci configs and reseting codec\n");
-    maestro_config(card);
-    m3_assp_halt(card);
-    m3_codec_reset(card, 1);
-
-    DPRINTK(DPMOD, "restoring dsp code card\n");
-    index = 0;
-    for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, i, 
-            card->suspend_mem[index++]);
-    for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, i, 
-            card->suspend_mem[index++]);
-
-     /* tell the dma engine to restart itself */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-        KDATA_DMA_ACTIVE, 0);
-
-    DPRINTK(DPMOD, "resuming dsp\n");
-    m3_assp_continue(card);
-
-    DPRINTK(DPMOD, "enabling ints\n");
-    m3_enable_ints(card);
-
-    /* bring back the old school flavor */
-    for(i = 0; i < SOUND_MIXER_NRDEVICES ; i++) {
-        int state = card->ac97->mixer_state[i];
-        if (!supported_mixer(card->ac97, i)) 
-                continue;
-
-        card->ac97->write_mixer(card->ac97, i, 
-                state & 0xff, (state >> 8) & 0xff);
-    }
-
-    m3_amp_enable(card, 1);
-
-    /* 
-     * now we flip on the music 
-     */
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s = &card->channels[i];
-        if(s->dev_audio == -1)
-            continue;
-        /*
-         * db->ready makes it so these guys can be
-         * called unconditionally..
-         */
-        DPRINTK(DPMOD, "turning on dacs ind %d\n",i);
-        start_dac(s);    
-        start_adc(s);    
-    }
-
-    spin_unlock_irqrestore(&card->lock, flags);
-
-    /* 
-     * all right, we think things are ready, 
-     * wake up people who were using the device 
-     * when we suspended
-     */
-    wake_up(&card->suspend_queue);
-
-    return 0;
-}
-
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>");
-MODULE_DESCRIPTION("ESS Maestro3/Allegro Driver");
-MODULE_LICENSE("GPL");
-
-#ifdef M_DEBUG
-module_param(debug, int, 0);
-#endif
-module_param(external_amp, int, 0);
-module_param(gpio_pin, int, 0);
-
-static struct pci_driver m3_pci_driver = {
-	.name	  = "ess_m3_audio",
-	.id_table = m3_id_table,
-	.probe	  = m3_probe,
-	.remove	  = m3_remove,
-	.suspend  = m3_suspend,
-	.resume	  = m3_resume,
-};
-
-static int __init m3_init_module(void)
-{
-    printk(KERN_INFO PFX "version " DRIVER_VERSION " built at " __TIME__ " " __DATE__ "\n");
-
-    if (register_reboot_notifier(&m3_reboot_nb)) {
-        printk(KERN_WARNING PFX "reboot notifier registration failed\n");
-        return -ENODEV; /* ? */
-    }
-
-    if (pci_register_driver(&m3_pci_driver)) {
-        unregister_reboot_notifier(&m3_reboot_nb);
-        return -ENODEV;
-    }
-    return 0;
-}
-
-static void __exit m3_cleanup_module(void)
-{
-    pci_unregister_driver(&m3_pci_driver);
-}
-
-module_init(m3_init_module);
-module_exit(m3_cleanup_module);
-
-void check_suspend(struct m3_card *card)
-{
-    DECLARE_WAITQUEUE(wait, current);
-
-    if(!card->in_suspend) 
-        return;
-
-    card->in_suspend++;
-    add_wait_queue(&card->suspend_queue, &wait);
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule();
-    remove_wait_queue(&card->suspend_queue, &wait);
-    set_current_state(TASK_RUNNING);
-}
diff --git a/sound/oss/maestro3.h b/sound/oss/maestro3.h
deleted file mode 100644
index dde2986..0000000
--- a/sound/oss/maestro3.h
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- *      ESS Technology allegro audio driver.
- *
- *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *      Hacked for the maestro3 driver by zab
- */
-
-// Allegro PCI configuration registers
-#define PCI_LEGACY_AUDIO_CTRL   0x40
-#define SOUND_BLASTER_ENABLE    0x00000001
-#define FM_SYNTHESIS_ENABLE     0x00000002
-#define GAME_PORT_ENABLE        0x00000004
-#define MPU401_IO_ENABLE        0x00000008
-#define MPU401_IRQ_ENABLE       0x00000010
-#define ALIAS_10BIT_IO          0x00000020
-#define SB_DMA_MASK             0x000000C0
-#define SB_DMA_0                0x00000040
-#define SB_DMA_1                0x00000040
-#define SB_DMA_R                0x00000080
-#define SB_DMA_3                0x000000C0
-#define SB_IRQ_MASK             0x00000700
-#define SB_IRQ_5                0x00000000
-#define SB_IRQ_7                0x00000100
-#define SB_IRQ_9                0x00000200
-#define SB_IRQ_10               0x00000300
-#define MIDI_IRQ_MASK           0x00003800
-#define SERIAL_IRQ_ENABLE       0x00004000
-#define DISABLE_LEGACY          0x00008000
-
-#define PCI_ALLEGRO_CONFIG      0x50
-#define SB_ADDR_240             0x00000004
-#define MPU_ADDR_MASK           0x00000018
-#define MPU_ADDR_330            0x00000000
-#define MPU_ADDR_300            0x00000008
-#define MPU_ADDR_320            0x00000010
-#define MPU_ADDR_340            0x00000018
-#define USE_PCI_TIMING          0x00000040
-#define POSTED_WRITE_ENABLE     0x00000080
-#define DMA_POLICY_MASK         0x00000700
-#define DMA_DDMA                0x00000000
-#define DMA_TDMA                0x00000100
-#define DMA_PCPCI               0x00000200
-#define DMA_WBDMA16             0x00000400
-#define DMA_WBDMA4              0x00000500
-#define DMA_WBDMA2              0x00000600
-#define DMA_WBDMA1              0x00000700
-#define DMA_SAFE_GUARD          0x00000800
-#define HI_PERF_GP_ENABLE       0x00001000
-#define PIC_SNOOP_MODE_0        0x00002000
-#define PIC_SNOOP_MODE_1        0x00004000
-#define SOUNDBLASTER_IRQ_MASK   0x00008000
-#define RING_IN_ENABLE          0x00010000
-#define SPDIF_TEST_MODE         0x00020000
-#define CLK_MULT_MODE_SELECT_2  0x00040000
-#define EEPROM_WRITE_ENABLE     0x00080000
-#define CODEC_DIR_IN            0x00100000
-#define HV_BUTTON_FROM_GD       0x00200000
-#define REDUCED_DEBOUNCE        0x00400000
-#define HV_CTRL_ENABLE          0x00800000
-#define SPDIF_ENABLE            0x01000000
-#define CLK_DIV_SELECT          0x06000000
-#define CLK_DIV_BY_48           0x00000000
-#define CLK_DIV_BY_49           0x02000000
-#define CLK_DIV_BY_50           0x04000000
-#define CLK_DIV_RESERVED        0x06000000
-#define PM_CTRL_ENABLE          0x08000000
-#define CLK_MULT_MODE_SELECT    0x30000000
-#define CLK_MULT_MODE_SHIFT     28
-#define CLK_MULT_MODE_0         0x00000000
-#define CLK_MULT_MODE_1         0x10000000
-#define CLK_MULT_MODE_2         0x20000000
-#define CLK_MULT_MODE_3         0x30000000
-#define INT_CLK_SELECT          0x40000000
-#define INT_CLK_MULT_RESET      0x80000000
-
-// M3
-#define INT_CLK_SRC_NOT_PCI     0x00100000
-#define INT_CLK_MULT_ENABLE     0x80000000
-
-#define PCI_ACPI_CONTROL        0x54
-#define PCI_ACPI_D0             0x00000000
-#define PCI_ACPI_D1             0xB4F70000
-#define PCI_ACPI_D2             0xB4F7B4F7
-
-#define PCI_USER_CONFIG         0x58
-#define EXT_PCI_MASTER_ENABLE   0x00000001
-#define SPDIF_OUT_SELECT        0x00000002
-#define TEST_PIN_DIR_CTRL       0x00000004
-#define AC97_CODEC_TEST         0x00000020
-#define TRI_STATE_BUFFER        0x00000080
-#define IN_CLK_12MHZ_SELECT     0x00000100
-#define MULTI_FUNC_DISABLE      0x00000200
-#define EXT_MASTER_PAIR_SEL     0x00000400
-#define PCI_MASTER_SUPPORT      0x00000800
-#define STOP_CLOCK_ENABLE       0x00001000
-#define EAPD_DRIVE_ENABLE       0x00002000
-#define REQ_TRI_STATE_ENABLE    0x00004000
-#define REQ_LOW_ENABLE          0x00008000
-#define MIDI_1_ENABLE           0x00010000
-#define MIDI_2_ENABLE           0x00020000
-#define SB_AUDIO_SYNC           0x00040000
-#define HV_CTRL_TEST            0x00100000
-#define SOUNDBLASTER_TEST       0x00400000
-
-#define PCI_USER_CONFIG_C       0x5C
-
-#define PCI_DDMA_CTRL           0x60
-#define DDMA_ENABLE             0x00000001
-
-
-// Allegro registers
-#define HOST_INT_CTRL           0x18
-#define SB_INT_ENABLE           0x0001
-#define MPU401_INT_ENABLE       0x0002
-#define ASSP_INT_ENABLE         0x0010
-#define RING_INT_ENABLE         0x0020
-#define HV_INT_ENABLE           0x0040
-#define CLKRUN_GEN_ENABLE       0x0100
-#define HV_CTRL_TO_PME          0x0400
-#define SOFTWARE_RESET_ENABLE   0x8000
-
-/*
- * should be using the above defines, probably.
- */
-#define REGB_ENABLE_RESET               0x01
-#define REGB_STOP_CLOCK                 0x10
-
-#define HOST_INT_STATUS         0x1A
-#define SB_INT_PENDING          0x01
-#define MPU401_INT_PENDING      0x02
-#define ASSP_INT_PENDING        0x10
-#define RING_INT_PENDING        0x20
-#define HV_INT_PENDING          0x40
-
-#define HARDWARE_VOL_CTRL       0x1B
-#define SHADOW_MIX_REG_VOICE    0x1C
-#define HW_VOL_COUNTER_VOICE    0x1D
-#define SHADOW_MIX_REG_MASTER   0x1E
-#define HW_VOL_COUNTER_MASTER   0x1F
-
-#define CODEC_COMMAND           0x30
-#define CODEC_READ_B            0x80
-
-#define CODEC_STATUS            0x30
-#define CODEC_BUSY_B            0x01
-
-#define CODEC_DATA              0x32
-
-#define RING_BUS_CTRL_A         0x36
-#define RAC_PME_ENABLE          0x0100
-#define RAC_SDFS_ENABLE         0x0200
-#define LAC_PME_ENABLE          0x0400
-#define LAC_SDFS_ENABLE         0x0800
-#define SERIAL_AC_LINK_ENABLE   0x1000
-#define IO_SRAM_ENABLE          0x2000
-#define IIS_INPUT_ENABLE        0x8000
-
-#define RING_BUS_CTRL_B         0x38
-#define SECOND_CODEC_ID_MASK    0x0003
-#define SPDIF_FUNC_ENABLE       0x0010
-#define SECOND_AC_ENABLE        0x0020
-#define SB_MODULE_INTF_ENABLE   0x0040
-#define SSPE_ENABLE             0x0040
-#define M3I_DOCK_ENABLE         0x0080
-
-#define SDO_OUT_DEST_CTRL       0x3A
-#define COMMAND_ADDR_OUT        0x0003
-#define PCM_LR_OUT_LOCAL        0x0000
-#define PCM_LR_OUT_REMOTE       0x0004
-#define PCM_LR_OUT_MUTE         0x0008
-#define PCM_LR_OUT_BOTH         0x000C
-#define LINE1_DAC_OUT_LOCAL     0x0000
-#define LINE1_DAC_OUT_REMOTE    0x0010
-#define LINE1_DAC_OUT_MUTE      0x0020
-#define LINE1_DAC_OUT_BOTH      0x0030
-#define PCM_CLS_OUT_LOCAL       0x0000
-#define PCM_CLS_OUT_REMOTE      0x0040
-#define PCM_CLS_OUT_MUTE        0x0080
-#define PCM_CLS_OUT_BOTH        0x00C0
-#define PCM_RLF_OUT_LOCAL       0x0000
-#define PCM_RLF_OUT_REMOTE      0x0100
-#define PCM_RLF_OUT_MUTE        0x0200
-#define PCM_RLF_OUT_BOTH        0x0300
-#define LINE2_DAC_OUT_LOCAL     0x0000
-#define LINE2_DAC_OUT_REMOTE    0x0400
-#define LINE2_DAC_OUT_MUTE      0x0800
-#define LINE2_DAC_OUT_BOTH      0x0C00
-#define HANDSET_OUT_LOCAL       0x0000
-#define HANDSET_OUT_REMOTE      0x1000
-#define HANDSET_OUT_MUTE        0x2000
-#define HANDSET_OUT_BOTH        0x3000
-#define IO_CTRL_OUT_LOCAL       0x0000
-#define IO_CTRL_OUT_REMOTE      0x4000
-#define IO_CTRL_OUT_MUTE        0x8000
-#define IO_CTRL_OUT_BOTH        0xC000
-
-#define SDO_IN_DEST_CTRL        0x3C
-#define STATUS_ADDR_IN          0x0003
-#define PCM_LR_IN_LOCAL         0x0000
-#define PCM_LR_IN_REMOTE        0x0004
-#define PCM_LR_RESERVED         0x0008
-#define PCM_LR_IN_BOTH          0x000C
-#define LINE1_ADC_IN_LOCAL      0x0000
-#define LINE1_ADC_IN_REMOTE     0x0010
-#define LINE1_ADC_IN_MUTE       0x0020
-#define MIC_ADC_IN_LOCAL        0x0000
-#define MIC_ADC_IN_REMOTE       0x0040
-#define MIC_ADC_IN_MUTE         0x0080
-#define LINE2_DAC_IN_LOCAL      0x0000
-#define LINE2_DAC_IN_REMOTE     0x0400
-#define LINE2_DAC_IN_MUTE       0x0800
-#define HANDSET_IN_LOCAL        0x0000
-#define HANDSET_IN_REMOTE       0x1000
-#define HANDSET_IN_MUTE         0x2000
-#define IO_STATUS_IN_LOCAL      0x0000
-#define IO_STATUS_IN_REMOTE     0x4000
-
-#define SPDIF_IN_CTRL           0x3E
-#define SPDIF_IN_ENABLE         0x0001
-
-#define GPIO_DATA               0x60
-#define GPIO_DATA_MASK          0x0FFF
-#define GPIO_HV_STATUS          0x3000
-#define GPIO_PME_STATUS         0x4000
-
-#define GPIO_MASK               0x64
-#define GPIO_DIRECTION          0x68
-#define GPO_PRIMARY_AC97        0x0001
-#define GPI_LINEOUT_SENSE       0x0004
-#define GPO_SECONDARY_AC97      0x0008
-#define GPI_VOL_DOWN            0x0010
-#define GPI_VOL_UP              0x0020
-#define GPI_IIS_CLK             0x0040
-#define GPI_IIS_LRCLK           0x0080
-#define GPI_IIS_DATA            0x0100
-#define GPI_DOCKING_STATUS      0x0100
-#define GPI_HEADPHONE_SENSE     0x0200
-#define GPO_EXT_AMP_SHUTDOWN    0x1000
-
-// M3
-#define GPO_M3_EXT_AMP_SHUTDN   0x0002
-
-#define ASSP_INDEX_PORT         0x80
-#define ASSP_MEMORY_PORT        0x82
-#define ASSP_DATA_PORT          0x84
-
-#define MPU401_DATA_PORT        0x98
-#define MPU401_STATUS_PORT      0x99
-
-#define CLK_MULT_DATA_PORT      0x9C
-
-#define ASSP_CONTROL_A          0xA2
-#define ASSP_0_WS_ENABLE        0x01
-#define ASSP_CTRL_A_RESERVED1   0x02
-#define ASSP_CTRL_A_RESERVED2   0x04
-#define ASSP_CLK_49MHZ_SELECT   0x08
-#define FAST_PLU_ENABLE         0x10
-#define ASSP_CTRL_A_RESERVED3   0x20
-#define DSP_CLK_36MHZ_SELECT    0x40
-
-#define ASSP_CONTROL_B          0xA4
-#define RESET_ASSP              0x00
-#define RUN_ASSP                0x01
-#define ENABLE_ASSP_CLOCK       0x00
-#define STOP_ASSP_CLOCK         0x10
-#define RESET_TOGGLE            0x40
-
-#define ASSP_CONTROL_C          0xA6
-#define ASSP_HOST_INT_ENABLE    0x01
-#define FM_ADDR_REMAP_DISABLE   0x02
-#define HOST_WRITE_PORT_ENABLE  0x08
-
-#define ASSP_HOST_INT_STATUS    0xAC
-#define DSP2HOST_REQ_PIORECORD  0x01
-#define DSP2HOST_REQ_I2SRATE    0x02
-#define DSP2HOST_REQ_TIMER      0x04
-
-// AC97 registers
-// XXX fix this crap up
-/*#define AC97_RESET              0x00*/
-
-#define AC97_VOL_MUTE_B         0x8000
-#define AC97_VOL_M              0x1F
-#define AC97_LEFT_VOL_S         8
-
-#define AC97_MASTER_VOL         0x02
-#define AC97_LINE_LEVEL_VOL     0x04
-#define AC97_MASTER_MONO_VOL    0x06
-#define AC97_PC_BEEP_VOL        0x0A
-#define AC97_PC_BEEP_VOL_M      0x0F
-#define AC97_SROUND_MASTER_VOL  0x38
-#define AC97_PC_BEEP_VOL_S      1
-
-/*#define AC97_PHONE_VOL          0x0C
-#define AC97_MIC_VOL            0x0E*/
-#define AC97_MIC_20DB_ENABLE    0x40
-
-/*#define AC97_LINEIN_VOL         0x10
-#define AC97_CD_VOL             0x12
-#define AC97_VIDEO_VOL          0x14
-#define AC97_AUX_VOL            0x16*/
-#define AC97_PCM_OUT_VOL        0x18
-/*#define AC97_RECORD_SELECT      0x1A*/
-#define AC97_RECORD_MIC         0x00
-#define AC97_RECORD_CD          0x01
-#define AC97_RECORD_VIDEO       0x02
-#define AC97_RECORD_AUX         0x03
-#define AC97_RECORD_MONO_MUX    0x02
-#define AC97_RECORD_DIGITAL     0x03
-#define AC97_RECORD_LINE        0x04
-#define AC97_RECORD_STEREO      0x05
-#define AC97_RECORD_MONO        0x06
-#define AC97_RECORD_PHONE       0x07
-
-/*#define AC97_RECORD_GAIN        0x1C*/
-#define AC97_RECORD_VOL_M       0x0F
-
-/*#define AC97_GENERAL_PURPOSE    0x20*/
-#define AC97_POWER_DOWN_CTRL    0x26
-#define AC97_ADC_READY          0x0001
-#define AC97_DAC_READY          0x0002
-#define AC97_ANALOG_READY       0x0004
-#define AC97_VREF_ON            0x0008
-#define AC97_PR0                0x0100
-#define AC97_PR1                0x0200
-#define AC97_PR2                0x0400
-#define AC97_PR3                0x0800
-#define AC97_PR4                0x1000
-
-#define AC97_RESERVED1          0x28
-
-#define AC97_VENDOR_TEST        0x5A
-
-#define AC97_CLOCK_DELAY        0x5C
-#define AC97_LINEOUT_MUX_SEL    0x0001
-#define AC97_MONO_MUX_SEL       0x0002
-#define AC97_CLOCK_DELAY_SEL    0x1F
-#define AC97_DAC_CDS_SHIFT      6
-#define AC97_ADC_CDS_SHIFT      11
-
-#define AC97_MULTI_CHANNEL_SEL  0x74
-
-/*#define AC97_VENDOR_ID1         0x7C
-#define AC97_VENDOR_ID2         0x7E*/
-
-/*
- * ASSP control regs
- */
-#define DSP_PORT_TIMER_COUNT    0x06
-
-#define DSP_PORT_MEMORY_INDEX   0x80
-
-#define DSP_PORT_MEMORY_TYPE    0x82
-#define MEMTYPE_INTERNAL_CODE   0x0002
-#define MEMTYPE_INTERNAL_DATA   0x0003
-#define MEMTYPE_MASK            0x0003
-
-#define DSP_PORT_MEMORY_DATA    0x84
-
-#define DSP_PORT_CONTROL_REG_A  0xA2
-#define DSP_PORT_CONTROL_REG_B  0xA4
-#define DSP_PORT_CONTROL_REG_C  0xA6
-
-#define REV_A_CODE_MEMORY_BEGIN         0x0000
-#define REV_A_CODE_MEMORY_END           0x0FFF
-#define REV_A_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_A_CODE_MEMORY_LENGTH        (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
-
-#define REV_B_CODE_MEMORY_BEGIN         0x0000
-#define REV_B_CODE_MEMORY_END           0x0BFF
-#define REV_B_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_B_CODE_MEMORY_LENGTH        (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
-
-#define REV_A_DATA_MEMORY_BEGIN         0x1000
-#define REV_A_DATA_MEMORY_END           0x2FFF
-#define REV_A_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_A_DATA_MEMORY_LENGTH        (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
-
-#define REV_B_DATA_MEMORY_BEGIN         0x1000
-#define REV_B_DATA_MEMORY_END           0x2BFF
-#define REV_B_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_B_DATA_MEMORY_LENGTH        (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
-
-
-#define NUM_UNITS_KERNEL_CODE          16
-#define NUM_UNITS_KERNEL_DATA           2
-
-#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
-#define NUM_UNITS_KERNEL_DATA_WITH_HSP  5
-
-/*
- * Kernel data layout
- */
-
-#define DP_SHIFT_COUNT                  7
-
-#define KDATA_BASE_ADDR                 0x1000
-#define KDATA_BASE_ADDR2                0x1080
-
-#define KDATA_TASK0                     (KDATA_BASE_ADDR + 0x0000)
-#define KDATA_TASK1                     (KDATA_BASE_ADDR + 0x0001)
-#define KDATA_TASK2                     (KDATA_BASE_ADDR + 0x0002)
-#define KDATA_TASK3                     (KDATA_BASE_ADDR + 0x0003)
-#define KDATA_TASK4                     (KDATA_BASE_ADDR + 0x0004)
-#define KDATA_TASK5                     (KDATA_BASE_ADDR + 0x0005)
-#define KDATA_TASK6                     (KDATA_BASE_ADDR + 0x0006)
-#define KDATA_TASK7                     (KDATA_BASE_ADDR + 0x0007)
-#define KDATA_TASK_ENDMARK              (KDATA_BASE_ADDR + 0x0008)
-
-#define KDATA_CURRENT_TASK              (KDATA_BASE_ADDR + 0x0009)
-#define KDATA_TASK_SWITCH               (KDATA_BASE_ADDR + 0x000A)
-
-#define KDATA_INSTANCE0_POS3D           (KDATA_BASE_ADDR + 0x000B)
-#define KDATA_INSTANCE1_POS3D           (KDATA_BASE_ADDR + 0x000C)
-#define KDATA_INSTANCE2_POS3D           (KDATA_BASE_ADDR + 0x000D)
-#define KDATA_INSTANCE3_POS3D           (KDATA_BASE_ADDR + 0x000E)
-#define KDATA_INSTANCE4_POS3D           (KDATA_BASE_ADDR + 0x000F)
-#define KDATA_INSTANCE5_POS3D           (KDATA_BASE_ADDR + 0x0010)
-#define KDATA_INSTANCE6_POS3D           (KDATA_BASE_ADDR + 0x0011)
-#define KDATA_INSTANCE7_POS3D           (KDATA_BASE_ADDR + 0x0012)
-#define KDATA_INSTANCE8_POS3D           (KDATA_BASE_ADDR + 0x0013)
-#define KDATA_INSTANCE_POS3D_ENDMARK    (KDATA_BASE_ADDR + 0x0014)
-
-#define KDATA_INSTANCE0_SPKVIRT         (KDATA_BASE_ADDR + 0x0015)
-#define KDATA_INSTANCE_SPKVIRT_ENDMARK  (KDATA_BASE_ADDR + 0x0016)
-
-#define KDATA_INSTANCE0_SPDIF           (KDATA_BASE_ADDR + 0x0017)
-#define KDATA_INSTANCE_SPDIF_ENDMARK    (KDATA_BASE_ADDR + 0x0018)
-
-#define KDATA_INSTANCE0_MODEM           (KDATA_BASE_ADDR + 0x0019)
-#define KDATA_INSTANCE_MODEM_ENDMARK    (KDATA_BASE_ADDR + 0x001A)
-
-#define KDATA_INSTANCE0_SRC             (KDATA_BASE_ADDR + 0x001B)
-#define KDATA_INSTANCE1_SRC             (KDATA_BASE_ADDR + 0x001C)
-#define KDATA_INSTANCE_SRC_ENDMARK      (KDATA_BASE_ADDR + 0x001D)
-
-#define KDATA_INSTANCE0_MINISRC         (KDATA_BASE_ADDR + 0x001E)
-#define KDATA_INSTANCE1_MINISRC         (KDATA_BASE_ADDR + 0x001F)
-#define KDATA_INSTANCE2_MINISRC         (KDATA_BASE_ADDR + 0x0020)
-#define KDATA_INSTANCE3_MINISRC         (KDATA_BASE_ADDR + 0x0021)
-#define KDATA_INSTANCE_MINISRC_ENDMARK  (KDATA_BASE_ADDR + 0x0022)
-
-#define KDATA_INSTANCE0_CPYTHRU         (KDATA_BASE_ADDR + 0x0023)
-#define KDATA_INSTANCE1_CPYTHRU         (KDATA_BASE_ADDR + 0x0024)
-#define KDATA_INSTANCE_CPYTHRU_ENDMARK  (KDATA_BASE_ADDR + 0x0025)
-
-#define KDATA_CURRENT_DMA               (KDATA_BASE_ADDR + 0x0026)
-#define KDATA_DMA_SWITCH                (KDATA_BASE_ADDR + 0x0027)
-#define KDATA_DMA_ACTIVE                (KDATA_BASE_ADDR + 0x0028)
-
-#define KDATA_DMA_XFER0                 (KDATA_BASE_ADDR + 0x0029)
-#define KDATA_DMA_XFER1                 (KDATA_BASE_ADDR + 0x002A)
-#define KDATA_DMA_XFER2                 (KDATA_BASE_ADDR + 0x002B)
-#define KDATA_DMA_XFER3                 (KDATA_BASE_ADDR + 0x002C)
-#define KDATA_DMA_XFER4                 (KDATA_BASE_ADDR + 0x002D)
-#define KDATA_DMA_XFER5                 (KDATA_BASE_ADDR + 0x002E)
-#define KDATA_DMA_XFER6                 (KDATA_BASE_ADDR + 0x002F)
-#define KDATA_DMA_XFER7                 (KDATA_BASE_ADDR + 0x0030)
-#define KDATA_DMA_XFER8                 (KDATA_BASE_ADDR + 0x0031)
-#define KDATA_DMA_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0032)
-
-#define KDATA_I2S_SAMPLE_COUNT          (KDATA_BASE_ADDR + 0x0033)
-#define KDATA_I2S_INT_METER             (KDATA_BASE_ADDR + 0x0034)
-#define KDATA_I2S_ACTIVE                (KDATA_BASE_ADDR + 0x0035)
-
-#define KDATA_TIMER_COUNT_RELOAD        (KDATA_BASE_ADDR + 0x0036)
-#define KDATA_TIMER_COUNT_CURRENT       (KDATA_BASE_ADDR + 0x0037)
-
-#define KDATA_HALT_SYNCH_CLIENT         (KDATA_BASE_ADDR + 0x0038)
-#define KDATA_HALT_SYNCH_DMA            (KDATA_BASE_ADDR + 0x0039)
-#define KDATA_HALT_ACKNOWLEDGE          (KDATA_BASE_ADDR + 0x003A)
-
-#define KDATA_ADC1_XFER0                (KDATA_BASE_ADDR + 0x003B)
-#define KDATA_ADC1_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x003C)
-#define KDATA_ADC1_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x003D)
-#define KDATA_ADC1_RIGHT_VOLUME  		(KDATA_BASE_ADDR + 0x003E)
-#define KDATA_ADC1_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x003F)
-#define KDATA_ADC1_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0040)
-
-#define KDATA_ADC2_XFER0                (KDATA_BASE_ADDR + 0x0041)
-#define KDATA_ADC2_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x0042)
-#define KDATA_ADC2_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0043)
-#define KDATA_ADC2_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x0044)
-#define KDATA_ADC2_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x0045)
-#define KDATA_ADC2_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0046)
-
-#define KDATA_CD_XFER0					(KDATA_BASE_ADDR + 0x0047)					
-#define KDATA_CD_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x0048)
-#define KDATA_CD_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0049)
-#define KDATA_CD_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x004A)
-#define KDATA_CD_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x004B)
-#define KDATA_CD_RIGHT_SUR_VOL			(KDATA_BASE_ADDR + 0x004C)
-
-#define KDATA_MIC_XFER0					(KDATA_BASE_ADDR + 0x004D)
-#define KDATA_MIC_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x004E)
-#define KDATA_MIC_VOLUME				(KDATA_BASE_ADDR + 0x004F)
-#define KDATA_MIC_SUR_VOL				(KDATA_BASE_ADDR + 0x0050)
-
-#define KDATA_I2S_XFER0                 (KDATA_BASE_ADDR + 0x0051)
-#define KDATA_I2S_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0052)
-
-#define KDATA_CHI_XFER0                 (KDATA_BASE_ADDR + 0x0053)
-#define KDATA_CHI_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0054)
-
-#define KDATA_SPDIF_XFER                (KDATA_BASE_ADDR + 0x0055)
-#define KDATA_SPDIF_CURRENT_FRAME       (KDATA_BASE_ADDR + 0x0056)
-#define KDATA_SPDIF_FRAME0              (KDATA_BASE_ADDR + 0x0057)
-#define KDATA_SPDIF_FRAME1              (KDATA_BASE_ADDR + 0x0058)
-#define KDATA_SPDIF_FRAME2              (KDATA_BASE_ADDR + 0x0059)
-
-#define KDATA_SPDIF_REQUEST             (KDATA_BASE_ADDR + 0x005A)
-#define KDATA_SPDIF_TEMP                (KDATA_BASE_ADDR + 0x005B)
-
-#define KDATA_SPDIFIN_XFER0             (KDATA_BASE_ADDR + 0x005C)
-#define KDATA_SPDIFIN_XFER_ENDMARK      (KDATA_BASE_ADDR + 0x005D)
-#define KDATA_SPDIFIN_INT_METER         (KDATA_BASE_ADDR + 0x005E)
-
-#define KDATA_DSP_RESET_COUNT           (KDATA_BASE_ADDR + 0x005F)
-#define KDATA_DEBUG_OUTPUT              (KDATA_BASE_ADDR + 0x0060)
-
-#define KDATA_KERNEL_ISR_LIST           (KDATA_BASE_ADDR + 0x0061)
-
-#define KDATA_KERNEL_ISR_CBSR1          (KDATA_BASE_ADDR + 0x0062)
-#define KDATA_KERNEL_ISR_CBER1          (KDATA_BASE_ADDR + 0x0063)
-#define KDATA_KERNEL_ISR_CBCR           (KDATA_BASE_ADDR + 0x0064)
-#define KDATA_KERNEL_ISR_AR0            (KDATA_BASE_ADDR + 0x0065)
-#define KDATA_KERNEL_ISR_AR1            (KDATA_BASE_ADDR + 0x0066)
-#define KDATA_KERNEL_ISR_AR2            (KDATA_BASE_ADDR + 0x0067)
-#define KDATA_KERNEL_ISR_AR3            (KDATA_BASE_ADDR + 0x0068)
-#define KDATA_KERNEL_ISR_AR4            (KDATA_BASE_ADDR + 0x0069)
-#define KDATA_KERNEL_ISR_AR5            (KDATA_BASE_ADDR + 0x006A)
-#define KDATA_KERNEL_ISR_BRCR           (KDATA_BASE_ADDR + 0x006B)
-#define KDATA_KERNEL_ISR_PASR           (KDATA_BASE_ADDR + 0x006C)
-#define KDATA_KERNEL_ISR_PAER           (KDATA_BASE_ADDR + 0x006D)
-
-#define KDATA_CLIENT_SCRATCH0           (KDATA_BASE_ADDR + 0x006E)
-#define KDATA_CLIENT_SCRATCH1           (KDATA_BASE_ADDR + 0x006F)
-#define KDATA_KERNEL_SCRATCH            (KDATA_BASE_ADDR + 0x0070)
-#define KDATA_KERNEL_ISR_SCRATCH        (KDATA_BASE_ADDR + 0x0071)
-
-#define KDATA_OUEUE_LEFT                (KDATA_BASE_ADDR + 0x0072)
-#define KDATA_QUEUE_RIGHT               (KDATA_BASE_ADDR + 0x0073)
-
-#define KDATA_ADC1_REQUEST              (KDATA_BASE_ADDR + 0x0074)
-#define KDATA_ADC2_REQUEST              (KDATA_BASE_ADDR + 0x0075)
-#define KDATA_CD_REQUEST				(KDATA_BASE_ADDR + 0x0076)
-#define KDATA_MIC_REQUEST				(KDATA_BASE_ADDR + 0x0077)
-
-#define KDATA_ADC1_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0078)
-#define KDATA_ADC2_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0079)
-#define KDATA_CD_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007A)
-#define KDATA_MIC_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007B)
-#define KDATA_MIC_SYNC_COUNTER			(KDATA_BASE_ADDR + 0x007C)
-
-/*
- * second 'segment' (?) reserved for mixer
- * buffers..
- */
-
-#define KDATA_MIXER_WORD0               (KDATA_BASE_ADDR2 + 0x0000)
-#define KDATA_MIXER_WORD1               (KDATA_BASE_ADDR2 + 0x0001)
-#define KDATA_MIXER_WORD2               (KDATA_BASE_ADDR2 + 0x0002)
-#define KDATA_MIXER_WORD3               (KDATA_BASE_ADDR2 + 0x0003)
-#define KDATA_MIXER_WORD4               (KDATA_BASE_ADDR2 + 0x0004)
-#define KDATA_MIXER_WORD5               (KDATA_BASE_ADDR2 + 0x0005)
-#define KDATA_MIXER_WORD6               (KDATA_BASE_ADDR2 + 0x0006)
-#define KDATA_MIXER_WORD7               (KDATA_BASE_ADDR2 + 0x0007)
-#define KDATA_MIXER_WORD8               (KDATA_BASE_ADDR2 + 0x0008)
-#define KDATA_MIXER_WORD9               (KDATA_BASE_ADDR2 + 0x0009)
-#define KDATA_MIXER_WORDA               (KDATA_BASE_ADDR2 + 0x000A)
-#define KDATA_MIXER_WORDB               (KDATA_BASE_ADDR2 + 0x000B)
-#define KDATA_MIXER_WORDC               (KDATA_BASE_ADDR2 + 0x000C)
-#define KDATA_MIXER_WORDD               (KDATA_BASE_ADDR2 + 0x000D)
-#define KDATA_MIXER_WORDE               (KDATA_BASE_ADDR2 + 0x000E)
-#define KDATA_MIXER_WORDF               (KDATA_BASE_ADDR2 + 0x000F)
-
-#define KDATA_MIXER_XFER0               (KDATA_BASE_ADDR2 + 0x0010)
-#define KDATA_MIXER_XFER1               (KDATA_BASE_ADDR2 + 0x0011)
-#define KDATA_MIXER_XFER2               (KDATA_BASE_ADDR2 + 0x0012)
-#define KDATA_MIXER_XFER3               (KDATA_BASE_ADDR2 + 0x0013)
-#define KDATA_MIXER_XFER4               (KDATA_BASE_ADDR2 + 0x0014)
-#define KDATA_MIXER_XFER5               (KDATA_BASE_ADDR2 + 0x0015)
-#define KDATA_MIXER_XFER6               (KDATA_BASE_ADDR2 + 0x0016)
-#define KDATA_MIXER_XFER7               (KDATA_BASE_ADDR2 + 0x0017)
-#define KDATA_MIXER_XFER8               (KDATA_BASE_ADDR2 + 0x0018)
-#define KDATA_MIXER_XFER9               (KDATA_BASE_ADDR2 + 0x0019)
-#define KDATA_MIXER_XFER_ENDMARK        (KDATA_BASE_ADDR2 + 0x001A)
-
-#define KDATA_MIXER_TASK_NUMBER         (KDATA_BASE_ADDR2 + 0x001B)
-#define KDATA_CURRENT_MIXER             (KDATA_BASE_ADDR2 + 0x001C)
-#define KDATA_MIXER_ACTIVE              (KDATA_BASE_ADDR2 + 0x001D)
-#define KDATA_MIXER_BANK_STATUS         (KDATA_BASE_ADDR2 + 0x001E)
-#define KDATA_DAC_LEFT_VOLUME	        (KDATA_BASE_ADDR2 + 0x001F)
-#define KDATA_DAC_RIGHT_VOLUME          (KDATA_BASE_ADDR2 + 0x0020)
-
-#define MAX_INSTANCE_MINISRC            (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
-#define MAX_VIRTUAL_DMA_CHANNELS        (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
-#define MAX_VIRTUAL_MIXER_CHANNELS      (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
-#define MAX_VIRTUAL_ADC1_CHANNELS       (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
-
-/*
- * client data area offsets
- */
-#define CDATA_INSTANCE_READY            0x00
-
-#define CDATA_HOST_SRC_ADDRL            0x01
-#define CDATA_HOST_SRC_ADDRH            0x02
-#define CDATA_HOST_SRC_END_PLUS_1L      0x03
-#define CDATA_HOST_SRC_END_PLUS_1H      0x04
-#define CDATA_HOST_SRC_CURRENTL         0x05
-#define CDATA_HOST_SRC_CURRENTH         0x06
-
-#define CDATA_IN_BUF_CONNECT            0x07
-#define CDATA_OUT_BUF_CONNECT           0x08
-
-#define CDATA_IN_BUF_BEGIN              0x09
-#define CDATA_IN_BUF_END_PLUS_1         0x0A
-#define CDATA_IN_BUF_HEAD               0x0B
-#define CDATA_IN_BUF_TAIL               0x0C
-#define CDATA_OUT_BUF_BEGIN             0x0D
-#define CDATA_OUT_BUF_END_PLUS_1        0x0E
-#define CDATA_OUT_BUF_HEAD              0x0F
-#define CDATA_OUT_BUF_TAIL              0x10
-
-#define CDATA_DMA_CONTROL               0x11
-#define CDATA_RESERVED                  0x12
-
-#define CDATA_FREQUENCY                 0x13
-#define CDATA_LEFT_VOLUME               0x14
-#define CDATA_RIGHT_VOLUME              0x15
-#define CDATA_LEFT_SUR_VOL              0x16
-#define CDATA_RIGHT_SUR_VOL             0x17
-
-#define CDATA_HEADER_LEN                0x18
-
-#define SRC3_DIRECTION_OFFSET           CDATA_HEADER_LEN
-#define SRC3_MODE_OFFSET                (CDATA_HEADER_LEN + 1)
-#define SRC3_WORD_LENGTH_OFFSET         (CDATA_HEADER_LEN + 2)
-#define SRC3_PARAMETER_OFFSET           (CDATA_HEADER_LEN + 3)
-#define SRC3_COEFF_ADDR_OFFSET          (CDATA_HEADER_LEN + 8)
-#define SRC3_FILTAP_ADDR_OFFSET         (CDATA_HEADER_LEN + 10)
-#define SRC3_TEMP_INBUF_ADDR_OFFSET     (CDATA_HEADER_LEN + 16)
-#define SRC3_TEMP_OUTBUF_ADDR_OFFSET    (CDATA_HEADER_LEN + 17)
-
-#define MINISRC_IN_BUFFER_SIZE   ( 0x50 * 2 )
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_TMP_BUFFER_SIZE  ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
-#define MINISRC_BIQUAD_STAGE    2
-#define MINISRC_COEF_LOC          0X175
-
-#define DMACONTROL_BLOCK_MASK           0x000F
-#define  DMAC_BLOCK0_SELECTOR           0x0000
-#define  DMAC_BLOCK1_SELECTOR           0x0001
-#define  DMAC_BLOCK2_SELECTOR           0x0002
-#define  DMAC_BLOCK3_SELECTOR           0x0003
-#define  DMAC_BLOCK4_SELECTOR           0x0004
-#define  DMAC_BLOCK5_SELECTOR           0x0005
-#define  DMAC_BLOCK6_SELECTOR           0x0006
-#define  DMAC_BLOCK7_SELECTOR           0x0007
-#define  DMAC_BLOCK8_SELECTOR           0x0008
-#define  DMAC_BLOCK9_SELECTOR           0x0009
-#define  DMAC_BLOCKA_SELECTOR           0x000A
-#define  DMAC_BLOCKB_SELECTOR           0x000B
-#define  DMAC_BLOCKC_SELECTOR           0x000C
-#define  DMAC_BLOCKD_SELECTOR           0x000D
-#define  DMAC_BLOCKE_SELECTOR           0x000E
-#define  DMAC_BLOCKF_SELECTOR           0x000F
-#define DMACONTROL_PAGE_MASK            0x00F0
-#define  DMAC_PAGE0_SELECTOR            0x0030
-#define  DMAC_PAGE1_SELECTOR            0x0020
-#define  DMAC_PAGE2_SELECTOR            0x0010
-#define  DMAC_PAGE3_SELECTOR            0x0000
-#define DMACONTROL_AUTOREPEAT           0x1000
-#define DMACONTROL_STOPPED              0x2000
-#define DMACONTROL_DIRECTION            0x0100
-
-
-/*
- * DSP Code images
- */
-
-static u16 assp_kernel_image[] = {
-    0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 
-    0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08, 
-    0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909, 
-    0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41, 
-    0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308, 
-    0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910, 
-    0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00, 
-    0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026, 
-    0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0, 
-    0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012, 
-    0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A, 
-    0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000, 
-    0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05, 
-    0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26, 
-    0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300, 
-    0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88, 
-    0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008, 
-    0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71, 
-    0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A, 
-    0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100, 
-    0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900, 
-    0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903, 
-    0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309, 
-    0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B, 
-    0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540, 
-    0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C, 
-    0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380, 
-    0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340, 
-    0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041, 
-    0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18, 
-    0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 
-    0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9, 
-    0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8, 
-    0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A, 
-    0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80, 
-    0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 
-    0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80, 
-    0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A, 
-    0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F, 
-    0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1, 
-    0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034, 
-    0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 
-    0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977, 
-    0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B, 
-    0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388, 
-    0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 
-    0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473, 
-    0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473, 
-    0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880, 
-    0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6, 
-    0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909, 
-    0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED, 
-    0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005, 
-    0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 
-    0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4, 
-    0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 
-    0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10, 
-    0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070, 
-    0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71, 
-    0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A, 
-    0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061, 
-    0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358, 
-    0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6, 
-    0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9, 
-    0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379, 
-    0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6, 
-    0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C, 
-    0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166, 
-    0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B, 
-    0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A, 
-    0xBE3A, 
-};
-
-/*
- * Mini sample rate converter code image
- * that is to be loaded at 0x400 on the DSP.
- */
-static u16 assp_minisrc_image[] = {
-
-    0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 
-    0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 
-    0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907, 
-    0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01, 
-    0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904, 
-    0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D, 
-    0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD, 
-    0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22, 
-    0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0, 
-    0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9, 
-    0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89, 
-    0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0, 
-    0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484, 
-    0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80, 
-    0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624, 
-    0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4, 
-    0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027, 
-    0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903, 
-    0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809, 
-    0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46, 
-    0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47, 
-    0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0, 
-    0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516, 
-    0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E, 
-    0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C, 
-    0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180, 
-    0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E, 
-    0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0, 
-    0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0, 
-    0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0, 
-    0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F, 
-    0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-};
-
diff --git a/sound/oss/maui.c b/sound/oss/maui.c
deleted file mode 100644
index 05cf194..0000000
--- a/sound/oss/maui.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * sound/maui.c
- *
- * The low level driver for Turtle Beach Maui and Tropez.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *	Changes:
- *		Alan Cox		General clean up, use kernel IRQ 
- *					system
- *		Christoph Hellwig	Adapted to module_init/module_exit
- *		Bartlomiej Zolnierkiewicz
- *					Added __init to download_code()
- *
- *	Status:
- *		Andrew J. Kroll		Tested 06/01/1999 with:
- *					* OSWF.MOT File Version: 1.15
- *					* OSWF.MOT File Dated: 09/12/94
- *					* Older versions will cause problems.
- */
-
-#include <linux/interrupt.h>
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#define USE_SEQ_MACROS
-#define USE_SIMPLE_MACROS
-
-#include "sound_config.h"
-#include "sound_firmware.h"
-
-#include "mpu401.h"
-
-static int      maui_base = 0x330;
-
-static volatile int irq_ok;
-static int     *maui_osp;
-
-#define HOST_DATA_PORT	(maui_base + 2)
-#define HOST_STAT_PORT	(maui_base + 3)
-#define HOST_CTRL_PORT	(maui_base + 3)
-
-#define STAT_TX_INTR	0x40
-#define STAT_TX_AVAIL	0x20
-#define STAT_TX_IENA	0x10
-#define STAT_RX_INTR	0x04
-#define STAT_RX_AVAIL	0x02
-#define STAT_RX_IENA	0x01
-
-static int      (*orig_load_patch)(int dev, int format, const char __user *addr,
-			      int offs, int count, int pmgr_flag) = NULL;
-
-#include "maui_boot.h"
-
-static int maui_wait(int mask)
-{
-	int i;
-
-	/*
-	 * Perform a short initial wait without sleeping
-	 */
-
-	for (i = 0; i < 100; i++)
-		if (inb(HOST_STAT_PORT) & mask)
-			return 1;
-
-	/*
-	 * Wait up to 15 seconds with sleeping
-	 */
-
-	for (i = 0; i < 150; i++) {
-		if (inb(HOST_STAT_PORT) & mask)
-			return 1;
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(HZ / 10);
-		if (signal_pending(current))
-			return 0;
-	}
-	return 0;
-}
-
-static int maui_read(void)
-{
-	if (maui_wait(STAT_RX_AVAIL))
-		return inb(HOST_DATA_PORT);
-	return -1;
-}
-
-static int maui_write(unsigned char data)
-{
-	if (maui_wait(STAT_TX_AVAIL)) {
-		outb((data), HOST_DATA_PORT);
-		return 1;
-	}
-	printk(KERN_WARNING "Maui: Write timeout\n");
-	return 0;
-}
-
-static irqreturn_t mauiintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-	irq_ok = 1;
-	return IRQ_HANDLED;
-}
-
-static int __init download_code(void)
-{
-	int i, lines = 0;
-	int eol_seen = 0, done = 0;
-	int skip = 1;
-
-	printk(KERN_INFO "Code download (%d bytes): ", maui_osLen);
-
-	for (i = 0; i < maui_osLen; i++) {
-		if (maui_os[i] != '\r') {
-			if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n'))) {
-				skip = 0;
-
-				if (maui_os[i] == '\n')
-					eol_seen = skip = 1;
-				else if (maui_os[i] == 'S') {
-					if (maui_os[i + 1] == '8')
-						done = 1;
-					if (!maui_write(0xF1))
-						goto failure;
-					if (!maui_write('S'))
-						goto failure;
-				} else {
-					if (!maui_write(maui_os[i]))
-						goto failure;
-				}
-
-				if (eol_seen) {
-					int c = 0;
-					int n;
-
-					eol_seen = 0;
-
-					for (n = 0; n < 2; n++) {
-						if (maui_wait(STAT_RX_AVAIL)) {
-							c = inb(HOST_DATA_PORT);
-							break;
-						}
-					}
-					if (c != 0x80) {
-						printk("Download not acknowledged\n");
-						return 0;
-					}
-					else if (!(lines++ % 10))
-						printk(".");
-
-					if (done) {
-						printk("\n");
-						printk(KERN_INFO "Download complete\n");
-						return 1;
-					}
-				}
-			}
-		}
-	}
-
-failure:
-	printk("\n");
-	printk(KERN_ERR "Download failed!!!\n");
-	return 0;
-}
-
-static int __init maui_init(int irq)
-{
-	unsigned char bits;
-
-	switch (irq) {
-		case 9:
-			bits = 0x00;
-			break;
-		case 5:
-			bits = 0x08;
-			break;
-		case 12:
-			bits = 0x10;
-			break;
-		case 15:
-			bits = 0x18;
-			break;
-
-		default:
-			printk(KERN_ERR "Maui: Invalid IRQ %d\n", irq);
-			return 0;
-	}
-	outb((0x00), HOST_CTRL_PORT);	/* Reset */
-	outb((bits), HOST_DATA_PORT);	/* Set the IRQ bits */
-	outb((bits | 0x80), HOST_DATA_PORT);	/* Set the IRQ bits again? */
-	outb((0x80), HOST_CTRL_PORT);	/* Leave reset */
-	outb((0x80), HOST_CTRL_PORT);	/* Leave reset */
-	outb((0xD0), HOST_CTRL_PORT);	/* Cause interrupt */
-
-#ifdef CONFIG_SMP
-	{
-		int i;
-		for (i = 0; i < 1000000 && !irq_ok; i++)
-			;
-		if (!irq_ok)
-			return 0;
-	}
-#endif
-	outb((0x80), HOST_CTRL_PORT);	/* Leave reset */
-
-	printk(KERN_INFO "Turtle Beach Maui initialization\n");
-
-	if (!download_code())
-		return 0;
-
-	outb((0xE0), HOST_CTRL_PORT);	/* Normal operation */
-
-	/* Select mpu401 mode */
-
-	maui_write(0xf0);
-	maui_write(1);
-	if (maui_read() != 0x80) {
-		maui_write(0xf0);
-		maui_write(1);
-		if (maui_read() != 0x80)
-			printk(KERN_ERR "Maui didn't acknowledge set HW mode command\n");
-	}
-	printk(KERN_INFO "Maui initialized OK\n");
-	return 1;
-}
-
-static int maui_short_wait(int mask) {
-	int i;
-
-	for (i = 0; i < 1000; i++) {
-		if (inb(HOST_STAT_PORT) & mask) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
-static int maui_load_patch(int dev, int format, const char __user *addr,
-		int offs, int count, int pmgr_flag)
-{
-
-	struct sysex_info header;
-	unsigned long left, src_offs;
-	int hdr_size = (unsigned long) &header.data[0] - (unsigned long) &header;
-	int i;
-
-	if (format == SYSEX_PATCH)	/* Handled by midi_synth.c */
-		return orig_load_patch(dev, format, addr, offs, count, pmgr_flag);
-
-	if (format != MAUI_PATCH)
-	{
-		  printk(KERN_WARNING "Maui: Unknown patch format\n");
-	}
-	if (count < hdr_size) {
-/*		  printk("Maui error: Patch header too short\n");*/
-		  return -EINVAL;
-	}
-	count -= hdr_size;
-
-	/*
-	 * Copy the header from user space but ignore the first bytes which have
-	 * been transferred already.
-	 */
-
-	if(copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs))
-		return -EFAULT;
-
-	if (count < header.len) {
-		  printk(KERN_ERR "Maui warning: Host command record too short (%d<%d)\n", count, (int) header.len);
-		  header.len = count;
-	}
-	left = header.len;
-	src_offs = 0;
-
-	for (i = 0; i < left; i++) {
-		unsigned char   data;
-
-		if(get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i])))
-			return -EFAULT;
-		if (i == 0 && !(data & 0x80))
-			return -EINVAL;
-
-		if (maui_write(data) == -1)
-			return -EIO;
-	}
-
-	if ((i = maui_read()) != 0x80) {
-		if (i != -1)
-			printk("Maui: Error status %02x\n", i);
-		return -EIO;
-	}
-	return 0;
-}
-
-static int __init probe_maui(struct address_info *hw_config)
-{
-	struct resource *ports;
-	int this_dev;
-	int i;
-	int tmp1, tmp2, ret;
-
-	ports = request_region(hw_config->io_base, 2, "mpu401");
-	if (!ports)
-		return 0;
-
-	if (!request_region(hw_config->io_base + 2, 6, "Maui"))
-		goto out;
-
-	maui_base = hw_config->io_base;
-	maui_osp = hw_config->osp;
-
-	if (request_irq(hw_config->irq, mauiintr, 0, "Maui", NULL) < 0)
-		goto out2;
-
-	/*
-	 * Initialize the processor if necessary
-	 */
-
-	if (maui_osLen > 0) {
-		if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) ||
-			!maui_write(0x9F) ||	/* Report firmware version */
-			!maui_short_wait(STAT_RX_AVAIL) ||
-			maui_read() == -1 || maui_read() == -1)
-			if (!maui_init(hw_config->irq))
-				goto out3;
-	}
-	if (!maui_write(0xCF))	/* Report hardware version */ {
-		printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
-		goto out3;
-	}
-	if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) {
-		printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
-		goto out3;
-	}
-	if (tmp1 == 0xff || tmp2 == 0xff)
-		goto out3;
-	printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);
-
-	if (!maui_write(0x9F))	/* Report firmware version */
-		goto out3;
-	if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
-		goto out3;
-
-	printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2);
-
-	if (!maui_write(0x85))	/* Report free DRAM */
-		goto out3;
-	tmp1 = 0;
-	for (i = 0; i < 4; i++) {
-		tmp1 |= maui_read() << (7 * i);
-	}
-	printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);
-
-	for (i = 0; i < 1000; i++)
-		if (probe_mpu401(hw_config, ports))
-			break;
-
-	ret = probe_mpu401(hw_config, ports);
-	if (!ret)
-		goto out3;
-
-	conf_printf("Maui", hw_config);
-
-	hw_config->irq *= -1;
-	hw_config->name = "Maui";
-	attach_mpu401(hw_config, THIS_MODULE);
-
-	if (hw_config->slots[1] != -1)	/* The MPU401 driver installed itself */ {
-		struct synth_operations *synth;
-
-		this_dev = hw_config->slots[1];
-
-		/*
-		 * Intercept patch loading calls so that they can be handled
-		 * by the Maui driver.
-		 */
-
-		synth = midi_devs[this_dev]->converter;
-		if (synth != NULL) {
-			synth->id = "MAUI";
-			orig_load_patch = synth->load_patch;
-			synth->load_patch = &maui_load_patch;
-		} else
-			printk(KERN_ERR "Maui: Can't install patch loader\n");
-	}
-	return 1;
-
-out3:
-	free_irq(hw_config->irq, NULL);
-out2:
-	release_region(hw_config->io_base + 2, 6);
-out:
-	release_region(hw_config->io_base, 2);
-	return 0;
-}
-
-static void __exit unload_maui(struct address_info *hw_config)
-{
-	int irq = hw_config->irq;
-	release_region(hw_config->io_base + 2, 6);
-	unload_mpu401(hw_config);
-
-	if (irq < 0)
-		irq = -irq;
-	if (irq > 0)
-		free_irq(irq, NULL);
-}
-
-static int fw_load;
-
-static struct address_info cfg;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-
-/*
- *	Install a Maui card. Needs mpu401 loaded already.
- */
-
-static int __init init_maui(void)
-{
-	printk(KERN_INFO "Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-	cfg.io_base = io;
-	cfg.irq = irq;
-
-	if (cfg.io_base == -1 || cfg.irq == -1) {
-		printk(KERN_INFO "maui: irq and io must be set.\n");
-		return -EINVAL;
-	}
-
-	if (maui_os == NULL) {
-		fw_load = 1;
-		maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os);
-	}
-	if (probe_maui(&cfg) == 0)
-		return -ENODEV;
-
-	return 0;
-}
-
-static void __exit cleanup_maui(void)
-{
-	if (fw_load && maui_os)
-		vfree(maui_os);
-	unload_maui(&cfg);
-}
-
-module_init(init_maui);
-module_exit(cleanup_maui);
-
-#ifndef MODULE
-static int __init setup_maui(char *str)
-{
-        /* io, irq */
-	int ints[3];
-	
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-	
-	io = ints[1];
-	irq = ints[2];
-
-	return 1;
-}
-
-__setup("maui=", setup_maui);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/midi_syms.c b/sound/oss/midi_syms.c
deleted file mode 100644
index 5b146dd..0000000
--- a/sound/oss/midi_syms.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Exported symbols for midi driver.
- */
-
-#include <linux/module.h>
-
-char midi_syms_symbol;
-
-#include "sound_config.h"
-#define _MIDI_SYNTH_C_
-#include "midi_synth.h"
-
-EXPORT_SYMBOL(do_midi_msg);
-EXPORT_SYMBOL(midi_synth_open);
-EXPORT_SYMBOL(midi_synth_close);
-EXPORT_SYMBOL(midi_synth_ioctl);
-EXPORT_SYMBOL(midi_synth_kill_note);
-EXPORT_SYMBOL(midi_synth_start_note);
-EXPORT_SYMBOL(midi_synth_set_instr);
-EXPORT_SYMBOL(midi_synth_reset);
-EXPORT_SYMBOL(midi_synth_hw_control);
-EXPORT_SYMBOL(midi_synth_aftertouch);
-EXPORT_SYMBOL(midi_synth_controller);
-EXPORT_SYMBOL(midi_synth_panning);
-EXPORT_SYMBOL(midi_synth_setup_voice);
-EXPORT_SYMBOL(midi_synth_send_sysex);
-EXPORT_SYMBOL(midi_synth_bender);
-EXPORT_SYMBOL(midi_synth_load_patch);
-EXPORT_SYMBOL(MIDIbuf_avail);
diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c
index 972edc6..9e45098 100644
--- a/sound/oss/midi_synth.c
+++ b/sound/oss/midi_synth.c
@@ -1,5 +1,5 @@
 /*
- * sound/midi_synth.c
+ * sound/oss/midi_synth.c
  *
  * High level midi sequencer manager for dumb MIDI interfaces.
  */
@@ -84,6 +84,7 @@
 		  ;
 	  }
 }
+EXPORT_SYMBOL(do_midi_msg);
 
 static void
 midi_outc(int midi_dev, int data)
@@ -276,6 +277,7 @@
 		return -EINVAL;
 	}
 }
+EXPORT_SYMBOL(midi_synth_ioctl);
 
 int
 midi_synth_kill_note(int dev, int channel, int note, int velocity)
@@ -342,6 +344,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(midi_synth_kill_note);
 
 int
 midi_synth_set_instr(int dev, int channel, int instr_no)
@@ -364,6 +367,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(midi_synth_set_instr);
 
 int
 midi_synth_start_note(int dev, int channel, int note, int velocity)
@@ -405,6 +409,7 @@
 	  }
 	return 0;
 }
+EXPORT_SYMBOL(midi_synth_start_note);
 
 void
 midi_synth_reset(int dev)
@@ -412,6 +417,7 @@
 
 	leave_sysex(dev);
 }
+EXPORT_SYMBOL(midi_synth_reset);
 
 int
 midi_synth_open(int dev, int mode)
@@ -444,6 +450,7 @@
 
 	return 1;
 }
+EXPORT_SYMBOL(midi_synth_open);
 
 void
 midi_synth_close(int dev)
@@ -459,11 +466,13 @@
 
 	midi_devs[orig_dev]->close(orig_dev);
 }
+EXPORT_SYMBOL(midi_synth_close);
 
 void
 midi_synth_hw_control(int dev, unsigned char *event)
 {
 }
+EXPORT_SYMBOL(midi_synth_hw_control);
 
 int
 midi_synth_load_patch(int dev, int format, const char __user *addr,
@@ -542,11 +551,13 @@
 		midi_outc(orig_dev, 0xf7);
 	return 0;
 }
-  
+EXPORT_SYMBOL(midi_synth_load_patch);
+
 void midi_synth_panning(int dev, int channel, int pressure)
 {
 }
-  
+EXPORT_SYMBOL(midi_synth_panning);
+
 void midi_synth_aftertouch(int dev, int channel, int pressure)
 {
 	int             orig_dev = synth_devs[dev]->midi_dev;
@@ -576,6 +587,7 @@
 
 	midi_outc(orig_dev, pressure);
 }
+EXPORT_SYMBOL(midi_synth_aftertouch);
 
 void
 midi_synth_controller(int dev, int channel, int ctrl_num, int value)
@@ -604,6 +616,7 @@
 	midi_outc(orig_dev, ctrl_num);
 	midi_outc(orig_dev, value & 0x7f);
 }
+EXPORT_SYMBOL(midi_synth_controller);
 
 void
 midi_synth_bender(int dev, int channel, int value)
@@ -635,11 +648,13 @@
 	midi_outc(orig_dev, value & 0x7f);
 	midi_outc(orig_dev, (value >> 7) & 0x7f);
 }
+EXPORT_SYMBOL(midi_synth_bender);
 
 void
 midi_synth_setup_voice(int dev, int voice, int channel)
 {
 }
+EXPORT_SYMBOL(midi_synth_setup_voice);
 
 int
 midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
@@ -695,3 +710,5 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(midi_synth_send_sysex);
+
diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c
index 6982556..a40be0c 100644
--- a/sound/oss/midibuf.c
+++ b/sound/oss/midibuf.c
@@ -1,5 +1,5 @@
 /*
- * sound/midibuf.c
+ * sound/oss/midibuf.c
  *
  * Device file manager for /dev/midi#
  */
@@ -414,18 +414,11 @@
 }
 
 
-void MIDIbuf_init(void)
-{
-	/* drag in midi_syms.o */
-	{
-		extern char midi_syms_symbol;
-		midi_syms_symbol = 0;
-	}
-}
-
 int MIDIbuf_avail(int dev)
 {
 	if (midi_in_buf[dev])
 		return DATA_AVAIL (midi_in_buf[dev]);
 	return 0;
 }
+EXPORT_SYMBOL(MIDIbuf_avail);
+
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index 0aac54c..162d07c 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -1,5 +1,5 @@
 /*
- * sound/mpu401.c
+ * sound/oss/mpu401.c
  *
  * The low level driver for Roland MPU-401 compatible Midi cards.
  */
@@ -432,16 +432,7 @@
 	devc->m_busy = 0;
 }
 
-int intchk_mpu401(void *dev_id)
-{
-	struct mpu_config *devc;
-	int dev = (int) dev_id;
-
-	devc = &dev_conf[dev];
-	return input_avail(devc);
-}
-
-irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
 	struct mpu_config *devc;
 	int dev = (int) dev_id;
@@ -1761,8 +1752,6 @@
 EXPORT_SYMBOL(probe_mpu401);
 EXPORT_SYMBOL(attach_mpu401);
 EXPORT_SYMBOL(unload_mpu401);
-EXPORT_SYMBOL(intchk_mpu401);
-EXPORT_SYMBOL(mpuintr);
 
 static struct address_info cfg;
 
diff --git a/sound/oss/mpu401.h b/sound/oss/mpu401.h
index bdc5bde..84c0e95 100644
--- a/sound/oss/mpu401.h
+++ b/sound/oss/mpu401.h
@@ -10,5 +10,3 @@
 int attach_mpu401(struct address_info * hw_config, struct module *owner);
 void unload_mpu401(struct address_info *hw_info);
 
-int intchk_mpu401(void *dev_id);
-irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
index a31734b..4799bc7 100644
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -1,5 +1,5 @@
 /*
- * sound/opl3.c
+ * sound/oss/opl3.c
  *
  * A low level driver for Yamaha YM3812 and OPL-3 -chips
  *
diff --git a/sound/oss/opl3sa.c b/sound/oss/opl3sa.c
deleted file mode 100644
index fe4907c..0000000
--- a/sound/oss/opl3sa.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * sound/opl3sa.c
- *
- * Low level driver for Yamaha YMF701B aka OPL3-SA chip
- * 
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- *	Alan Cox		Modularisation
- *	Christoph Hellwig	Adapted to module_init/module_exit
- *	Arnaldo C. de Melo	got rid of attach_uart401
- *
- * FIXME:
- * 	Check for install of mpu etc is wrong, should check result of the mss stuff
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-
-#undef  SB_OK
-
-#include "sound_config.h"
-
-#include "ad1848.h"
-#include "mpu401.h"
-
-#ifdef SB_OK
-#include "sb.h"
-static int sb_initialized;
-#endif
-
-static DEFINE_SPINLOCK(lock);
-
-static unsigned char opl3sa_read(int addr)
-{
-	unsigned long flags;
-	unsigned char tmp;
-
-	spin_lock_irqsave(&lock,flags);
-	outb((0x1d), 0xf86);	/* password */
-	outb(((unsigned char) addr), 0xf86);	/* address */
-	tmp = inb(0xf87);	/* data */
-	spin_unlock_irqrestore(&lock,flags);
-
-	return tmp;
-}
-
-static void opl3sa_write(int addr, int data)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&lock,flags);
-	outb((0x1d), 0xf86);	/* password */
-	outb(((unsigned char) addr), 0xf86);	/* address */
-	outb(((unsigned char) data), 0xf87);	/* data */
-	spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init opl3sa_detect(void)
-{
-	int tmp;
-
-	if (((tmp = opl3sa_read(0x01)) & 0xc4) != 0x04)
-	{
-		DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01)));
-		/* return 0; */
-	}
-
-	/*
-	 * Check that the password feature has any effect
-	 */
-	
-	if (inb(0xf87) == tmp)
-	{
-		DDB(printk("OPL3-SA detect failed 2 (%x/%x)\n", tmp, inb(0xf87)));
-		return 0;
-	}
-	tmp = (opl3sa_read(0x04) & 0xe0) >> 5;
-
-	if (tmp != 0 && tmp != 1)
-	{
-		DDB(printk("OPL3-SA detect failed 3 (%d)\n", tmp));
-		return 0;
-	}
-	DDB(printk("OPL3-SA mode %x detected\n", tmp));
-
-	opl3sa_write(0x01, 0x00);	/* Disable MSS */
-	opl3sa_write(0x02, 0x00);	/* Disable SB */
-	opl3sa_write(0x03, 0x00);	/* Disable MPU */
-
-	return 1;
-}
-
-/*
- *    Probe and attach routines for the Windows Sound System mode of
- *     OPL3-SA
- */
-
-static int __init probe_opl3sa_wss(struct address_info *hw_config, struct resource *ports)
-{
-	unsigned char tmp = 0x24;	/* WSS enable */
-
-	/*
-	 * Check if the IO port returns valid signature. The original MS Sound
-	 * system returns 0x04 while some cards (OPL3-SA for example)
-	 * return 0x00.
-	 */
-
-	if (!opl3sa_detect())
-	{
-		printk(KERN_ERR "OSS: OPL3-SA chip not found\n");
-		return 0;
-	}
-	
-	switch (hw_config->io_base)
-	{
-		case 0x530:
-			tmp |= 0x00;
-			break;
-		case 0xe80:
-			tmp |= 0x08;
-			break;
-		case 0xf40:
-			tmp |= 0x10;
-			break;
-		case 0x604:
-			tmp |= 0x18;
-			break;
-		default:
-			printk(KERN_ERR "OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base);
-		  return 0;
-	}
-
-	opl3sa_write(0x01, tmp);	/* WSS setup register */
-
-	return probe_ms_sound(hw_config, ports);
-}
-
-static void __init attach_opl3sa_wss(struct address_info *hw_config, struct resource *ports)
-{
-	int nm = num_mixers;
-
-	/* FIXME */
-	attach_ms_sound(hw_config, ports, THIS_MODULE);
-	if (num_mixers > nm)	/* A mixer was installed */
-	{
-		AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
-		AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
-		AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
-	}
-}
-
-
-static int __init probe_opl3sa_mpu(struct address_info *hw_config)
-{
-	unsigned char conf;
-	static signed char irq_bits[] = {
-		-1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4
-	};
-
-	if (hw_config->irq > 10)
-	{
-		printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
-		return 0;
-	}
-	if (irq_bits[hw_config->irq] == -1)
-	{
-		printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
-		return 0;
-	}
-	switch (hw_config->io_base)
-	{
-		case 0x330:
-			conf = 0x00;
-			break;
-		case 0x332:
-			conf = 0x20;
-			break;
-		case 0x334:
-			conf = 0x40;
-			break;
-		case 0x300:
-			conf = 0x60;
-			break;
-		default:
-			return 0;	/* Invalid port */
-	}
-
-	conf |= 0x83;		/* MPU & OPL3 (synth) & game port enable */
-	conf |= irq_bits[hw_config->irq] << 2;
-
-	opl3sa_write(0x03, conf);
-
-	hw_config->name = "OPL3-SA (MPU401)";
-
-	return probe_uart401(hw_config, THIS_MODULE);
-}
-
-static void __exit unload_opl3sa_wss(struct address_info *hw_config)
-{
-	int dma2 = hw_config->dma2;
-
-	if (dma2 == -1)
-		dma2 = hw_config->dma;
-
-	release_region(0xf86, 2);
-	release_region(hw_config->io_base, 4);
-
-	ad1848_unload(hw_config->io_base + 4,
-		      hw_config->irq,
-		      hw_config->dma,
-		      dma2,
-		      0);
-	sound_unload_audiodev(hw_config->slots[0]);
-}
-
-static inline void __exit unload_opl3sa_mpu(struct address_info *hw_config)
-{
-	unload_uart401(hw_config);
-}
-
-#ifdef SB_OK
-static inline void __exit unload_opl3sa_sb(struct address_info *hw_config)
-{
-	sb_dsp_unload(hw_config);
-}
-#endif
-
-static int found_mpu;
-
-static struct address_info cfg;
-static struct address_info cfg_mpu;
-
-static int __initdata io	= -1;
-static int __initdata irq	= -1;
-static int __initdata dma	= -1;
-static int __initdata dma2	= -1;
-static int __initdata mpu_io	= -1;
-static int __initdata mpu_irq	= -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma2, int, 0);
-module_param(mpu_io, int, 0);
-module_param(mpu_irq, int, 0);
-
-static int __init init_opl3sa(void)
-{
-	struct resource *ports;
-	if (io == -1 || irq == -1 || dma == -1) {
-		printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
-		return -EINVAL;
-	}
-
-	cfg.io_base = io;
-	cfg.irq = irq;
-	cfg.dma = dma;
-	cfg.dma2 = dma2;
-	
-	cfg_mpu.io_base = mpu_io;
-	cfg_mpu.irq = mpu_irq;
-
-	ports = request_region(io + 4, 4, "ad1848");
-	if (!ports)
-		return -EBUSY;
-
-	if (!request_region(0xf86, 2, "OPL3-SA"))/* Control port is busy */ {
-		release_region(io + 4, 4);
-		return 0;
-	}
-
-	if (!request_region(io, 4, "WSS config")) {
-		release_region(0x86, 2);
-		release_region(io + 4, 4);
-		return 0;
-	}
-
-	if (probe_opl3sa_wss(&cfg, ports) == 0) {
-		release_region(0xf86, 2);
-		release_region(io, 4);
-		release_region(io + 4, 4);
-		return -ENODEV;
-	}
-
-	found_mpu=probe_opl3sa_mpu(&cfg_mpu);
-
-	attach_opl3sa_wss(&cfg, ports);
-	return 0;
-}
-
-static void __exit cleanup_opl3sa(void)
-{
-	if(found_mpu)
-		unload_opl3sa_mpu(&cfg_mpu);
-	unload_opl3sa_wss(&cfg);
-}
-
-module_init(init_opl3sa);
-module_exit(cleanup_opl3sa);
-
-#ifndef MODULE
-static int __init setup_opl3sa(char *str)
-{
-	/* io, irq, dma, dma2, mpu_io, mpu_irq */
-	int ints[7];
-	
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-	
-	io	= ints[1];
-	irq	= ints[2];
-	dma	= ints[3];
-	dma2	= ints[4];
-	mpu_io	= ints[5];
-	mpu_irq	= ints[6];
-
-	return 1;
-}
-
-__setup("opl3sa=", setup_opl3sa);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
index aec05a2..e20051f 100644
--- a/sound/oss/opl3sa2.c
+++ b/sound/oss/opl3sa2.c
@@ -1,5 +1,5 @@
 /*
- * sound/opl3sa2.c
+ * sound/oss/opl3sa2.c
  *
  * A low level driver for Yamaha OPL3-SA2 and SA3 cards.
  * NOTE: All traces of the name OPL3-SAx have now (December 2000) been
diff --git a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c
index 9766600..4ebb963 100644
--- a/sound/oss/pas2_card.c
+++ b/sound/oss/pas2_card.c
@@ -1,5 +1,5 @@
 /*
- * sound/pas2_card.c
+ * sound/oss/pas2_card.c
  *
  * Detection routine for the Pro Audio Spectrum cards.
  */
diff --git a/sound/oss/pas2_midi.c b/sound/oss/pas2_midi.c
index 79d6a58..1122d10 100644
--- a/sound/oss/pas2_midi.c
+++ b/sound/oss/pas2_midi.c
@@ -1,5 +1,5 @@
 /*
- * sound/pas2_midi.c
+ * sound/oss/pas2_midi.c
  *
  * The low level driver for the PAS Midi Interface.
  */
diff --git a/sound/oss/pas2_mixer.c b/sound/oss/pas2_mixer.c
index 4aade53..a0bcb85 100644
--- a/sound/oss/pas2_mixer.c
+++ b/sound/oss/pas2_mixer.c
@@ -1,6 +1,6 @@
 
 /*
- * sound/pas2_mixer.c
+ * sound/oss/pas2_mixer.c
  *
  * Mixer routines for the Pro Audio Spectrum cards.
  */
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 37ee234..ece428b 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -1,5 +1,5 @@
 /*
- * sound/pss.c
+ * sound/oss/pss.c
  *
  * The low level driver for the Personal Sound System (ECHO ESC614).
  *
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
deleted file mode 100644
index f17d25b..0000000
--- a/sound/oss/rme96xx.c
+++ /dev/null
@@ -1,1857 +0,0 @@
-/* (C) 2000 Guenter Geiger <geiger@debian.org>
-   with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
-   based on es1370.c
-
-
-
-   *  10 Jan 2001: 0.1 initial version
-   *  19 Jan 2001: 0.2 fixed bug in select()
-   *  27 Apr 2001: 0.3 more than one card usable
-   *  11 May 2001: 0.4 fixed for SMP, included into kernel source tree
-   *  17 May 2001: 0.5 draining code didn't work on new cards
-   *  18 May 2001: 0.6 remove synchronize_irq() call 
-   *  17 Jul 2001: 0.7 updated xrmectrl to make it work for newer cards
-   *   2 feb 2002: 0.8 fixed pci device handling, see below for patches from Heiko (Thanks!)
-                       Marcus Meissner <Marcus.Meissner@caldera.de>
-
-		       Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-		       HP20020108 fixed handling of "large" read()
-		       HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
-		       HP20020118 made mixer ioctl and handling of devices>1 more safe
-		       HP20020201 fixed handling of "large" read() properly
-		       added REV 1.5 S/P-DIF receiver support
-		       SNDCTL_DSP_SPEED now returns the actual speed
-   *  10 Aug 2002: added synchronize_irq() again
-
-TODO:
-   - test more than one card --- done
-   - check for pci IOREGION (see es1370) in rme96xx_probe ??
-   - error detection
-   - mmap interface
-   - mixer mmap interface
-   - mixer ioctl
-   - get rid of noise upon first open (why ??)
-   - allow multiple open (at least for read)
-   - allow multiple open for non overlapping regions
-   - recheck the multiple devices part (offsets of different devices, etc)
-   - do decent draining in _release --- done
-   - SMP support
-   - what about using fragstotal>2 for small fragsize? (HP20020118)
-   - add support for AFMT_S32_LE
-*/
-
-#ifndef RMEVERSION
-#define RMEVERSION "0.8"
-#endif
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/sound.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-#include <asm/dma.h>
-#include <asm/page.h>
-
-#include "rme96xx.h"
-
-#define NR_DEVICE 2
-
-static int devices = 1;
-module_param(devices, int, 0);
-MODULE_PARM_DESC(devices, "number of dsp devices allocated by the driver");
-
-
-MODULE_AUTHOR("Guenter Geiger, geiger@debian.org");
-MODULE_DESCRIPTION("RME9652/36 \"Hammerfall\" Driver");
-MODULE_LICENSE("GPL");
-
-
-#ifdef DEBUG
-#define DBG(x) printk("RME_DEBUG:");x
-#define COMM(x) printk("RME_COMM: " x "\n");
-#else
-#define DBG(x) while (0) {}
-#define COMM(x)
-#endif
-
-/*-------------------------------------------------------------------------- 
-                        Preporcessor Macros and Definitions
- --------------------------------------------------------------------------*/
-
-#define RME96xx_MAGIC 0x6473
-
-/* Registers-Space in offsets from base address with 16MByte size */
-
-#define RME96xx_IO_EXTENT     16l*1024l*1024l
-#define RME96xx_CHANNELS_PER_CARD 26
-
-/*                  Write - Register */
-
-/* 0,4,8,12,16,20,24,28 ... hardware init (erasing fifo-pointer intern) */
-#define RME96xx_num_of_init_regs   8
-
-#define RME96xx_init_buffer       (0/4)
-#define RME96xx_play_buffer       (32/4)  /* pointer to 26x64kBit RAM from mainboard */
-#define RME96xx_rec_buffer        (36/4)  /* pointer to 26x64kBit RAM from mainboard */
-#define RME96xx_control_register  (64/4)  /* exact meaning see below */
-#define RME96xx_irq_clear         (96/4)  /* irq acknowledge */
-#define RME96xx_time_code         (100/4) /* if used with alesis adat */
-#define RME96xx_thru_base         (128/4) /* 132...228 Thru for 26 channels */
-#define RME96xx_thru_channels     RME96xx_CHANNELS_PER_CARD
-
-/*                     Read Register */
-
-#define RME96xx_status_register    0     /* meaning see below */
-
-
-
-/* Status Register: */
-/* ------------------------------------------------------------------------ */
-#define RME96xx_IRQ          0x0000001 /* IRQ is High if not reset by RMExx_irq_clear */
-#define RME96xx_lock_2       0x0000002 /* ADAT 3-PLL: 1=locked, 0=unlocked */
-#define RME96xx_lock_1       0x0000004 /* ADAT 2-PLL: 1=locked, 0=unlocked */
-#define RME96xx_lock_0       0x0000008 /* ADAT 1-PLL: 1=locked, 0=unlocked */
-
-#define RME96xx_fs48         0x0000010 /* sample rate 0 ...44.1/88.2,  1 ... 48/96 Khz */
-#define RME96xx_wsel_rd      0x0000020 /* if Word-Clock is used and valid then 1 */
-#define RME96xx_buf_pos1     0x0000040 /* Bit 6..15 : Position of buffer-pointer in 64Bytes-blocks */
-#define RME96xx_buf_pos2     0x0000080 /* resolution +/- 1 64Byte/block (since 64Bytes bursts) */
- 
-#define RME96xx_buf_pos3     0x0000100 /* 10 bits = 1024 values */
-#define RME96xx_buf_pos4     0x0000200 /* if we mask off the first 6 bits, we can take the status */
-#define RME96xx_buf_pos5     0x0000400 /* register as sample counter in the hardware buffer */
-#define RME96xx_buf_pos6     0x0000800 
-
-#define RME96xx_buf_pos7     0x0001000 
-#define RME96xx_buf_pos8     0x0002000 
-#define RME96xx_buf_pos9     0x0004000
-#define RME96xx_buf_pos10    0x0008000 
-
-#define RME96xx_sync_2       0x0010000 /* if ADAT-IN3 synced to system clock */
-#define RME96xx_sync_1       0x0020000 /* if ADAT-IN2 synced to system clock */
-#define RME96xx_sync_0       0x0040000 /* if ADAT-IN1 synced to system clock */
-#define RME96xx_DS_rd        0x0080000 /* 1=Double Speed, 0=Normal Speed */
-
-#define RME96xx_tc_busy      0x0100000 /* 1=time-code copy in progress (960ms) */
-#define RME96xx_tc_out       0x0200000 /* time-code out bit */
-#define RME96xx_F_0          0x0400000 /*  000=64kHz, 100=88.2kHz, 011=96kHz  */
-#define RME96xx_F_1          0x0800000 /*  111=32kHz, 110=44.1kHz, 101=48kHz, */
-
-#define RME96xx_F_2          0x1000000 /*  001=Rev 1.5+ external Crystal Chip */
-#define RME96xx_ERF          0x2000000 /* Error-Flag of SDPIF Receiver (1=No Lock)*/
-#define RME96xx_buffer_id    0x4000000 /* toggles by each interrupt on rec/play */
-#define RME96xx_tc_valid     0x8000000 /* 1 = a signal is detected on time-code input */
-#define RME96xx_SPDIF_READ  0x10000000 /* byte available from Rev 1.5+ SPDIF interface */
-
-/* Status Register Fields */
-
-#define RME96xx_lock            (RME96xx_lock_0|RME96xx_lock_1|RME96xx_lock_2)
-#define RME96xx_sync            (RME96xx_sync_0|RME96xx_sync_1|RME96xx_sync_2)
-#define RME96xx_F               (RME96xx_F_0|RME96xx_F_1|RME96xx_F_2)
-#define rme96xx_decode_spdif_rate(x) ((x)>>22)
-
-/* Bit 6..15 : h/w buffer pointer */
-#define RME96xx_buf_pos          0x000FFC0 
-/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
-   Rev G EEPROMS and Rev 1.5 cards or later.
-*/ 
-#define RME96xx_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME96xx_buf_pos))
-
-
-/* Control-Register: */			    
-/*--------------------------------------------------------------------------------*/
-
-#define RME96xx_start_bit	0x0001 /* start record/play */
-#define RME96xx_latency0	0x0002 /* Buffer size / latency */
-#define RME96xx_latency1	0x0004 /*   buffersize = 512Bytes * 2^n */
-#define RME96xx_latency2	0x0008 /*   0=64samples ... 7=8192samples */
-
-#define RME96xx_Master		0x0010 /* Clock Mode 1=Master, 0=Slave/Auto */
-#define RME96xx_IE		0x0020 /* Interupt Enable */
-#define RME96xx_freq		0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/
-#define RME96xx_freq1		0x0080 /* samplerate 0=32 kHz, 1=other rates ??? (from ALSA, but may be wrong) */
-#define RME96xx_DS              0x0100 /* double speed 0=44.1/48, 1=88.2/96 Khz */
-#define RME96xx_PRO		0x0200 /* SPDIF-OUT 0=consumer, 1=professional */
-#define RME96xx_EMP		0x0400 /* SPDIF-OUT emphasis 0=off, 1=on */
-#define RME96xx_Dolby		0x0800 /* SPDIF-OUT non-audio bit 1=set, 0=unset */
-
-#define RME96xx_opt_out	        0x1000 /* use 1st optical OUT as SPDIF: 1=yes, 0=no */
-#define RME96xx_wsel            0x2000 /* use Wordclock as sync (overwrites master) */
-#define RME96xx_inp_0           0x4000 /* SPDIF-IN 00=optical (ADAT1), */
-#define RME96xx_inp_1           0x8000 /* 01=coaxial (Cinch), 10=internal CDROM */
-
-#define RME96xx_SyncRef0       0x10000 /* preferred sync-source in autosync */
-#define RME96xx_SyncRef1       0x20000 /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
-
-#define RME96xx_SPDIF_RESET    (1<<18) /* Rev 1.5+: h/w SPDIF receiver */
-#define RME96xx_SPDIF_SELECT   (1<<19)
-#define RME96xx_SPDIF_CLOCK    (1<<20)
-#define RME96xx_SPDIF_WRITE    (1<<21)
-#define RME96xx_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
-
-
-#define RME96xx_ctrl_init            (RME96xx_latency0 |\
-                                     RME96xx_Master |\
-                                     RME96xx_inp_1)
-                              
-
-
-/* Control register fields and shortcuts */
-
-#define RME96xx_latency (RME96xx_latency0|RME96xx_latency1|RME96xx_latency2)
-#define RME96xx_inp         (RME96xx_inp_0|RME96xx_inp_1)
-#define RME96xx_SyncRef    (RME96xx_SyncRef0|RME96xx_SyncRef1)
-#define RME96xx_mixer_allowed (RME96xx_Master|RME96xx_PRO|RME96xx_EMP|RME96xx_Dolby|RME96xx_opt_out|RME96xx_wsel|RME96xx_inp|RME96xx_SyncRef|RME96xx_ADAT1_INTERNAL)
-
-/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit1  (??? HP20020201) */
-
-#define RME96xx_SET_LATENCY(x)   (((x)&0x7)<<1)
-#define RME96xx_GET_LATENCY(x)   (((x)>>1)&0x7)
-#define RME96xx_SET_inp(x) (((x)&0x3)<<14)
-#define RME96xx_GET_inp(x)   (((x)>>14)&0x3)
-#define RME96xx_SET_SyncRef(x) (((x)&0x3)<<17)
-#define RME96xx_GET_SyncRef(x)   (((x)>>17)&0x3)
-
-
-/* buffer sizes */
-#define RME96xx_BYTES_PER_SAMPLE  4 /* sizeof(u32) */
-#define RME_16K 16*1024
-
-#define RME96xx_DMA_MAX_SAMPLES  (RME_16K)
-#define RME96xx_DMA_MAX_SIZE     (RME_16K * RME96xx_BYTES_PER_SAMPLE)
-#define RME96xx_DMA_MAX_SIZE_ALL (RME96xx_DMA_MAX_SIZE * RME96xx_CHANNELS_PER_CARD)
-
-#define RME96xx_NUM_OF_FRAGMENTS     2
-#define RME96xx_FRAGMENT_MAX_SIZE    (RME96xx_DMA_MAX_SIZE/2)
-#define RME96xx_FRAGMENT_MAX_SAMPLES (RME96xx_DMA_MAX_SAMPLES/2)
-#define RME96xx_MAX_LATENCY       7   /* 16k samples */
-
-
-#define RME96xx_MAX_DEVS 4 /* we provide some OSS stereodevs */
-#define RME96xx_MASK_DEVS 0x3 /* RME96xx_MAX_DEVS-1 */
-
-#define RME_MESS "rme96xx:"
-/*------------------------------------------------------------------------ 
-                  Types, struct and function declarations 
- ------------------------------------------------------------------------*/
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT RME_MESS" invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-	if (!(s) || (s)->magic != RME96xx_MAGIC) { \
-		printk(invalid_magic);            \
-		return -ENXIO;                    \
-	}                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-
-static struct file_operations rme96xx_audio_fops;
-static struct file_operations rme96xx_mixer_fops;
-static int numcards;
-
-typedef int32_t raw_sample_t;
-
-typedef struct _rme96xx_info {
-
-	/* hardware settings */
-	int magic;
-	struct pci_dev * pcidev; /* pci_dev structure */
-	unsigned long __iomem *iobase;	
-	unsigned int irq;
-
-	/* list of rme96xx devices */
-	struct list_head devs;
-
-	spinlock_t lock;
-
-	u32 *recbuf;             /* memory for rec buffer */
-	u32 *playbuf;            /* memory for play buffer */
-
-	u32 control_register;
-
-	u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
-
-	int hw_rev;             /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
-	char *card_name;	/* hammerfall or hammerfall light names */
-
-	int open_count;         /* unused ???   HP20020201 */
-
-	int rate;
-	int latency;
-	unsigned int fragsize;
-	int started;
-
-	int hwptr; /* can be negativ because of pci burst offset  */
-	unsigned int hwbufid;  /* set by interrupt, buffer which is written/read now */
-	
-	struct dmabuf {
-
-		unsigned int format;
-		int formatshift;
-		int inchannels;       /* number of channels for device */
-		int outchannels;       /* number of channels for device */
-		int mono; /* if true, we play mono on 2 channels */
-		int inoffset; /* which channel is considered the first one */
-         	int outoffset;
-		
-		/* state */
-		int opened;               /* open() made */
-		int started;              /* first write/read */
-		int mmapped;              /* mmap */
-		int open_mode;
-
-		struct _rme96xx_info *s;  
-
-		/* pointer to read/write position in buffer */
-		unsigned readptr;          
-		unsigned writeptr;          
-
-		unsigned error; /* over/underruns cleared on sync again */
-
-		/* waiting and locking */
-		wait_queue_head_t wait;
-		struct mutex  open_mutex;
-		wait_queue_head_t open_wait;
-
-	} dma[RME96xx_MAX_DEVS]; 
-
-	int dspnum[RME96xx_MAX_DEVS];  /* register with sound subsystem */ 
-	int mixer;  /* register with sound subsystem */ 
-} rme96xx_info;
-
-
-/* fiddling with the card (first level hardware control) */
-
-static inline void rme96xx_set_ctrl(rme96xx_info* s,int mask)
-{
-
-	s->control_register|=mask;
-	writel(s->control_register,s->iobase + RME96xx_control_register);
-
-}
-
-static inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask)
-{
-
-	s->control_register&=(~mask);
-	writel(s->control_register,s->iobase + RME96xx_control_register);
-
-}
-
-static inline int rme96xx_get_sample_rate_status(rme96xx_info* s)
-{
-	int val;
-	u32 status;
-	status = readl(s->iobase + RME96xx_status_register);
-	val = (status & RME96xx_fs48) ? 48000 : 44100;
-	if (status & RME96xx_DS_rd)
-		val *= 2;
-	return val;
-}
-
-static inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s)
-{
-	int val;
-	val = (s->control_register & RME96xx_freq) ? 48000 : 44100;
-	if (s->control_register & RME96xx_DS)
-		val *= 2;
-	return val;
-}
-
-
-/* code from ALSA card-rme9652.c for rev 1.5 SPDIF receiver   HP 20020201 */
-
-static void rme96xx_spdif_set_bit (rme96xx_info* s, int mask, int onoff)
-{
-	if (onoff) 
-		s->control_register |= mask;
-	else 
-		s->control_register &= ~mask;
-		
-	writel(s->control_register,s->iobase + RME96xx_control_register);
-}
-
-static void rme96xx_spdif_write_byte (rme96xx_info* s, const int val)
-{
-	long mask;
-	long i;
-
-	for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
-		if (val & mask)
-			rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 1);
-		else 
-			rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 0);
-
-		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
-		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
-	}
-}
-
-static int rme96xx_spdif_read_byte (rme96xx_info* s)
-{
-	long mask;
-	long val;
-	long i;
-
-	val = 0;
-
-	for (i = 0, mask = 0x80;  i < 8; i++, mask >>= 1) {
-		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
-		if (readl(s->iobase + RME96xx_status_register) & RME96xx_SPDIF_READ)
-			val |= mask;
-		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
-	}
-
-	return val;
-}
-
-static void rme96xx_write_spdif_codec (rme96xx_info* s, const int address, const int data)
-{
-	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-	rme96xx_spdif_write_byte (s, 0x20);
-	rme96xx_spdif_write_byte (s, address);
-	rme96xx_spdif_write_byte (s, data);
-	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-}
-
-
-static int rme96xx_spdif_read_codec (rme96xx_info* s, const int address)
-{
-	int ret;
-
-	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-	rme96xx_spdif_write_byte (s, 0x20);
-	rme96xx_spdif_write_byte (s, address);
-	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-
-	rme96xx_spdif_write_byte (s, 0x21);
-	ret = rme96xx_spdif_read_byte (s);
-	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-
-	return ret;
-}
-
-static void rme96xx_initialize_spdif_receiver (rme96xx_info* s)
-{
-	/* XXX what unsets this ? */
-	/* no idea ???   HP 20020201 */
-
-	s->control_register |= RME96xx_SPDIF_RESET;
-
-	rme96xx_write_spdif_codec (s, 4, 0x40);
-	rme96xx_write_spdif_codec (s, 17, 0x13);
-	rme96xx_write_spdif_codec (s, 6, 0x02);
-}
-
-static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate)
-{
-	unsigned int rate_bits;
-
-	*spdifrate = 0x1;
-	if (readl(s->iobase + RME96xx_status_register) & RME96xx_ERF) {
-		return -1;	/* error condition */
-	}
-	
-	if (s->hw_rev == 15) {
-
-		int x, y, ret;
-		
-		x = rme96xx_spdif_read_codec (s, 30);
-
-		if (x != 0) 
-			y = 48000 * 64 / x;
-		else
-			y = 0;
-
-		if      (y > 30400 && y < 33600)  {ret = 32000; *spdifrate = 0x7;}
-		else if (y > 41900 && y < 46000)  {ret = 44100; *spdifrate = 0x6;}
-		else if (y > 46000 && y < 50400)  {ret = 48000; *spdifrate = 0x5;}
-		else if (y > 60800 && y < 67200)  {ret = 64000; *spdifrate = 0x0;}
-		else if (y > 83700 && y < 92000)  {ret = 88200; *spdifrate = 0x4;}
-		else if (y > 92000 && y < 100000) {ret = 96000; *spdifrate = 0x3;}
-		else                              {ret = 0; *spdifrate = 0x1;}
-		return ret;
-	}
-
-	rate_bits = readl(s->iobase + RME96xx_status_register) & RME96xx_F;
-
-	switch (*spdifrate = rme96xx_decode_spdif_rate(rate_bits)) {
-	case 0x7:
-		return 32000;
-		break;
-
-	case 0x6:
-		return 44100;
-		break;
-
-	case 0x5:
-		return 48000;
-		break;
-
-	case 0x4:
-		return 88200;
-		break;
-
-	case 0x3:
-		return 96000;
-		break;
-
-	case 0x0:
-		return 64000;
-		break;
-
-	default:
-		/* was an ALSA warning ...
-		  snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
-		  s->card_name, rate_bits);
-		*/
-		return 0;
-		break;
-	}
-}
-
-/* end of code from ALSA card-rme9652.c */
-
-
-
-/* the hwbuf in the status register seems to have some jitter, to get rid of
-   it, we first only let the numbers grow, to be on the secure side we 
-   subtract a certain amount RME96xx_BURSTBYTES from the resulting number */
-
-/* the function returns the hardware pointer in bytes */
-#define RME96xx_BURSTBYTES -64  /* bytes by which hwptr could be off */
-
-static inline int rme96xx_gethwptr(rme96xx_info* s,int exact)
-{
-	unsigned long flags;
-	if (exact) {
-		unsigned int hwp;
-/* the hwptr seems to be rather unreliable :(, so we don't use it */
-		spin_lock_irqsave(&s->lock,flags);
-		
-		hwp  = readl(s->iobase + RME96xx_status_register) & 0xffc0;
-		s->hwptr = (hwp < s->hwptr) ? s->hwptr : hwp;
-//		s->hwptr = hwp;
-
-		spin_unlock_irqrestore(&s->lock,flags);
-		return (s->hwptr+RME96xx_BURSTBYTES) & ((s->fragsize<<1)-1);
-	}
-	return (s->hwbufid ? s->fragsize : 0);
-}
-
-static inline void rme96xx_setlatency(rme96xx_info* s,int l)
-{
-	s->latency = l;
-	s->fragsize = 1<<(8+l);
-	rme96xx_unset_ctrl(s,RME96xx_latency);
-	rme96xx_set_ctrl(s,RME96xx_SET_LATENCY(l));	
-}
-
-
-static void rme96xx_clearbufs(struct dmabuf* dma)
-{
-	int i,j;
-	unsigned long flags;
-
-	/* clear dmabufs */
-	for(i=0;i<devices;i++) {
-		for (j=0;j<dma->outchannels + dma->mono;j++)
-			memset(&dma->s->playbuf[(dma->outoffset + j)*RME96xx_DMA_MAX_SAMPLES], 
-			       0, RME96xx_DMA_MAX_SIZE);
-	}
-	spin_lock_irqsave(&dma->s->lock,flags);
-	dma->writeptr = 0;
-	dma->readptr = 0;
-	spin_unlock_irqrestore(&dma->s->lock,flags);
-}
-
-static int rme96xx_startcard(rme96xx_info *s,int stop)
-{
-	int i;
-	unsigned long flags;
-
-	COMM       ("startcard");
-	if(s->control_register & RME96xx_IE){
-		/* disable interrupt first */
-		
-		rme96xx_unset_ctrl( s,RME96xx_start_bit );
-		udelay(10);
-		rme96xx_unset_ctrl( s,RME96xx_IE);
-		spin_lock_irqsave(&s->lock,flags); /* timing is critical */
-		s->started = 0;
-		spin_unlock_irqrestore(&s->lock,flags);
-		if (stop) {
-		     COMM("Sound card stopped");
-		     return 1;
-		}
-	}
-	COMM       ("interrupt disabled");
-	/* first initialize all pointers on card */
-	for(i=0;i<RME96xx_num_of_init_regs;i++){
-		writel(0,s->iobase + i);
-		udelay(10); /* ?? */
-	}
-	COMM       ("regs cleaned");
-
-	spin_lock_irqsave(&s->lock,flags); /* timing is critical */
-	udelay(10);
-	s->started = 1;
-	s->hwptr = 0;
-	spin_unlock_irqrestore(&s->lock,flags);
-
-	rme96xx_set_ctrl( s, RME96xx_IE | RME96xx_start_bit);
-
-
-	COMM("Sound card started");
-  
-	return 1;
-}
-
-
-static inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp)
-{
-	int cnt;
-	int  swptr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dma->s->lock,flags); 
-	swptr = dma->writeptr;
-	cnt = (hwp - swptr);
-	
-	if (cnt < 0) {
-	     cnt = ((dma->s->fragsize<<1) - swptr);
-	}
-	spin_unlock_irqrestore(&dma->s->lock,flags);
-	return cnt;
-}
-
-static inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp)
-{
-	int cnt;
-	int  swptr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dma->s->lock,flags); 
-	swptr = dma->readptr;
-	cnt = (hwp - swptr);
-	 
-	if (cnt < 0) {
-		cnt = ((dma->s->fragsize<<1) - swptr);
-	}
-	spin_unlock_irqrestore(&dma->s->lock,flags);
-	return cnt;
-}
-
-
-static inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop)
-{
-	int swptr = dma->writeptr;
-	switch (dma->format) {
-	case AFMT_S32_BLOCKED:
-	{
-	     char __user * buf = (char __user *)buffer;
-	     int cnt = count/dma->outchannels;
-	     int i;
-	     for (i=0;i < dma->outchannels;i++) {
-		  char* hwbuf =(char*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES];
-		  hwbuf+=swptr;
-
-		  if (copy_from_user(hwbuf,buf, cnt))
-		       return -1;
-		  buf+=hop;
-	     }
-	     swptr+=cnt;
-	     break;
-	}
-	case AFMT_S16_LE:
-	{
-	     int i,j;
-	     int cnt = count/dma->outchannels;
-	     for (i=0;i < dma->outchannels + dma->mono;i++) {
-		     short __user * sbuf = (short __user *)buffer + i*(!dma->mono);
-		     short* hwbuf =(short*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES];	     
-		     hwbuf+=(swptr>>1);
-		     for (j=0;j<(cnt>>1);j++) {
-			     hwbuf++; /* skip the low 16 bits */
-			     __get_user(*hwbuf++,sbuf++);
-			     sbuf+=(dma->outchannels-1);
-		     }
-	     }
-	     swptr += (cnt<<1);
-	     break;
-	}
-	default:
-	     printk(RME_MESS" unsupported format\n");
-	     return -1;
-	} /* switch */
-
-	swptr&=((dma->s->fragsize<<1) -1);
-	dma->writeptr = swptr;
-
-	return 0;
-}
-
-/* The count argument is the number of bytes */
-static inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop)
-{
-	int swptr = dma->readptr;
-	switch (dma->format) {
-	case AFMT_S32_BLOCKED:
-	{
-	     char __user * buf = (char __user *)buffer;
-	     int cnt = count/dma->inchannels;
-	     int i;
-
-	     for (i=0;i < dma->inchannels;i++) {
-		  char* hwbuf =(char*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES];
-		  hwbuf+=swptr;
-
-		  if (copy_to_user(buf,hwbuf,cnt))
-		       return -1;
-		  buf+=hop;
-	     }
-	     swptr+=cnt;
-	     break;
-	}
-	case AFMT_S16_LE:
-	{
-	     int i,j;
-	     int cnt = count/dma->inchannels;
-	     for (i=0;i < dma->inchannels;i++) {
-		  short __user * sbuf = (short __user *)buffer + i;
-		  short* hwbuf =(short*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES];	     
-		  hwbuf+=(swptr>>1);
-		  for (j=0;j<(cnt>>1);j++) {
-		       hwbuf++;
-		       __put_user(*hwbuf++,sbuf++);
-		       sbuf+=(dma->inchannels-1);
-		  }
-	     }
-	     swptr += (cnt<<1);
-	     break;
-	}
-	default:
-	     printk(RME_MESS" unsupported format\n");
-	     return -1;
-	} /* switch */
-	
-	swptr&=((dma->s->fragsize<<1) -1);	
-	dma->readptr = swptr;
-	return 0;
-}
-
-
-static irqreturn_t rme96xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	int i;
-	rme96xx_info *s = (rme96xx_info *)dev_id;
-	struct dmabuf *db;
-	u32 status;
-	unsigned long flags;
-
-	status = readl(s->iobase + RME96xx_status_register);
-	if (!(status & RME96xx_IRQ)) {
-		return IRQ_NONE;
-	}
-
-	spin_lock_irqsave(&s->lock,flags);
-	writel(0,s->iobase + RME96xx_irq_clear);
-
-	s->hwbufid = (status & RME96xx_buffer_id)>>26;	
-	if ((status & 0xffc0) <= 256) s->hwptr = 0; 
-	for(i=0;i<devices;i++)
-	{
-		db = &(s->dma[i]);
-		if(db->started > 0)
-			wake_up(&(db->wait));		
-	}  
-	spin_unlock_irqrestore(&s->lock,flags);
-	return IRQ_HANDLED;
-}
-
-
-
-/*---------------------------------------------------------------------------- 
- PCI detection and module initialization stuff 
- ----------------------------------------------------------------------------*/
-
-static void* busmaster_malloc(int size) {
-     int pg; /* 2 s exponent of memory size */
-        char *buf;
-
-        DBG(printk("kernel malloc pages ..\n"));
-        
-        for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-
-        buf = (char *) __get_free_pages(GFP_KERNEL | GFP_DMA, pg);
-
-        if (buf) {
-                struct page* page, *last_page;
-
-                page = virt_to_page(buf);
-                last_page = page + (1 << pg);
-                DBG(printk("setting reserved bit\n"));
-                while (page < last_page) {
-			SetPageReserved(page);
-                        page++;
-                }
-		return buf;
-        }
-	DBG(printk("allocated %ld",(long)buf));
-	return NULL;
-}
-
-static void busmaster_free(void* ptr,int size) {
-        int pg;
-	struct page* page, *last_page;
-
-        if (ptr == NULL)
-                return;
-
-        for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-
-        page = virt_to_page(ptr);
-        last_page = page + (1 << pg);
-        while (page < last_page) {
-		ClearPageReserved(page);
-		page++;
-	}
-	DBG(printk("freeing pages\n"));
-        free_pages((unsigned long) ptr, pg);
-	DBG(printk("done\n"));
-}
-
-/* initialize those parts of the info structure which are not pci detectable resources */
-
-static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,int ooffset) {
-
-	mutex_init(&dma->open_mutex);
-	init_waitqueue_head(&dma->open_wait);
-	init_waitqueue_head(&dma->wait);
-	dma->s = s; 
-	dma->error = 0;
-
-	dma->format = AFMT_S32_BLOCKED;
-	dma->formatshift = 0;
-	dma->inchannels = dma->outchannels = 1;
-	dma->inoffset = ioffset;
-	dma->outoffset = ooffset;
-
-	dma->opened=0;
-	dma->started=0;
-	dma->mmapped=0;
-	dma->open_mode=0;
-	dma->mono=0;
-
-	rme96xx_clearbufs(dma);
-	return 0;
-}
-
-
-static int rme96xx_init(rme96xx_info* s)
-{
-	int i;
-	int status;
-	unsigned short rev;
-
-	DBG(printk("%s\n", __FUNCTION__));
-	numcards++;
-
-	s->magic = RME96xx_MAGIC; 
-
-	spin_lock_init(&s->lock);
-
-	COMM            ("setup busmaster memory")
-	s->recbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL);
-	s->playbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL);
-
-	if (!s->recbuf || !s->playbuf) {
-		printk(KERN_ERR RME_MESS" Unable to allocate busmaster memory\n");
-		return -ENODEV;
-	}
-
-	COMM            ("setting rec and playbuffers")
-
-	writel((u32) virt_to_bus(s->recbuf),s->iobase + RME96xx_rec_buffer);
-  	writel((u32) virt_to_bus(s->playbuf),s->iobase + RME96xx_play_buffer);
-
-	COMM             ("initializing control register")
-	rme96xx_unset_ctrl(s,0xffffffff);
-	rme96xx_set_ctrl(s,RME96xx_ctrl_init);
-
-
-	COMM              ("setup devices")	
-	for (i=0;i < devices;i++) {
-		struct dmabuf * dma = &s->dma[i];
-		rme96xx_dmabuf_init(s,dma,2*i,2*i);
-	}
-
-	/* code from ALSA card-rme9652.c   HP 20020201 */
-        /* Determine the h/w rev level of the card. This seems like
-	   a particularly kludgy way to encode it, but its what RME
-	   chose to do, so we follow them ...
-	*/
-
-	status = readl(s->iobase + RME96xx_status_register);
-	if (rme96xx_decode_spdif_rate(status&RME96xx_F) == 1) {
-		s->hw_rev = 15;
-	} else {
-		s->hw_rev = 11;
-	}
-
-	/* Differentiate between the standard Hammerfall, and the
-	   "Light", which does not have the expansion board. This
-	   method comes from information received from Mathhias
-	   Clausen at RME. Display the EEPROM and h/w revID where
-	   relevant.  
-	*/
-
-	pci_read_config_word(s->pcidev, PCI_CLASS_REVISION, &rev);
-	switch (rev & 0xff) {
-	case 8: /* original eprom */
-		if (s->hw_rev == 15) {
-			s->card_name = "RME Digi9636 (Rev 1.5)";
-		} else {
-			s->card_name = "RME Digi9636";
-		}
-		break;
-	case 9: /* W36_G EPROM */
-		s->card_name = "RME Digi9636 (Rev G)";
-		break;
-	case 4: /* W52_G EPROM */
-		s->card_name = "RME Digi9652 (Rev G)";
-		break;
-	default:
-	case 3: /* original eprom */
-		if (s->hw_rev == 15) {
-			s->card_name = "RME Digi9652 (Rev 1.5)";
-		} else {
-			s->card_name = "RME Digi9652";
-		}
-		break;
-	}
-
-	printk(KERN_INFO RME_MESS" detected %s (hw_rev %d)\n",s->card_name,s->hw_rev); 
-
-	if (s->hw_rev == 15)
-		rme96xx_initialize_spdif_receiver (s);
-
-	s->started = 0;
-	rme96xx_setlatency(s,7);
-
-	printk(KERN_INFO RME_MESS" card %d initialized\n",numcards); 
-	return 0;
-}
-
-
-/* open uses this to figure out which device was opened .. this seems to be 
-   unnecessary complex */
-
-static LIST_HEAD(devs);
-
-static int __devinit rme96xx_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-	int i;
-	rme96xx_info *s;
-
-	DBG(printk("%s\n", __FUNCTION__));
-	
-	if (pcidev->irq == 0) 
-		return -1;
-	if (!pci_dma_supported(pcidev, 0xffffffff)) {
-		printk(KERN_WARNING RME_MESS" architecture does not support 32bit PCI busmaster DMA\n");
-		return -1;
-	}
-	if (!(s = kmalloc(sizeof(rme96xx_info), GFP_KERNEL))) {
-		printk(KERN_WARNING RME_MESS" out of memory\n");
-		return -1;
-	}
-	memset(s, 0, sizeof(rme96xx_info));
-
-	s->pcidev = pcidev;
-	s->iobase = ioremap(pci_resource_start(pcidev, 0),RME96xx_IO_EXTENT);
-	s->irq = pcidev->irq;
-
-        DBG(printk("remapped iobase: %lx irq %d\n",(long)s->iobase,s->irq));
-
-	if (pci_enable_device(pcidev))
-		goto err_irq;
-	if (request_irq(s->irq, rme96xx_interrupt, IRQF_SHARED, "rme96xx", s)) {
-		printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq);
-		goto err_irq;
-	}
-	
-	/* initialize the card */
-
-	i = 0;
-	if (rme96xx_init(s) < 0) {
-		printk(KERN_ERR RME_MESS" initialization failed\n");
-		goto err_devices;
-	}
-	for (i=0;i<devices;i++) {
-		if ((s->dspnum[i] = register_sound_dsp(&rme96xx_audio_fops, -1)) < 0)
-			goto err_devices;
-	}
-
-	if ((s->mixer = register_sound_mixer(&rme96xx_mixer_fops, -1)) < 0)
-		goto err_devices;
-
-	pci_set_drvdata(pcidev, s);
-	pcidev->dma_mask = 0xffffffff; /* ????? */
-	/* put it into driver list */
-	list_add_tail(&s->devs, &devs);
-
-	DBG(printk("initialization successful\n"));
-	return 0;
-
-	/* error handler */
- err_devices:
-	while (i--) 
-		unregister_sound_dsp(s->dspnum[i]);
-	free_irq(s->irq,s);
- err_irq:
-	kfree(s);
-	return -1;
-}
-
-
-static void __devexit rme96xx_remove(struct pci_dev *dev)
-{
-	int i;
-	rme96xx_info *s = pci_get_drvdata(dev);
-
-	if (!s) {
-		printk(KERN_ERR"device structure not valid\n");
-		return ;
-	}
-
-	if (s->started) rme96xx_startcard(s,0);
-
-	i = devices;
-	while (i) {
-		i--;
-		unregister_sound_dsp(s->dspnum[i]);
-	}
-	
-	unregister_sound_mixer(s->mixer);
-	synchronize_irq(s->irq);
-	free_irq(s->irq,s);
-	busmaster_free(s->recbuf,RME96xx_DMA_MAX_SIZE_ALL);
-	busmaster_free(s->playbuf,RME96xx_DMA_MAX_SIZE_ALL);
-	kfree(s);
-	pci_set_drvdata(dev, NULL);
-}
-
-
-#ifndef PCI_VENDOR_ID_RME 
-#define PCI_VENDOR_ID_RME 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_RME9652
-#define PCI_DEVICE_ID_RME9652 0x3fc4
-#endif
-#ifndef PCI_ANY_ID
-#define PCI_ANY_ID 0
-#endif
-
-static struct pci_device_id id_table[] = {
-	{
-		.vendor	   = PCI_VENDOR_ID_RME,
-		.device	   = PCI_DEVICE_ID_RME9652,
-		.subvendor = PCI_ANY_ID,
-		.subdevice = PCI_ANY_ID,
-	},
-	{ 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver rme96xx_driver = {
-	.name	  =  "rme96xx",
-	.id_table = id_table,
-	.probe	  = rme96xx_probe,
-	.remove	  = __devexit_p(rme96xx_remove),
-};
-
-static int __init init_rme96xx(void)
-{
-	printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n");
-	devices = ((devices-1) & RME96xx_MASK_DEVS) + 1;
-	printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices);
-        numcards = 0;
-	return pci_register_driver(&rme96xx_driver);
-}
-
-static void __exit cleanup_rme96xx(void)
-{
-	printk(KERN_INFO RME_MESS" unloading\n");
-	pci_unregister_driver(&rme96xx_driver);
-}
-
-module_init(init_rme96xx);
-module_exit(cleanup_rme96xx);
-
-
-
-
-
-/*-------------------------------------------------------------------------- 
-   Implementation of file operations 
----------------------------------------------------------------------------*/
-
-#define RME96xx_FMT (AFMT_S16_LE|AFMT_U8|AFMT_S32_BLOCKED)
-/* AFTM_U8 is not (yet?) supported ...  HP20020201 */
-
-static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct dmabuf * dma = (struct dmabuf *)file->private_data; 
-	rme96xx_info *s = dma->s;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int count;
-	int val = 0;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_STATE(s);
-
-	DBG(printk("ioctl %ud\n",cmd));
-
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-#if 0
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-#endif
-		return 0;
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-//		rme96xx_clearbufs(dma);
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-/* generally it's not a problem if we change the speed 
-			if (dma->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
-				return -EINVAL;
-*/
-			spin_lock_irqsave(&s->lock, flags);
-
-			switch (val) {
-			case 44100:
-			case 88200:
-				rme96xx_unset_ctrl(s,RME96xx_freq);
-				break;
-			case 48000: 
-			case 96000: 
-				rme96xx_set_ctrl(s,RME96xx_freq);
-				break;
-			/* just report current rate as default
-			   e.g. use 0 to "select" current digital input rate
-			default:
-				rme96xx_unset_ctrl(s,RME96xx_freq);
-				val = 44100;
-			*/
-			}
-			if (val > 50000)
-				rme96xx_set_ctrl(s,RME96xx_DS);
-			else
-				rme96xx_unset_ctrl(s,RME96xx_DS);
-			/* set val to actual value  HP 20020201 */
-			/* NOTE: if not "Sync Master", reported rate might be not yet "updated" ... but I don't want to insert a long udelay() here */
-			if ((s->control_register & RME96xx_Master) && !(s->control_register & RME96xx_wsel))
-				val = rme96xx_get_sample_rate_ctrl(s);
-			else
-				val = rme96xx_get_sample_rate_status(s);
-			s->rate = val;
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		DBG(printk("speed set to %d\n",val));
-		return put_user(val, p);
-		
-        case SNDCTL_DSP_STEREO: /* this plays a mono file on two channels */
-                if (get_user(val, p))
-			return -EFAULT;
-		
-		if (!val) {
-			DBG(printk("setting to mono\n")); 
-			dma->mono=1; 
-			dma->inchannels = 1;
-			dma->outchannels = 1;
-		}
-		else {
-			DBG(printk("setting to stereo\n")); 
-			dma->mono = 0;
-			dma->inchannels = 2;
-			dma->outchannels = 2;
-		}
-		return 0;
-        case SNDCTL_DSP_CHANNELS:
-		/* remember to check for resonable offset/channel pairs here */
-                if (get_user(val, p))
-			return -EFAULT;
-
-		if (file->f_mode & FMODE_WRITE) { 			
-			if (val > 0 && (dma->outoffset + val) <= RME96xx_CHANNELS_PER_CARD) 
-				dma->outchannels = val;
-			else
-				dma->outchannels = val = 2;
-			DBG(printk("setting to outchannels %d\n",val)); 
-		}
-		if (file->f_mode & FMODE_READ) {
-			if (val > 0 && (dma->inoffset + val) <= RME96xx_CHANNELS_PER_CARD) 
-				dma->inchannels = val;
-			else
-				dma->inchannels = val = 2;
-			DBG(printk("setting to inchannels %d\n",val)); 
-		}
-
-		dma->mono=0;
-
-		return put_user(val, p);
-		
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(RME96xx_FMT, p);
-		
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		DBG(printk("setting to format %x\n",val)); 
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			if (val & RME96xx_FMT)
-				dma->format = val;
-			switch (dma->format) {
-			case AFMT_S16_LE:
-				dma->formatshift=1;
-				break;
-			case AFMT_S32_BLOCKED:
-				dma->formatshift=0;
-				break;
-			}
-		}
-		return put_user(dma->format, p);
-		
-	case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-#if 0
-		if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-			val |= PCM_ENABLE_OUTPUT;
-#endif
-		return put_user(val, p);
-		
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-#if 0
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-					return ret;
-				start_adc(s);
-			} else
-				stop_adc(s);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-					return ret;
-				start_dac2(s);
-			} else
-				stop_dac2(s);
-		}
-#endif
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-
-		val = rme96xx_gethwptr(dma->s,0);
-
-
-		count = rme96xx_getospace(dma,val);
-		if (!s->started) count = s->fragsize*2;
-		abinfo.fragsize =(s->fragsize*dma->outchannels)>>dma->formatshift;
-                abinfo.bytes = (count*dma->outchannels)>>dma->formatshift;
-                abinfo.fragstotal = 2;
-                abinfo.fragments = (count > s->fragsize); 
-
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-
-		val = rme96xx_gethwptr(dma->s,0);
-
-		count = rme96xx_getispace(dma,val);
-
-		abinfo.fragsize = (s->fragsize*dma->inchannels)>>dma->formatshift;
-                abinfo.bytes = (count*dma->inchannels)>>dma->formatshift;
-                abinfo.fragstotal = 2;
-                abinfo.fragments = count > s->fragsize; 
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-		
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY: /* What should this exactly do ? ,
-				      ATM it is just abinfo.bytes */
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-
-		val = rme96xx_gethwptr(dma->s,0);
-		count = val - dma->readptr;
-		if (count < 0)
-			count += s->fragsize<<1;
-
-		return put_user(count, p);
-
-
-/* check out how to use mmaped mode (can only be blocked !!!) */
-        case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		val = rme96xx_gethwptr(dma->s,0);
-		spin_lock_irqsave(&s->lock,flags);
-                cinfo.bytes = s->fragsize<<1;
-		count = val - dma->readptr;
-		if (count < 0)
-			count += s->fragsize<<1;
-
-                cinfo.blocks = (count > s->fragsize); 
-                cinfo.ptr = val;
-		if (dma->mmapped)
-			dma->readptr &= s->fragsize<<1;
-		spin_unlock_irqrestore(&s->lock,flags);
-
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		val = rme96xx_gethwptr(dma->s,0);
-		spin_lock_irqsave(&s->lock,flags);
-                cinfo.bytes = s->fragsize<<1;
-		count = val - dma->writeptr;
-		if (count < 0)
-			count += s->fragsize<<1;
-
-                cinfo.blocks = (count > s->fragsize); 
-                cinfo.ptr = val;
-		if (dma->mmapped)
-			dma->writeptr &= s->fragsize<<1;
-		spin_unlock_irqrestore(&s->lock,flags);
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-        case SNDCTL_DSP_GETBLKSIZE:
-	     return put_user(s->fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		val&=0xffff;
-		val -= 7;
-		if (val < 0) val = 0;
-		if (val > 7) val = 7;
-		rme96xx_setlatency(s,val);
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-#if 0
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE)
-			s->dma_dac2.subdivision = val;
-#endif		
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		/* HP20020201 */
-		s->rate = rme96xx_get_sample_rate_status(s);
-		return put_user(s->rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user(dma->outchannels, p);
-
-        case SOUND_PCM_READ_BITS:
-		switch (dma->format) {
-			case AFMT_S32_BLOCKED:
-				val = 32;
-				break;
-			case AFMT_S16_LE:
-				val = 16;
-				break;
-		}
-		return put_user(val, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-
-
-	return -ENODEV;
-}
-
-
-
-static int rme96xx_open(struct inode *in, struct file *f)
-{
-	int minor = iminor(in);
-	struct list_head *list;
-	int devnum;
-	rme96xx_info *s;
-	struct dmabuf* dma;
-	DECLARE_WAITQUEUE(wait, current); 
-
-	DBG(printk("device num %d open\n",devnum));
-
-	nonseekable_open(in, f);
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, rme96xx_info, devs);
-		for (devnum=0; devnum<devices; devnum++)
-			if (!((s->dspnum[devnum] ^ minor) & ~0xf)) 
-				break;
-		if (devnum<devices)
-			break;
-	}
-       	VALIDATE_STATE(s);
-
-	dma = &s->dma[devnum];
-	f->private_data = dma;
-	/* wait for device to become free */
-	mutex_lock(&dma->open_mutex);
-	while (dma->open_mode & f->f_mode) {
-		if (f->f_flags & O_NONBLOCK) {
-			mutex_unlock(&dma->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&dma->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&dma->open_mutex);
-		schedule();
-		remove_wait_queue(&dma->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&dma->open_mutex);
-	}
-
-	COMM                ("hardware open")
-
-	if (!dma->opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset);
-
-	dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
-	dma->opened = 1;
-	mutex_unlock(&dma->open_mutex);
-
-	DBG(printk("device num %d open finished\n",devnum));
-	return 0;
-}
-
-static int rme96xx_release(struct inode *in, struct file *file)
-{
-	struct dmabuf * dma = (struct dmabuf*) file->private_data;
-	/* int hwp;  ... was unused   HP20020201 */
-	DBG(printk("%s\n", __FUNCTION__));
-
-	COMM          ("draining")
-	if (dma->open_mode & FMODE_WRITE) {
-#if 0 /* Why doesn't this work with some cards ?? */
-	     hwp = rme96xx_gethwptr(dma->s,0);
-	     while (rme96xx_getospace(dma,hwp)) {
-		  interruptible_sleep_on(&(dma->wait));
-		  hwp = rme96xx_gethwptr(dma->s,0);
-	     }
-#endif
-	     rme96xx_clearbufs(dma);
-	}
-
-	dma->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-
-	if (!(dma->open_mode & (FMODE_READ|FMODE_WRITE))) {
-	     dma->opened = 0;
-	     if (dma->s->started) rme96xx_startcard(dma->s,1);
-	}
-
-	wake_up(&dma->open_wait);
-	mutex_unlock(&dma->open_mutex);
-
-	return 0;
-}
-
-
-static ssize_t rme96xx_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct dmabuf *dma = (struct dmabuf *)file->private_data;
-	ssize_t ret = 0;
-	int cnt; /* number of bytes from "buffer" that will/can be used */
-	int hop = count/dma->outchannels;
-	int hwp;
-	int exact = (file->f_flags & O_NONBLOCK); 
-
-
-	if(dma == NULL || (dma->s) == NULL) 
-		return -ENXIO;
-
-	if (dma->mmapped || !dma->opened)
-		return -ENXIO;
-
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-
-	if (! (dma->open_mode  & FMODE_WRITE))
-                return -ENXIO;
-
-	if (!dma->s->started) rme96xx_startcard(dma->s,exact);
-	hwp = rme96xx_gethwptr(dma->s,0);
-
-	if(!(dma->started)){		 
-		COMM          ("first write")
-			
-		dma->readptr = hwp;
-		dma->writeptr = hwp;
-		dma->started = 1;
-	}
-
-  	while (count > 0) {
-		cnt = rme96xx_getospace(dma,hwp);		
-		cnt>>=dma->formatshift;
-		cnt*=dma->outchannels;
-		if (cnt > count)
-			cnt = count;
-
-		if (cnt != 0) {
-		        if (rme96xx_copyfromuser(dma,buffer,cnt,hop))
-				return ret ? ret : -EFAULT;
-			count -= cnt;
-			buffer += cnt;
-			ret += cnt;
-			if (count == 0) return ret;
-		}
-		if (file->f_flags & O_NONBLOCK)
-			return ret ? ret : -EAGAIN;
-		
-		if ((hwp - dma->writeptr) <= 0) {
-			interruptible_sleep_on(&(dma->wait));
-			
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-		}			
-
-		hwp = rme96xx_gethwptr(dma->s,exact);
-
-	}; /* count > 0 */
-
-	return ret;
-}
-
-static ssize_t rme96xx_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{ 
-	struct dmabuf *dma = (struct dmabuf *)file->private_data;
-	ssize_t ret = 0;
-	int cnt; /* number of bytes from "buffer" that will/can be used */
-	int hop = count/dma->inchannels;
-	int hwp;
-	int exact = (file->f_flags & O_NONBLOCK); 
-
-
-	if(dma == NULL || (dma->s) == NULL) 
-		return -ENXIO;
-
-	if (dma->mmapped || !dma->opened)
-		return -ENXIO;
-
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-
-	if (! (dma->open_mode  & FMODE_READ))
-                return -ENXIO;
-
-	if (!dma->s->started) rme96xx_startcard(dma->s,exact);
-	hwp = rme96xx_gethwptr(dma->s,0);
-
-	if(!(dma->started)){		 
-		COMM          ("first read")
-		     
-		dma->writeptr = hwp;
-		dma->readptr = hwp;
-		dma->started = 1;
-	}
-
-  	while (count > 0) {
-		cnt = rme96xx_getispace(dma,hwp);		
-		cnt>>=dma->formatshift;
-		cnt*=dma->inchannels;
-
-		if (cnt > count)
-			cnt = count;
-
-		if (cnt != 0) {
-		        
-			if (rme96xx_copytouser(dma,buffer,cnt,hop))
-				return ret ? ret : -EFAULT;
-			
-			count -= cnt;
-			buffer += cnt;
-			ret += cnt;
-			if (count == 0) return ret;
-		}
-		if (file->f_flags & O_NONBLOCK)
-			return ret ? ret : -EAGAIN;
-		
-		if ((hwp - dma->readptr) <= 0) {
-			interruptible_sleep_on(&(dma->wait));
-			
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-		}			
-		hwp = rme96xx_gethwptr(dma->s,exact);
-
-	}; /* count > 0 */
-
-	return ret;
-}
-
-static int rm96xx_mmap(struct file *file, struct vm_area_struct *vma) {
-	struct dmabuf *dma = (struct dmabuf *)file->private_data;
-	rme96xx_info* s = dma->s;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-
-	if (vma->vm_pgoff != 0) {
-		unlock_kernel();
-		return -EINVAL;
-	}
-	size = vma->vm_end - vma->vm_start;
-	if (size > RME96xx_DMA_MAX_SIZE) {
-		unlock_kernel();
-		return -EINVAL;
-	}
-
-
-	if (vma->vm_flags & VM_WRITE) {
-		if (!s->started) rme96xx_startcard(s,1);
-
-		if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->outoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) {
-			unlock_kernel();
-			return -EAGAIN;
-		}
-	} 
-	else if (vma->vm_flags & VM_READ) {
-		if (!s->started) rme96xx_startcard(s,1);
-		if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->inoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) {
-			unlock_kernel();
-			return -EAGAIN;
-		}
-	} else  {
-		unlock_kernel();
-		return -EINVAL;
-	}
-
-
-/* this is the mapping */
-	vma->vm_flags &= ~VM_IO;
-	dma->mmapped = 1;
-	unlock_kernel();
-	return 0;
-}
-
-static unsigned int rme96xx_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct dmabuf *dma = (struct dmabuf *)file->private_data;
-	rme96xx_info* s = dma->s;
-	unsigned int mask = 0;
-	unsigned int hwp,cnt;
-
-        DBG(printk("rme96xx poll_wait ...\n"));
-	VALIDATE_STATE(s);
-
-	if (!s->started) {
-		  mask |= POLLOUT | POLLWRNORM;
-	}
-	poll_wait(file, &dma->wait, wait);
-
-	hwp = rme96xx_gethwptr(dma->s,0);
-
-        DBG(printk("rme96xx poll: ..cnt %d > %d\n",cnt,s->fragsize));	
-
-	cnt = rme96xx_getispace(dma,hwp);
-
-	if (file->f_mode & FMODE_READ) 
-	     if (cnt > 0)
-		  mask |= POLLIN | POLLRDNORM;
-
-
-
-	cnt = rme96xx_getospace(dma,hwp);
-
-	if (file->f_mode & FMODE_WRITE) 
-	     if (cnt > 0)
-		  mask |= POLLOUT | POLLWRNORM;
-
-
-//        printk("rme96xx poll_wait ...%d > %d\n",rme96xx_getospace(dma,hwp),rme96xx_getispace(dma,hwp));
-
-	return mask;
-}
-
-
-static struct file_operations rme96xx_audio_fops = {
-	.owner	 = THIS_MODULE,
-	.read	 = rme96xx_read,
-	.write	 = rme96xx_write,
-	.poll	 = rme96xx_poll,
-	.ioctl	 = rme96xx_ioctl,  
-	.mmap	 = rm96xx_mmap,
-	.open	 = rme96xx_open,  
-	.release = rme96xx_release 
-};
-
-static int rme96xx_mixer_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	struct list_head *list;
-	rme96xx_info *s;
-
-	COMM  ("mixer open");
-
-	nonseekable_open(inode, file);
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, rme96xx_info, devs);
-		if (s->mixer== minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-
-	COMM                       ("mixer opened")
-	return 0;
-}
-
-static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	rme96xx_info *s = (rme96xx_info *)file->private_data;
-	u32 status;
-	int spdifrate;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	status = readl(s->iobase + RME96xx_status_register);
-	/* hack to convert rev 1.5 SPDIF rate to "crystalrate" format   HP 20020201 */
-	rme96xx_spdif_sample_rate(s,&spdifrate);
-	status = (status & ~RME96xx_F) | ((spdifrate<<22) & RME96xx_F);
-
-	VALIDATE_STATE(s);
-	if (cmd == SOUND_MIXER_PRIVATE1) {
-		rme_mixer mixer;
-		if (copy_from_user(&mixer,argp,sizeof(mixer)))
-			return -EFAULT;
-		
-		mixer.devnr &= RME96xx_MASK_DEVS;
-		if (mixer.devnr >= devices)
-			mixer.devnr = devices-1;
-		if (file->f_mode & FMODE_WRITE && !s->dma[mixer.devnr].opened) {
-			/* modify only if device not open */
-			if (mixer.o_offset < 0)
-				mixer.o_offset = 0;
-			if (mixer.o_offset >= RME96xx_CHANNELS_PER_CARD)
-				mixer.o_offset = RME96xx_CHANNELS_PER_CARD-1;
-			if (mixer.i_offset < 0)
-				mixer.i_offset = 0;
-			if (mixer.i_offset >= RME96xx_CHANNELS_PER_CARD)
-				mixer.i_offset = RME96xx_CHANNELS_PER_CARD-1;
-			s->dma[mixer.devnr].outoffset = mixer.o_offset;
-			s->dma[mixer.devnr].inoffset = mixer.i_offset;
-		}
-
-		mixer.o_offset = s->dma[mixer.devnr].outoffset;
-		mixer.i_offset = s->dma[mixer.devnr].inoffset;
-
-		return copy_to_user(argp, &mixer, sizeof(mixer)) ? -EFAULT : 0;
-	}
-	if (cmd == SOUND_MIXER_PRIVATE2) {
-		return put_user(status, p);
-	}
-	if (cmd == SOUND_MIXER_PRIVATE3) {
-		u32 control;
-		if (copy_from_user(&control,argp,sizeof(control)))
-			return -EFAULT;
-		if (file->f_mode & FMODE_WRITE) {
-			s->control_register &= ~RME96xx_mixer_allowed;
-			s->control_register |= control & RME96xx_mixer_allowed;
-			writel(control,s->iobase + RME96xx_control_register);
-		}
-
-	     return put_user(s->control_register, p);
-	}
-	return -1;
-}
-
-
-
-static int rme96xx_mixer_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static /*const*/ struct file_operations rme96xx_mixer_fops = {
-	.owner	 = THIS_MODULE,
-	.ioctl	 = rme96xx_mixer_ioctl,
-	.open	 = rme96xx_mixer_open,
-	.release = rme96xx_mixer_release,
-};
diff --git a/sound/oss/rme96xx.h b/sound/oss/rme96xx.h
deleted file mode 100644
index 7a3c188..0000000
--- a/sound/oss/rme96xx.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* (C) 2000 Guenter Geiger <geiger@debian.org>
-   with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
-
-Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-   HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
-   HP20020201 completed?
-
-A text/graphic control panel (rmectrl/xrmectrl) is available from
-   http://gige.xdv.org/pages/soft/pages/rme
-*/
-
-
-#ifndef AFMT_S32_BLOCKED
-#define AFMT_S32_BLOCKED 0x0000400
-#endif
-
-/* AFMT_S16_BLOCKED not yet supported */
-#ifndef AFMT_S16_BLOCKED 
-#define AFMT_S16_BLOCKED 0x0000800
-#endif
-
-
-typedef struct rme_status {
-	unsigned int irq:1;
-	unsigned int lockmask:3;     /* ADAT input PLLs locked */
-	                             /*   100=ADAT1, 010=ADAT2, 001=ADAT3 */
-	unsigned int sr48:1;         /* sample rate: 0=44.1/88.2 1=48/96 kHz */
-	unsigned int wclock:1;       /* 1=wordclock used */
-	unsigned int bufpoint:10;
-	unsigned int syncmask:3;     /* ADAT input in sync with system clock */
-	                             /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */
-	unsigned int doublespeed:1;  /* sample rate: 0=44.1/48 1=88.2/96 kHz */
-	unsigned int tc_busy:1;
-	unsigned int tc_out:1;
-	unsigned int crystalrate:3;  /* spdif input sample rate: */
-	                             /*   000=64kHz, 100=88.2kHz, 011=96kHz */
-	                             /*   111=32kHz, 110=44.1kHz, 101=48kHz */
-	unsigned int spdif_error:1;  /* 1=no spdif lock */
-	unsigned int bufid:1;
-	unsigned int tc_valid:1;     /* 1=timecode input detected */
-	unsigned int spdif_read:1;
-} rme_status_t;
-
-
-/* only fields marked W: can be modified by writing to SOUND_MIXER_PRIVATE3 */
-typedef struct rme_control {
-	unsigned int start:1;
-	unsigned int latency:3;      /* buffer size / latency [samples]: */
-	                             /*   0=64 ... 7=8192 */
-	unsigned int master:1;       /* W: clock mode: 1=master 0=slave/auto */
-	unsigned int ie:1;
-	unsigned int sr48:1;         /* samplerate 0=44.1/88.2, 1=48/96 kHz */
-	unsigned int spare:1;
-	unsigned int doublespeed:1;  /* double speed 0=44.1/48, 1=88.2/96 Khz */
-	unsigned int pro:1;          /* W: SPDIF-OUT 0=consumer, 1=professional */
-	unsigned int emphasis:1;     /* W: SPDIF-OUT emphasis 0=off, 1=on */
-	unsigned int dolby:1;        /* W: SPDIF-OUT non-audio bit 1=set, 0=unset */
-	unsigned int opt_out:1;      /* W: use 1st optical OUT as SPDIF: 1=yes, 0=no */
-	unsigned int wordclock:1;    /* W: use Wordclock as sync (overwrites master) */
-        unsigned int spdif_in:2;     /* W: SPDIF-IN: */
-                                     /*    00=optical (ADAT1), 01=coaxial (Cinch), 10=internal CDROM */
-	unsigned int sync_ref:2;     /* W: preferred sync-source in autosync */
-                                     /*    00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
-	unsigned int spdif_reset:1;
-	unsigned int spdif_select:1;
-	unsigned int spdif_clock:1;
-	unsigned int spdif_write:1;
-	unsigned int adat1_cd:1;     /* W: Rev 1.5+: if set, internal CD connector carries ADAT */
-} rme_ctrl_t;
-
-
-typedef struct _rme_mixer {
-	int i_offset;
-	int o_offset;
-	int devnr;
-	int spare[8];
-} rme_mixer;
-
diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c
index 75e54f6..733b014 100644
--- a/sound/oss/sb_audio.c
+++ b/sound/oss/sb_audio.c
@@ -1,5 +1,5 @@
 /*
- * sound/sb_audio.c
+ * sound/oss/sb_audio.c
  *
  * Audio routines for Sound Blaster compatible cards.
  *
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
index 35bab6e..bbe5b75 100644
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -1,5 +1,5 @@
 /*
- * sound/sb_common.c
+ * sound/oss/sb_common.c
  *
  * Common routines for Sound Blaster compatible cards.
  *
diff --git a/sound/oss/sb_midi.c b/sound/oss/sb_midi.c
index ed3bd06..2e3bc04 100644
--- a/sound/oss/sb_midi.c
+++ b/sound/oss/sb_midi.c
@@ -1,5 +1,5 @@
 /*
- * sound/sb_dsp.c
+ * sound/oss/sb_midi.c
  *
  * The low level driver for the Sound Blaster DS chips.
  *
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index ccb21d4..238e2cf 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -1,5 +1,5 @@
 /*
- * sound/sb_mixer.c
+ * sound/oss/sb_mixer.c
  *
  * The low level mixer driver for the Sound Blaster compatible cards.
  */
diff --git a/sound/oss/sb_mixer.h b/sound/oss/sb_mixer.h
index ab74426..4b9425f 100644
--- a/sound/oss/sb_mixer.h
+++ b/sound/oss/sb_mixer.h
@@ -1,5 +1,5 @@
 /*
- * sound/sb_mixer.h
+ * sound/oss/sb_mixer.h
  * 
  * Definitions for the SB Pro and SB16 mixers
  */
diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c
index 6815c30..5c215f7 100644
--- a/sound/oss/sequencer.c
+++ b/sound/oss/sequencer.c
@@ -1,5 +1,5 @@
 /*
- * sound/sequencer.c
+ * sound/oss/sequencer.c
  *
  * The sequencer personality manager.
  */
@@ -16,7 +16,6 @@
  */
 #include <linux/kmod.h>
 #include <linux/spinlock.h>
-#define SEQUENCER_C
 #include "sound_config.h"
 
 #include "midi_ctrl.h"
@@ -157,6 +156,7 @@
 	wake_up(&midi_sleeper);
 	spin_unlock_irqrestore(&lock,flags);
 }
+EXPORT_SYMBOL(seq_copy_to_input);
 
 static void sequencer_midi_input(int dev, unsigned char data)
 {
@@ -206,6 +206,7 @@
 	}
 	seq_copy_to_input(event_rec, len);
 }
+EXPORT_SYMBOL(seq_input_event);
 
 int sequencer_write(int dev, struct file *file, const char __user *buf, int count)
 {
@@ -1554,6 +1555,7 @@
 {
 	seq_startplay();
 }
+EXPORT_SYMBOL(sequencer_timer);
 
 int note_to_freq(int note_num)
 {
@@ -1587,6 +1589,7 @@
 
 	return note_freq;
 }
+EXPORT_SYMBOL(note_to_freq);
 
 unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
 		 int vibrato_cents)
@@ -1640,19 +1643,12 @@
 	else
 		return (base_freq * amount) / 10000;	/* Bend up */
 }
-
+EXPORT_SYMBOL(compute_finetune);
 
 void sequencer_init(void)
 {
-	/* drag in sequencer_syms.o */
-	{
-		extern char sequencer_syms_symbol;
-		sequencer_syms_symbol = 0;
-	}
-
 	if (sequencer_ok)
 		return;
-	MIDIbuf_init();
 	queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ);
 	if (queue == NULL)
 	{
@@ -1668,6 +1664,7 @@
 	}
 	sequencer_ok = 1;
 }
+EXPORT_SYMBOL(sequencer_init);
 
 void sequencer_unload(void)
 {
diff --git a/sound/oss/sequencer_syms.c b/sound/oss/sequencer_syms.c
deleted file mode 100644
index 5d00879..0000000
--- a/sound/oss/sequencer_syms.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Exported symbols for sequencer driver.
- */
-
-#include <linux/module.h>
-
-char sequencer_syms_symbol;
-
-#include "sound_config.h"
-#include "sound_calls.h"
-
-EXPORT_SYMBOL(note_to_freq);
-EXPORT_SYMBOL(compute_finetune);
-EXPORT_SYMBOL(seq_copy_to_input);
-EXPORT_SYMBOL(seq_input_event);
-EXPORT_SYMBOL(sequencer_init);
-EXPORT_SYMBOL(sequencer_timer);
-
-EXPORT_SYMBOL(sound_timer_init);
-EXPORT_SYMBOL(sound_timer_interrupt);
-EXPORT_SYMBOL(sound_timer_syncinterval);
-
-/* Tuning */
-
-#define _SEQUENCER_C_
-#include "tuning.h"
-
-EXPORT_SYMBOL(cent_tuning);
-EXPORT_SYMBOL(semitone_tuning);
diff --git a/sound/oss/sgalaxy.c b/sound/oss/sgalaxy.c
deleted file mode 100644
index 3f32d46..0000000
--- a/sound/oss/sgalaxy.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * sound/sgalaxy.c
- *
- * Low level driver for Aztech Sound Galaxy cards.
- * Copyright 1998 Artur Skawina <skawina@geocities.com>
- *
- * Supported cards:
- *    Aztech Sound Galaxy Waverider Pro 32 - 3D
- *    Aztech Sound Galaxy Washington 16
- *
- * Based on cs4232.c by Hannu Savolainen and Alan Cox.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000	Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *		Added __init to sb_rst() and sb_cmd()
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include "sound_config.h"
-#include "ad1848.h"
-
-static void sleep( unsigned howlong )
-{
-	current->state   = TASK_INTERRUPTIBLE;
-	schedule_timeout(howlong);
-}
-
-#define DPORT 0x80
-
-/* Sound Blaster regs */
-
-#define SBDSP_RESET      0x6
-#define SBDSP_READ       0xA
-#define SBDSP_COMMAND    0xC
-#define SBDSP_STATUS     SBDSP_COMMAND
-#define SBDSP_DATA_AVAIL 0xE
-
-static int __init sb_rst(int base)
-{
-	int   i;
-   
-	outb( 1, base+SBDSP_RESET );     /* reset the DSP */
-	outb( 0, base+SBDSP_RESET );
-    
-	for ( i=0; i<500; i++ )          /* delay */
-		inb(DPORT);
-      
-	for ( i=0; i<100000; i++ )
-	{
-		if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
-			break;
-	}
-
-	if ( inb( base+SBDSP_READ )!=0xAA )
-		return 0;
-
-	return 1;
-}
-
-static int __init sb_cmd( int base, unsigned char val )
-{
-	int  i;
-
-	for ( i=100000; i; i-- )
-	{
-		if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
-		{
-        		outb( val, base+SBDSP_COMMAND );
-        		break;
-		}
-	}
-	return i;      /* i>0 == success */
-}
-
-
-#define ai_sgbase    driver_use_1
-
-static int __init probe_sgalaxy( struct address_info *ai )
-{
-	struct resource *ports;
-	int n;
-
-	if (!request_region(ai->io_base, 4, "WSS config")) {
-		printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
-		return 0;
-	}
-
-	ports = request_region(ai->io_base + 4, 4, "ad1848");
-	if (!ports) {
-		printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
-		release_region(ai->io_base, 4);
-		return 0;
-	}
-
-	if (!request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB")) {
-		printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
-		release_region(ai->io_base + 4, 4);
-		release_region(ai->io_base, 4);
-		return 0;
-	}
-        
-	if (ad1848_detect(ports, NULL, ai->osp))
-		goto out;  /* The card is already active, check irq etc... */
-        
-	/* switch to MSS/WSS mode */
-   
-	sb_rst( ai->ai_sgbase );
-   
-	sb_cmd( ai->ai_sgbase, 9 );
-	sb_cmd( ai->ai_sgbase, 0 );
-
-	sleep( HZ/10 );
-
-out:
-      	if (!probe_ms_sound(ai, ports)) {
-		release_region(ai->io_base + 4, 4);
-		release_region(ai->io_base, 4);
-		release_region(ai->ai_sgbase, 0x10);
-		return 0;
-	}
-
-	attach_ms_sound(ai, ports, THIS_MODULE);
-	n=ai->slots[0];
-	
-	if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
-		AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE );   /* Line-in */
-		AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH );  /* FM+Wavetable*/
-		AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD );     /* CD */
-	}
-	return 1;
-}
-
-static void __exit unload_sgalaxy( struct address_info *ai )
-{
-	unload_ms_sound( ai );
-	release_region( ai->ai_sgbase, 0x10 );
-}
-
-static struct address_info cfg;
-
-static int __initdata io	= -1;
-static int __initdata irq	= -1;
-static int __initdata dma	= -1;
-static int __initdata dma2	= -1;
-static int __initdata sgbase	= -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma2, int, 0);
-module_param(sgbase, int, 0);
-
-static int __init init_sgalaxy(void)
-{
-	cfg.io_base   = io;
-	cfg.irq       = irq;
-	cfg.dma       = dma;
-	cfg.dma2      = dma2;
-	cfg.ai_sgbase = sgbase;
-
-	if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
-		printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
-		return -EINVAL;
-	}
-
-	if ( probe_sgalaxy(&cfg) == 0 )
-		return -ENODEV;
-
-	return 0;
-}
-
-static void __exit cleanup_sgalaxy(void)
-{
-	unload_sgalaxy(&cfg);
-}
-
-module_init(init_sgalaxy);
-module_exit(cleanup_sgalaxy);
-
-#ifndef MODULE
-static int __init setup_sgalaxy(char *str)
-{
-	/* io, irq, dma, dma2, sgbase */
-	int ints[6];
-	
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-	io	= ints[1];
-	irq	= ints[2];
-	dma	= ints[3];
-	dma2	= ints[4];
-	sgbase	= ints[5];
-
-	return 1;
-}
-
-__setup("sgalaxy=", setup_sgalaxy);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
deleted file mode 100644
index 8ea532d..0000000
--- a/sound/oss/sonicvibes.c
+++ /dev/null
@@ -1,2792 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      sonicvibes.c  --  S3 Sonic Vibes audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi
- *
- *
- * Module command line parameters:
- *   none so far
- *
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  The card has both an FM and a Wavetable synth, but I have to figure
- *  out first how to drive them...
- *
- *  Revision history
- *    06.05.1998   0.1   Initial release
- *    10.05.1998   0.2   Fixed many bugs, esp. ADC rate calculation
- *                       First stab at a simple midi interface (no bells&whistles)
- *    13.05.1998   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of
- *                       set_dac_rate in the FMODE_WRITE case in sv_open
- *                       Fix hwptr out of bounds (now mpg123 works)
- *    14.05.1998   0.4   Don't allow excessive interrupt rates
- *    08.06.1998   0.5   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.1998   0.6   Do not include modversions.h
- *                       Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *    31.08.1998   0.7   Fix realplayer problems - dac.count issues
- *    10.12.1998   0.8   Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.1998   0.9   Fix a few f_file & FMODE_ bugs
- *    06.01.1999   0.10  remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.11  cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    05.04.1999   0.13  added code to sv_read and sv_write which should detect
- *                       lockups of the sound chip and revive it. This is basically
- *                       an ugly hack, but at least applications using this driver
- *                       won't hang forever. I don't know why these lockups happen,
- *                       it might well be the motherboard chipset (an early 486 PCI
- *                       board with ALI chipset), since every busmastering 100MB
- *                       ethernet card I've tried (Realtek 8139 and Macronix tulip clone)
- *                       exhibit similar behaviour (they work for a couple of packets
- *                       and then lock up and can be revived by ifconfig down/up).
- *    07.04.1999   0.14  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Note: dmaio hack might still be wrong on archs other than i386
- *    15.06.1999   0.15  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.16  Add pci_set_master
- *    03.08.1999   0.17  adapt to Linus' new __setup/__initcall
- *                       added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr"
- *    12.08.1999   0.18  module_init/__setup fixes
- *    24.08.1999   0.19  get rid of the dmaio kludge, replace with allocate_resource
- *    31.08.1999   0.20  add spin_lock_init
- *                       use new resource allocation to allocate DDMA IO space
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.21  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    28.10.1999   0.22  More waitqueue races fixed
- *    01.12.1999   0.23  New argument to allocate_resource
- *    07.12.1999   0.24  More allocate_resource semantics change
- *    08.01.2000   0.25  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *                       use Martin Mares' pci_assign_resource
- *    07.02.2000   0.26  Use pci_alloc_consistent and pci_register_driver
- *    21.11.2000   0.27  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.28  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    31.01.2001   0.29  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    18.05.2001   0.30  PCI probing and error values cleaned up by Marcus
- *                       Meissner <mm@caldera.de>
- *    03.01.2003   0.31  open_mode fixes from Georg Acher <acher@in.tum.de>
- *
- */
-
-/*****************************************************************************/
-      
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/gameport.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include "dm.h"
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3             0x5333
-#endif
-#ifndef PCI_DEVICE_ID_S3_SONICVIBES
-#define PCI_DEVICE_ID_S3_SONICVIBES  0xca00
-#endif
-
-#define SV_MAGIC  ((PCI_VENDOR_ID_S3<<16)|PCI_DEVICE_ID_S3_SONICVIBES)
-
-#define SV_EXTENT_SB      0x10
-#define SV_EXTENT_ENH     0x10
-#define SV_EXTENT_SYNTH   0x4
-#define SV_EXTENT_MIDI    0x4
-#define SV_EXTENT_GAME    0x8
-#define SV_EXTENT_DMA     0x10
-
-/*
- * we are not a bridge and thus use a resource for DDMA that is used for bridges but
- * left empty for normal devices
- */
-#define RESOURCE_SB       0
-#define RESOURCE_ENH      1
-#define RESOURCE_SYNTH    2
-#define RESOURCE_MIDI     3
-#define RESOURCE_GAME     4
-#define RESOURCE_DDMA     7
-
-#define SV_MIDI_DATA      0
-#define SV_MIDI_COMMAND   1
-#define SV_MIDI_STATUS    1
-
-#define SV_DMA_ADDR0      0
-#define SV_DMA_ADDR1      1
-#define SV_DMA_ADDR2      2
-#define SV_DMA_ADDR3      3
-#define SV_DMA_COUNT0     4
-#define SV_DMA_COUNT1     5
-#define SV_DMA_COUNT2     6
-#define SV_DMA_MODE       0xb
-#define SV_DMA_RESET      0xd
-#define SV_DMA_MASK       0xf
-
-/*
- * DONT reset the DMA controllers unless you understand
- * the reset semantics. Assuming reset semantics as in
- * the 8237 does not work.
- */
-
-#define DMA_MODE_AUTOINIT 0x10
-#define DMA_MODE_READ     0x44    /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE    0x48    /* memory to I/O, no autoinit, increment, single mode */
-
-#define SV_CODEC_CONTROL  0
-#define SV_CODEC_INTMASK  1
-#define SV_CODEC_STATUS   2
-#define SV_CODEC_IADDR    4
-#define SV_CODEC_IDATA    5
-
-#define SV_CCTRL_RESET      0x80
-#define SV_CCTRL_INTADRIVE  0x20
-#define SV_CCTRL_WAVETABLE  0x08
-#define SV_CCTRL_REVERB     0x04
-#define SV_CCTRL_ENHANCED   0x01
-
-#define SV_CINTMASK_DMAA    0x01
-#define SV_CINTMASK_DMAC    0x04
-#define SV_CINTMASK_SPECIAL 0x08
-#define SV_CINTMASK_UPDOWN  0x40
-#define SV_CINTMASK_MIDI    0x80
-
-#define SV_CSTAT_DMAA       0x01
-#define SV_CSTAT_DMAC	    0x04
-#define SV_CSTAT_SPECIAL    0x08
-#define SV_CSTAT_UPDOWN	    0x40
-#define SV_CSTAT_MIDI	    0x80
-
-#define SV_CIADDR_TRD       0x80
-#define SV_CIADDR_MCE       0x40
-
-/* codec indirect registers */
-#define SV_CIMIX_ADCINL     0x00
-#define SV_CIMIX_ADCINR     0x01
-#define SV_CIMIX_AUX1INL    0x02
-#define SV_CIMIX_AUX1INR    0x03
-#define SV_CIMIX_CDINL      0x04
-#define SV_CIMIX_CDINR      0x05
-#define SV_CIMIX_LINEINL    0x06
-#define SV_CIMIX_LINEINR    0x07
-#define SV_CIMIX_MICIN      0x08
-#define SV_CIMIX_SYNTHINL   0x0A
-#define SV_CIMIX_SYNTHINR   0x0B
-#define SV_CIMIX_AUX2INL    0x0C
-#define SV_CIMIX_AUX2INR    0x0D
-#define SV_CIMIX_ANALOGINL  0x0E
-#define SV_CIMIX_ANALOGINR  0x0F
-#define SV_CIMIX_PCMINL     0x10
-#define SV_CIMIX_PCMINR     0x11
-
-#define SV_CIGAMECONTROL    0x09
-#define SV_CIDATAFMT        0x12
-#define SV_CIENABLE         0x13
-#define SV_CIUPDOWN         0x14
-#define SV_CIREVISION       0x15
-#define SV_CIADCOUTPUT      0x16
-#define SV_CIDMAABASECOUNT1 0x18
-#define SV_CIDMAABASECOUNT0 0x19
-#define SV_CIDMACBASECOUNT1 0x1c
-#define SV_CIDMACBASECOUNT0 0x1d
-#define SV_CIPCMSR0         0x1e
-#define SV_CIPCMSR1         0x1f
-#define SV_CISYNTHSR0       0x20
-#define SV_CISYNTHSR1       0x21
-#define SV_CIADCCLKSOURCE   0x22
-#define SV_CIADCALTSR       0x23
-#define SV_CIADCPLLM        0x24
-#define SV_CIADCPLLN        0x25
-#define SV_CISYNTHPLLM      0x26
-#define SV_CISYNTHPLLN      0x27
-#define SV_CIUARTCONTROL    0x2a
-#define SV_CIDRIVECONTROL   0x2b
-#define SV_CISRSSPACE       0x2c
-#define SV_CISRSCENTER      0x2d
-#define SV_CIWAVETABLESRC   0x2e
-#define SV_CIANALOGPWRDOWN  0x30
-#define SV_CIDIGITALPWRDOWN 0x31
-
-
-#define SV_CIMIX_ADCSRC_CD     0x20
-#define SV_CIMIX_ADCSRC_DAC    0x40
-#define SV_CIMIX_ADCSRC_AUX2   0x60
-#define SV_CIMIX_ADCSRC_LINE   0x80
-#define SV_CIMIX_ADCSRC_AUX1   0xa0
-#define SV_CIMIX_ADCSRC_MIC    0xc0
-#define SV_CIMIX_ADCSRC_MIXOUT 0xe0
-#define SV_CIMIX_ADCSRC_MASK   0xe0
-
-#define SV_CFMT_STEREO     0x01
-#define SV_CFMT_16BIT      0x02
-#define SV_CFMT_MASK       0x03
-#define SV_CFMT_ASHIFT     0   
-#define SV_CFMT_CSHIFT     4
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-#define SV_CENABLE_PPE     0x4
-#define SV_CENABLE_RE      0x2
-#define SV_CENABLE_PE      0x1
-
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 2
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define FMODE_DMFM 0x10
-
-/* --------------------------------------------------------------------- */
-
-struct sv_state {
-	/* magic */
-	unsigned int magic;
-
-	/* list of sonicvibes devices */
-	struct list_head devs;
-
-	/* the corresponding pci_dev structure */
-	struct pci_dev *dev;
-
-	/* soundcore stuff */
-	int dev_audio;
-	int dev_mixer;
-	int dev_midi;
-	int dev_dmfm;
-
-	/* hardware resources */
-	unsigned long iosb, ioenh, iosynth, iomidi;  /* long for SPARC */
-	unsigned int iodmaa, iodmac, irq;
-
-        /* mixer stuff */
-        struct {
-                unsigned int modcnt;
-#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
-		unsigned short vol[13];
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-        } mix;
-
-	/* wave stuff */
-	unsigned int rateadc, ratedac;
-	unsigned char fmt, enable;
-
-	spinlock_t lock;
-	struct mutex open_mutex;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-
-	struct dmabuf {
-		void *rawbuf;
-		dma_addr_t dmaaddr;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-		unsigned hwptr, swptr;
-		unsigned total_bytes;
-		int count;
-		unsigned error; /* over/underrun */
-		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;
-		unsigned dmasize;
-		unsigned fragsamples;
-		/* OSS stuff */
-		unsigned mapped:1;
-		unsigned ready:1;
-		unsigned endcleared:1;
-		unsigned enabled:1;
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac, dma_adc;
-
-	/* midi stuff */
-	struct {
-		unsigned ird, iwr, icnt;
-		unsigned ord, owr, ocnt;
-		wait_queue_head_t iwait;
-		wait_queue_head_t owait;
-		struct timer_list timer;
-		unsigned char ibuf[MIDIINBUF];
-		unsigned char obuf[MIDIOUTBUF];
-	} midi;
-
-#if SUPPORT_JOYSTICK
-	struct gameport *gameport;
-#endif
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-static unsigned long wavetable_mem;
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned r = 0;
-	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
- */
-
-#undef DMABYTEIO
-
-static void set_dmaa(struct sv_state *s, unsigned int addr, unsigned int count)
-{
-#ifdef DMABYTEIO
-	unsigned io = s->iodmaa, u;
-
-	count--;
-	for (u = 4; u > 0; u--, addr >>= 8, io++)
-		outb(addr & 0xff, io);
-	for (u = 3; u > 0; u--, count >>= 8, io++)
-		outb(count & 0xff, io);
-#else /* DMABYTEIO */
-	count--;
-	outl(addr, s->iodmaa + SV_DMA_ADDR0);
-	outl(count, s->iodmaa + SV_DMA_COUNT0);
-#endif /* DMABYTEIO */
-	outb(0x18, s->iodmaa + SV_DMA_MODE);
-}
-
-static void set_dmac(struct sv_state *s, unsigned int addr, unsigned int count)
-{
-#ifdef DMABYTEIO
-	unsigned io = s->iodmac, u;
-
-	count >>= 1;
-	count--;
-	for (u = 4; u > 0; u--, addr >>= 8, io++)
-		outb(addr & 0xff, io);
-	for (u = 3; u > 0; u--, count >>= 8, io++)
-		outb(count & 0xff, io);
-#else /* DMABYTEIO */
-	count >>= 1;
-	count--;
-	outl(addr, s->iodmac + SV_DMA_ADDR0);
-	outl(count, s->iodmac + SV_DMA_COUNT0);
-#endif /* DMABYTEIO */
-	outb(0x14, s->iodmac + SV_DMA_MODE);
-}
-
-static inline unsigned get_dmaa(struct sv_state *s)
-{
-#ifdef DMABYTEIO
-	unsigned io = s->iodmaa+6, v = 0, u;
-
-	for (u = 3; u > 0; u--, io--) {
-		v <<= 8;
-		v |= inb(io);
-	}
-	return v + 1;
-#else /* DMABYTEIO */
-	return (inl(s->iodmaa + SV_DMA_COUNT0) & 0xffffff) + 1;
-#endif /* DMABYTEIO */
-}
-
-static inline unsigned get_dmac(struct sv_state *s)
-{
-#ifdef DMABYTEIO
-	unsigned io = s->iodmac+6, v = 0, u;
-
-	for (u = 3; u > 0; u--, io--) {
-		v <<= 8;
-		v |= inb(io);
-	}
-	return (v + 1) << 1;
-#else /* DMABYTEIO */
-	return ((inl(s->iodmac + SV_DMA_COUNT0) & 0xffffff) + 1) << 1;
-#endif /* DMABYTEIO */
-}
-
-static void wrindir(struct sv_state *s, unsigned char idx, unsigned char data)
-{
-	outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-	udelay(10);
-	outb(data, s->ioenh + SV_CODEC_IDATA);
-	udelay(10);
-}
-
-static unsigned char rdindir(struct sv_state *s, unsigned char idx)
-{
-	unsigned char v;
-
-	outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-	udelay(10);
-	v = inb(s->ioenh + SV_CODEC_IDATA);
-	udelay(10);
-	return v;
-}
-
-static void set_fmt(struct sv_state *s, unsigned char mask, unsigned char data)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	outb(SV_CIDATAFMT | SV_CIADDR_MCE, s->ioenh + SV_CODEC_IADDR);
-	if (mask) {
-		s->fmt = inb(s->ioenh + SV_CODEC_IDATA);
-		udelay(10);
-	}
-	s->fmt = (s->fmt & mask) | data;
-	outb(s->fmt, s->ioenh + SV_CODEC_IDATA);
-	udelay(10);
-	outb(0, s->ioenh + SV_CODEC_IADDR);
-	spin_unlock_irqrestore(&s->lock, flags);
-	udelay(10);
-}
-
-static void frobindir(struct sv_state *s, unsigned char idx, unsigned char mask, unsigned char data)
-{
-	outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-	udelay(10);
-	outb((inb(s->ioenh + SV_CODEC_IDATA) & mask) ^ data, s->ioenh + SV_CODEC_IDATA);
-	udelay(10);
-}
-
-#define REFFREQUENCY  24576000
-#define ADCMULT 512
-#define FULLRATE 48000
-
-static unsigned setpll(struct sv_state *s, unsigned char reg, unsigned rate)
-{
-	unsigned long flags;
-	unsigned char r, m=0, n=0;
-	unsigned xm, xn, xr, xd, metric = ~0U;
-	/* the warnings about m and n used uninitialized are bogus and may safely be ignored */
-
-	if (rate < 625000/ADCMULT)
-		rate = 625000/ADCMULT;
-	if (rate > 150000000/ADCMULT)
-		rate = 150000000/ADCMULT;
-	/* slight violation of specs, needed for continuous sampling rates */
-	for (r = 0; rate < 75000000/ADCMULT; r += 0x20, rate <<= 1);
-	for (xn = 3; xn < 35; xn++)
-		for (xm = 3; xm < 130; xm++) {
-			xr = REFFREQUENCY/ADCMULT * xm / xn;
-			xd = abs((signed)(xr - rate));
-			if (xd < metric) {
-				metric = xd;
-				m = xm - 2;
-				n = xn - 2;
-			}
-		}
-	reg &= 0x3f;
-	spin_lock_irqsave(&s->lock, flags);
-	outb(reg, s->ioenh + SV_CODEC_IADDR);
-	udelay(10);
-	outb(m, s->ioenh + SV_CODEC_IDATA);
-	udelay(10);
-	outb(reg+1, s->ioenh + SV_CODEC_IADDR);
-	udelay(10);
-	outb(r | n, s->ioenh + SV_CODEC_IDATA);
-	spin_unlock_irqrestore(&s->lock, flags);
-	udelay(10);
-	return (REFFREQUENCY/ADCMULT * (m + 2) / (n + 2)) >> ((r >> 5) & 7);
-}
-
-#if 0
-
-static unsigned getpll(struct sv_state *s, unsigned char reg)
-{
-	unsigned long flags;
-	unsigned char m, n;
-
-	reg &= 0x3f;
-	spin_lock_irqsave(&s->lock, flags);
-	outb(reg, s->ioenh + SV_CODEC_IADDR);
-	udelay(10);
-	m = inb(s->ioenh + SV_CODEC_IDATA);
-	udelay(10);
-	outb(reg+1, s->ioenh + SV_CODEC_IADDR);
-	udelay(10);
-	n = inb(s->ioenh + SV_CODEC_IDATA);
-	spin_unlock_irqrestore(&s->lock, flags);
-	udelay(10);
-	return (REFFREQUENCY/ADCMULT * (m + 2) / ((n & 0x1f) + 2)) >> ((n >> 5) & 7);
-}
-
-#endif
-
-static void set_dac_rate(struct sv_state *s, unsigned rate)
-{
-	unsigned div;
-	unsigned long flags;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
-	div = (rate * 65536 + FULLRATE/2) / FULLRATE;
-	if (div > 65535)
-		div = 65535;
-	spin_lock_irqsave(&s->lock, flags);
-	wrindir(s, SV_CIPCMSR1, div >> 8);
-	wrindir(s, SV_CIPCMSR0, div);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->ratedac = (div * FULLRATE + 32768) / 65536;
-}
-
-static void set_adc_rate(struct sv_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned rate1, rate2, div;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
-	rate1 = setpll(s, SV_CIADCPLLM, rate);
-	div = (48000 + rate/2) / rate;
-	if (div > 8)
-		div = 8;
-	rate2 = (48000 + div/2) / div;
-	spin_lock_irqsave(&s->lock, flags);
-	wrindir(s, SV_CIADCALTSR, (div-1) << 4);
-	if (abs((signed)(rate-rate2)) <= abs((signed)(rate-rate1))) {
-		wrindir(s, SV_CIADCCLKSOURCE, 0x10);
-		s->rateadc = rate2;
-	} else {
-		wrindir(s, SV_CIADCCLKSOURCE, 0x00);
-		s->rateadc = rate1;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct sv_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->enable &= ~SV_CENABLE_RE;
-	wrindir(s, SV_CIENABLE, s->enable);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static inline void stop_dac(struct sv_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->enable &= ~(SV_CENABLE_PPE | SV_CENABLE_PE);
-	wrindir(s, SV_CIENABLE, s->enable);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_dac(struct sv_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-		s->enable = (s->enable & ~SV_CENABLE_PPE) | SV_CENABLE_PE;
-		wrindir(s, SV_CIENABLE, s->enable);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_adc(struct sv_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-	    && s->dma_adc.ready) {
-		s->enable |= SV_CENABLE_RE;
-		wrindir(s, SV_CIENABLE, s->enable);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static void dealloc_dmabuf(struct sv_state *s, struct dmabuf *db)
-{
-	struct page *page, *pend;
-
-	if (db->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			ClearPageReserved(page);
-		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-	}
-	db->rawbuf = NULL;
-	db->mapped = db->ready = 0;
-}
-
-
-/* DMAA is used for playback, DMAC is used for recording */
-
-static int prog_dmabuf(struct sv_state *s, unsigned rec)
-{
-	struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-	unsigned rate = rec ? s->rateadc : s->ratedac;
-	int order;
-	unsigned bytepersec;
-	unsigned bufs;
-	struct page *page, *pend;
-	unsigned char fmt;
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	fmt = s->fmt;
-	if (rec) {
-		s->enable &= ~SV_CENABLE_RE;
-		fmt >>= SV_CFMT_CSHIFT;
-	} else {
-		s->enable &= ~SV_CENABLE_PE;
-		fmt >>= SV_CFMT_ASHIFT;
-	}
-	wrindir(s, SV_CIENABLE, s->enable);
-	spin_unlock_irqrestore(&s->lock, flags);
-	fmt &= SV_CFMT_MASK;
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-				break;
-		if (!db->rawbuf)
-			return -ENOMEM;
-		db->buforder = order;
-		if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
-			printk(KERN_DEBUG "sv: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
-			       virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
-		if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
-			printk(KERN_DEBUG "sv: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
-			       virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
-		/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			SetPageReserved(page);
-	}
-	bytepersec = rate << sample_shift[fmt];
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < bytepersec)
-			db->fragshift = ld2(bytepersec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3;
-	}
-	db->numfrag = bufs >> db->fragshift;
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->numfrag = bufs >> db->fragshift;
-	}
-	db->fragsize = 1 << db->fragshift;
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
-	db->fragsamples = db->fragsize >> sample_shift[fmt];
-	db->dmasize = db->numfrag << db->fragshift;
-	memset(db->rawbuf, (fmt & SV_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
-	spin_lock_irqsave(&s->lock, flags);
-	if (rec) {
-		set_dmac(s, db->dmaaddr, db->numfrag << db->fragshift);
-		/* program enhanced mode registers */
-		wrindir(s, SV_CIDMACBASECOUNT1, (db->fragsamples-1) >> 8);
-		wrindir(s, SV_CIDMACBASECOUNT0, db->fragsamples-1);
-	} else {
-		set_dmaa(s, db->dmaaddr, db->numfrag << db->fragshift);
-		/* program enhanced mode registers */
-		wrindir(s, SV_CIDMAABASECOUNT1, (db->fragsamples-1) >> 8);
-		wrindir(s, SV_CIDMAABASECOUNT0, db->fragsamples-1);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	db->enabled = 1;
-	db->ready = 1;
-	return 0;
-}
-
-static inline void clear_advance(struct sv_state *s)
-{
-	unsigned char c = (s->fmt & (SV_CFMT_16BIT << SV_CFMT_ASHIFT)) ? 0 : 0x80;
-	unsigned char *buf = s->dma_dac.rawbuf;
-	unsigned bsize = s->dma_dac.dmasize;
-	unsigned bptr = s->dma_dac.swptr;
-	unsigned len = s->dma_dac.fragsize;
-
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(buf + bptr, c, x);
-		bptr = 0;
-		len -= x;
-	}
-	memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void sv_update_ptr(struct sv_state *s)
-{
-	unsigned hwptr;
-	int diff;
-
-	/* update ADC pointer */
-	if (s->dma_adc.ready) {
-		hwptr = (s->dma_adc.dmasize - get_dmac(s)) % s->dma_adc.dmasize;
-		diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-		s->dma_adc.hwptr = hwptr;
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-			wake_up(&s->dma_adc.wait);
-		if (!s->dma_adc.mapped) {
-			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-				s->enable &= ~SV_CENABLE_RE;
-				wrindir(s, SV_CIENABLE, s->enable);
-				s->dma_adc.error++;
-			}
-		}
-	}
-	/* update DAC pointer */
-	if (s->dma_dac.ready) {
-		hwptr = (s->dma_dac.dmasize - get_dmaa(s)) % s->dma_dac.dmasize;
-		diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-		s->dma_dac.hwptr = hwptr;
-		s->dma_dac.total_bytes += diff;
-		if (s->dma_dac.mapped) {
-			s->dma_dac.count += diff;
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-				wake_up(&s->dma_dac.wait);
-		} else {
-			s->dma_dac.count -= diff;
-			if (s->dma_dac.count <= 0) {
-				s->enable &= ~SV_CENABLE_PE;
-				wrindir(s, SV_CIENABLE, s->enable);
-				s->dma_dac.error++;
-			} else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-				clear_advance(s);
-				s->dma_dac.endcleared = 1;
-			}
-			if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
-				wake_up(&s->dma_dac.wait);
-		}
-	}
-}
-
-/* hold spinlock for the following! */
-static void sv_handle_midi(struct sv_state *s)
-{
-	unsigned char ch;
-	int wake;
-
-	wake = 0;
-	while (!(inb(s->iomidi+1) & 0x80)) {
-		ch = inb(s->iomidi);
-		if (s->midi.icnt < MIDIINBUF) {
-			s->midi.ibuf[s->midi.iwr] = ch;
-			s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-			s->midi.icnt++;
-		}
-		wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.iwait);
-	wake = 0;
-	while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) {
-		outb(s->midi.obuf[s->midi.ord], s->iomidi);
-		s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-		s->midi.ocnt--;
-		if (s->midi.ocnt < MIDIOUTBUF-16)
-			wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.owait);
-}
-
-static irqreturn_t sv_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct sv_state *s = (struct sv_state *)dev_id;
-	unsigned int intsrc;
-	
-	/* fastpath out, to ease interrupt sharing */
-	intsrc = inb(s->ioenh + SV_CODEC_STATUS);
-	if (!(intsrc & (SV_CSTAT_DMAA | SV_CSTAT_DMAC | SV_CSTAT_MIDI)))
-		return IRQ_NONE;
-	spin_lock(&s->lock);
-	sv_update_ptr(s);
-	sv_handle_midi(s);
-	spin_unlock(&s->lock);
-	return IRQ_HANDLED;
-}
-
-static void sv_midi_timer(unsigned long data)
-{
-	struct sv_state *s = (struct sv_state *)data;
-	unsigned long flags;
-	
-	spin_lock_irqsave(&s->lock, flags);
-	sv_handle_midi(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->midi.timer.expires = jiffies+1;
-	add_timer(&s->midi.timer);
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "sv: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-	if (!(s) || (s)->magic != SV_MAGIC) { \
-		printk(invalid_magic);            \
-		return -ENXIO;                    \
-	}                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-#define MT_4          1
-#define MT_5MUTE      2
-#define MT_4MUTEMONO  3
-#define MT_6MUTE      4
-
-static const struct {
-	unsigned left:5;
-	unsigned right:5;
-	unsigned type:3;
-	unsigned rec:3;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-	[SOUND_MIXER_RECLEV] = { SV_CIMIX_ADCINL,    SV_CIMIX_ADCINR,    MT_4,         0 },
-	[SOUND_MIXER_LINE1]  = { SV_CIMIX_AUX1INL,   SV_CIMIX_AUX1INR,   MT_5MUTE,     5 },
-	[SOUND_MIXER_CD]     = { SV_CIMIX_CDINL,     SV_CIMIX_CDINR,     MT_5MUTE,     1 },
-	[SOUND_MIXER_LINE]   = { SV_CIMIX_LINEINL,   SV_CIMIX_LINEINR,   MT_5MUTE,     4 },
-	[SOUND_MIXER_MIC]    = { SV_CIMIX_MICIN,     SV_CIMIX_ADCINL,    MT_4MUTEMONO, 6 },
-	[SOUND_MIXER_SYNTH]  = { SV_CIMIX_SYNTHINL,  SV_CIMIX_SYNTHINR,  MT_5MUTE,     2 },
-	[SOUND_MIXER_LINE2]  = { SV_CIMIX_AUX2INL,   SV_CIMIX_AUX2INR,   MT_5MUTE,     3 },
-	[SOUND_MIXER_VOLUME] = { SV_CIMIX_ANALOGINL, SV_CIMIX_ANALOGINR, MT_5MUTE,     7 },
-	[SOUND_MIXER_PCM]    = { SV_CIMIX_PCMINL,    SV_CIMIX_PCMINR,    MT_6MUTE,     0 }
-};
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-static int return_mixval(struct sv_state *s, unsigned i, int *arg)
-{
-	unsigned long flags;
-	unsigned char l, r, rl, rr;
-
-	spin_lock_irqsave(&s->lock, flags);
-	l = rdindir(s, mixtable[i].left);
-	r = rdindir(s, mixtable[i].right);
-	spin_unlock_irqrestore(&s->lock, flags);
-	switch (mixtable[i].type) {
-	case MT_4:
-		r &= 0xf;
-		l &= 0xf;
-		rl = 10 + 6 * (l & 15);
-		rr = 10 + 6 * (r & 15);
-		break;
-
-	case MT_4MUTEMONO:
-		rl = 55 - 3 * (l & 15);
-		if (r & 0x10)
-			rl += 45;
-		rr = rl;
-		r = l;
-		break;
-
-	case MT_5MUTE:
-	default:
-		rl = 100 - 3 * (l & 31);
-		rr = 100 - 3 * (r & 31);
-		break;
-				
-	case MT_6MUTE:
-		rl = 100 - 3 * (l & 63) / 2;
-		rr = 100 - 3 * (r & 63) / 2;
-		break;
-	}
-	if (l & 0x80)
-		rl = 0;
-	if (r & 0x80)
-		rr = 0;
-	return put_user((rr << 8) | rl, arg);
-}
-
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
-static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = 
-{
-	[SOUND_MIXER_RECLEV] = 1,
-	[SOUND_MIXER_LINE1]  = 2,
-	[SOUND_MIXER_CD]     = 3,
-	[SOUND_MIXER_LINE]   = 4,
-	[SOUND_MIXER_MIC]    = 5,
-	[SOUND_MIXER_SYNTH]  = 6,
-	[SOUND_MIXER_LINE2]  = 7,
-	[SOUND_MIXER_VOLUME] = 8,
-	[SOUND_MIXER_PCM]    = 9
-};
-
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
-static unsigned mixer_recmask(struct sv_state *s)
-{
-	unsigned long flags;
-	int i, j;
-
-	spin_lock_irqsave(&s->lock, flags);
-	j = rdindir(s, SV_CIMIX_ADCINL) >> 5;
-	spin_unlock_irqrestore(&s->lock, flags);
-	j &= 7;
-	for (i = 0; i < SOUND_MIXER_NRDEVICES && mixtable[i].rec != j; i++);
-	return 1 << i;
-}
-
-static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
-{
-	unsigned long flags;
-	int i, val;
-	unsigned char l, r, rl, rr;
-	int __user *p = (int __user *)arg;
-
-	VALIDATE_STATE(s);
-        if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		memset(&info, 0, sizeof(info));
-		strlcpy(info.id, "SonicVibes", sizeof(info.id));
-		strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
-		info.modify_counter = s->mix.modcnt;
-		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == SOUND_OLD_MIXER_INFO) {
-		_old_mixer_info info;
-		memset(&info, 0, sizeof(info));
-		strlcpy(info.id, "SonicVibes", sizeof(info.id));
-		strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
-		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, p);
-	if (cmd == SOUND_MIXER_PRIVATE1) {  /* SRS settings */
-		if (get_user(val, p))
-			return -EFAULT;
-		spin_lock_irqsave(&s->lock, flags);
-		if (val & 1) {
-			if (val & 2) {
-				l = 4 - ((val >> 2) & 7);
-				if (l & ~3)
-					l = 4;
-				r = 4 - ((val >> 5) & 7);
-				if (r & ~3)
-					r = 4;
-				wrindir(s, SV_CISRSSPACE, l);
-				wrindir(s, SV_CISRSCENTER, r);
-			} else
-				wrindir(s, SV_CISRSSPACE, 0x80);
-		}
-		l = rdindir(s, SV_CISRSSPACE);
-		r = rdindir(s, SV_CISRSCENTER);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (l & 0x80)
-			return put_user(0, p);
-		return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, p);
-	}
-	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-			return put_user(mixer_recmask(s), p);
-			
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].type)
-					val |= 1 << i;
-			return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].rec)
-					val |= 1 << i;
-			return put_user(val, p);
-			
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-				if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
-					val |= 1 << i;
-			return put_user(val, p);
-			
-                case SOUND_MIXER_CAPS:
-			return put_user(SOUND_CAP_EXCL_INPUT, p);
-
-		default:
-			i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                                return -EINVAL;
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-			return return_mixval(s, i, p);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-			if (!volidx[i])
-				return -EINVAL;
-			return put_user(s->mix.vol[volidx[i]-1], p);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-		}
-	}
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-		return -EINVAL;
-	s->mix.modcnt++;
-	switch (_IOC_NR(cmd)) {
-	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-		if (get_user(val, p))
-			return -EFAULT;
-		i = hweight32(val);
-		if (i == 0)
-			return 0; /*val = mixer_recmask(s);*/
-		else if (i > 1) 
-			val &= ~mixer_recmask(s);
-		for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-			if (!(val & (1 << i)))
-				continue;
-			if (mixtable[i].rec)
-				break;
-		}
-		if (i == SOUND_MIXER_NRDEVICES)
-			return 0;
-		spin_lock_irqsave(&s->lock, flags);
-		frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5);
-		frobindir(s, SV_CIMIX_ADCINR, 0x1f, mixtable[i].rec << 5);
-		spin_unlock_irqrestore(&s->lock, flags);
-		return 0;
-
-	default:
-		i = _IOC_NR(cmd);
-		if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-			return -EINVAL;
-		if (get_user(val, p))
-			return -EFAULT;
-		l = val & 0xff;
-		r = (val >> 8) & 0xff;
-		if (mixtable[i].type == MT_4MUTEMONO)
-			l = (r + l) / 2;
-		if (l > 100)
-			l = 100;
-		if (r > 100)
-			r = 100;
-		spin_lock_irqsave(&s->lock, flags);
-		switch (mixtable[i].type) {
-		case MT_4:
-			if (l >= 10)
-				l -= 10;
-			if (r >= 10)
-				r -= 10;
-			frobindir(s, mixtable[i].left, 0xf0, l / 6);
-			frobindir(s, mixtable[i].right, 0xf0, l / 6);
-			break;
-
-		case MT_4MUTEMONO:
-			rr = 0;
-			if (l < 10)
-				rl = 0x80;
-			else {
-				if (l >= 55) {
-					rr = 0x10;
-					l -= 45;
-				}
-				rl = (55 - l) / 3;
-			}
-			wrindir(s, mixtable[i].left, rl);
-			frobindir(s, mixtable[i].right, ~0x10, rr);
-			break;
-			
-		case MT_5MUTE:
-			if (l < 7)
-				rl = 0x80;
-			else
-				rl = (100 - l) / 3;
-			if (r < 7)
-				rr = 0x80;
-			else
-				rr = (100 - r) / 3;
-			wrindir(s, mixtable[i].left, rl);
-			wrindir(s, mixtable[i].right, rr);
-			break;
-				
-		case MT_6MUTE:
-			if (l < 6)
-				rl = 0x80;
-			else
-				rl = (100 - l) * 2 / 3;
-			if (r < 6)
-				rr = 0x80;
-			else
-				rr = (100 - r) * 2 / 3;
-			wrindir(s, mixtable[i].left, rl);
-			wrindir(s, mixtable[i].right, rr);
-			break;
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                return return_mixval(s, i, p);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-		if (!volidx[i])
-			return -EINVAL;
-		s->mix.vol[volidx[i]-1] = val;
-		return put_user(s->mix.vol[volidx[i]-1], p);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sv_open_mixdev(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	struct list_head *list;
-	struct sv_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct sv_state, devs);
-		if (s->dev_mixer == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	return nonseekable_open(inode, file);
-}
-
-static int sv_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	
-	VALIDATE_STATE(s);
-	return 0;
-}
-
-static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	return mixer_ioctl((struct sv_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations sv_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= sv_ioctl_mixdev,
-	.open		= sv_open_mixdev,
-	.release	= sv_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct sv_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count, tmo;
-
-	if (s->dma_dac.mapped || !s->dma_dac.ready)
-		return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-		tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
-		tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK];
-		if (!schedule_timeout(tmo + 1))
-			printk(KERN_DEBUG "sv: dma timed out??\n");
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t sv_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-#if 0
-	spin_lock_irqsave(&s->lock, flags);
-	sv_update_ptr(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-#endif
-        add_wait_queue(&s->dma_adc.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		swptr = s->dma_adc.swptr;
-		cnt = s->dma_adc.dmasize-swptr;
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_adc.enabled)
-				start_adc(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			if (!schedule_timeout(HZ)) {
-				printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-				       s->dma_adc.hwptr, s->dma_adc.swptr);
-				stop_adc(s);
-				spin_lock_irqsave(&s->lock, flags);
-				set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-				/* program enhanced mode registers */
-				wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
-				wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1);
-				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_adc.enabled)
-			start_adc(s);
-	}
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-static ssize_t sv_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_dac.mapped)
-		return -ENXIO;
-	if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-#if 0
-	spin_lock_irqsave(&s->lock, flags);
-	sv_update_ptr(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-#endif
-        add_wait_queue(&s->dma_dac.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac.count < 0) {
-			s->dma_dac.count = 0;
-			s->dma_dac.swptr = s->dma_dac.hwptr;
-		}
-		swptr = s->dma_dac.swptr;
-		cnt = s->dma_dac.dmasize-swptr;
-		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-			cnt = s->dma_dac.dmasize - s->dma_dac.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_dac.enabled)
-				start_dac(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			if (!schedule_timeout(HZ)) {
-				printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-				       s->dma_dac.hwptr, s->dma_dac.swptr);
-				stop_dac(s);
-				spin_lock_irqsave(&s->lock, flags);
-				set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-				/* program enhanced mode registers */
-				wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
-				wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1);
-				s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac.swptr = swptr;
-		s->dma_dac.count += cnt;
-		s->dma_dac.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_dac.enabled)
-			start_dac(s);
-	}
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int sv_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready && prog_dmabuf(s, 1))
-			return 0;
-		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready && prog_dmabuf(s, 0))
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	sv_update_ptr(s);
-	if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int sv_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	struct dmabuf *db;
-	int ret = -EINVAL;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf(s, 1)) != 0)
-			goto out;
-		db = &s->dma_dac;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf(s, 0)) != 0)
-			goto out;
-		db = &s->dma_adc;
-	} else 
-		goto out;
-	ret = -EINVAL;
-	if (vma->vm_pgoff != 0)
-		goto out;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder))
-		goto out;
-	ret = -EAGAIN;
-	if (remap_pfn_range(vma, vma->vm_start,
-				virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-				size, vma->vm_page_prot))
-		goto out;
-	db->mapped = 1;
-	ret = 0;
-out:
-	unlock_kernel();
-	return ret;
-}
-
-static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int count;
-	int val, mapped, ret;
-	unsigned char fmtm, fmtd;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-		return 0;
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq(s->irq);
-			s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->irq);
-			s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				set_adc_rate(s, val);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				set_dac_rate(s, val);
-			}
-		}
-		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-		
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-			return -EFAULT;
-		fmtd = 0;
-		fmtm = ~0;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ready = 0;
-			if (val)
-				fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
-			else
-				fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.ready = 0;
-			if (val)
-				fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
-			else
-				fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
-		}
-		set_fmt(s, fmtm, fmtd);
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			fmtd = 0;
-			fmtm = ~0;
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val >= 2)
-					fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
-				else
-					fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val >= 2)
-					fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
-				else
-					fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
-			}
-			set_fmt(s, fmtm, fmtd);
-		}
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) 
-					   : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
-		
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-		
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			fmtd = 0;
-			fmtm = ~0;
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val == AFMT_S16_LE)
-					fmtd |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
-				else
-					fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_CSHIFT);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val == AFMT_S16_LE)
-					fmtd |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
-				else
-					fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_ASHIFT);
-			}
-			set_fmt(s, fmtm, fmtd);
-		}
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) 
-					   : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, p);
-		
-	case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if (file->f_mode & FMODE_READ && s->enable & SV_CENABLE_RE) 
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE) 
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, p);
-		
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-					return ret;
-				s->dma_adc.enabled = 1;
-				start_adc(s);
-			} else {
-				s->dma_adc.enabled = 0;
-				stop_adc(s);
-			}
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-					return ret;
-				s->dma_dac.enabled = 1;
-				start_dac(s);
-			} else {
-				s->dma_dac.enabled = 0;
-				stop_dac(s);
-			}
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		sv_update_ptr(s);
-		abinfo.fragsize = s->dma_dac.fragsize;
-		count = s->dma_dac.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = s->dma_dac.dmasize - count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		sv_update_ptr(s);
-		abinfo.fragsize = s->dma_adc.fragsize;
-		count = s->dma_adc.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-		
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		sv_update_ptr(s);
-                count = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		sv_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-		count = s->dma_adc.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		sv_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-		count = s->dma_dac.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= s->dma_dac.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf(s, 0)))
-				return val;
-			return put_user(s->dma_dac.fragsize, p);
-		}
-		if ((val = prog_dmabuf(s, 1)))
-			return val;
-		return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			s->dma_dac.ossfragshift = val & 0xffff;
-			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac.ossfragshift < 4)
-				s->dma_dac.ossfragshift = 4;
-			if (s->dma_dac.ossfragshift > 15)
-				s->dma_dac.ossfragshift = 15;
-			if (s->dma_dac.ossmaxfrags < 4)
-				s->dma_dac.ossmaxfrags = 4;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE)
-			s->dma_dac.subdivision = val;
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) 
-					   : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) 
-					   : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-	return mixer_ioctl(s, cmd, arg);
-}
-
-static int sv_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned char fmtm = ~0, fmts = 0;
-	struct list_head *list;
-	struct sv_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct sv_state, devs);
-		if (!((s->dev_audio ^ minor) & ~0xf))
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & file->f_mode) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	if (file->f_mode & FMODE_READ) {
-		fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			fmts |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-		s->dma_adc.enabled = 1;
-		set_adc_rate(s, 8000);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_ASHIFT);
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			fmts |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
-		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-		s->dma_dac.enabled = 1;
-		set_dac_rate(s, 8000);
-	}
-	set_fmt(s, fmtm, fmts);
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int sv_release(struct inode *inode, struct file *file)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-		dealloc_dmabuf(s, &s->dma_dac);
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-	}
-	s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations sv_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= sv_read,
-	.write		= sv_write,
-	.poll		= sv_poll,
-	.ioctl		= sv_ioctl,
-	.mmap		= sv_mmap,
-	.open		= sv_open,
-	.release	= sv_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t sv_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-	add_wait_queue(&s->midi.iwait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.ird;
-		cnt = MIDIINBUF - ptr;
-		if (s->midi.icnt < cnt)
-			cnt = s->midi.icnt;
-		if (cnt <= 0)
-                      __set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-                      if (file->f_flags & O_NONBLOCK) {
-                              if (!ret)
-                                      ret = -EAGAIN;
-                              break;
-                      }
-                      schedule();
-                      if (signal_pending(current)) {
-                              if (!ret)
-                                      ret = -ERESTARTSYS;
-                              break;
-                      }
-			continue;
-		}
-		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIINBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.ird = ptr;
-		s->midi.icnt -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		break;
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&s->midi.iwait, &wait);
-	return ret;
-}
-
-static ssize_t sv_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.owr;
-		cnt = MIDIOUTBUF - ptr;
-		if (s->midi.ocnt + cnt > MIDIOUTBUF)
-			cnt = MIDIOUTBUF - s->midi.ocnt;
-		if (cnt <= 0) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			sv_handle_midi(s);
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIOUTBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.owr = ptr;
-		s->midi.ocnt += cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		spin_lock_irqsave(&s->lock, flags);
-		sv_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&s->midi.owait, &wait);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
-		poll_wait(file, &s->midi.owait, wait);
-	if (file->f_mode & FMODE_READ)
-		poll_wait(file, &s->midi.iwait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_mode & FMODE_READ) {
-		if (s->midi.icnt > 0)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->midi.ocnt < MIDIOUTBUF)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int sv_midi_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct sv_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct sv_state, devs);
-		if (s->dev_midi == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-		//outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL);
-		outb(inb(s->ioenh + SV_CODEC_INTMASK) | SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
-		wrindir(s, SV_CIUARTCONTROL, 5); /* output MIDI data to external and internal synth */
-		wrindir(s, SV_CIWAVETABLESRC, 1); /* Wavetable in PC RAM */
-		outb(0xff, s->iomidi+1); /* reset command */
-		outb(0x3f, s->iomidi+1); /* uart command */
-		if (!(inb(s->iomidi+1) & 0x80))
-			inb(s->iomidi);
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		init_timer(&s->midi.timer);
-		s->midi.timer.expires = jiffies+1;
-		s->midi.timer.data = (unsigned long)s;
-		s->midi.timer.function = sv_midi_timer;
-		add_timer(&s->midi.timer);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int sv_midi_release(struct inode *inode, struct file *file)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	unsigned count, tmo;
-
-	VALIDATE_STATE(s);
-
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE) {
-		add_wait_queue(&s->midi.owait, &wait);
-		for (;;) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			spin_lock_irqsave(&s->lock, flags);
-			count = s->midi.ocnt;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (count <= 0)
-				break;
-			if (signal_pending(current))
-				break;
-			if (file->f_flags & O_NONBLOCK) {
-				remove_wait_queue(&s->midi.owait, &wait);
-				set_current_state(TASK_RUNNING);
-				unlock_kernel();
-				return -EBUSY;
-			}
-			tmo = (count * HZ) / 3100;
-			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG "sv: midi timed out??\n");
-		}
-		remove_wait_queue(&s->midi.owait, &wait);
-		set_current_state(TASK_RUNNING);
-	}
-	mutex_lock(&s->open_mutex);
-	s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		outb(inb(s->ioenh + SV_CODEC_INTMASK) & ~SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
-		del_timer(&s->midi.timer);		
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations sv_midi_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= sv_midi_read,
-	.write		= sv_midi_write,
-	.poll		= sv_midi_poll,
-	.open		= sv_midi_open,
-	.release	= sv_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	static const unsigned char op_offset[18] = {
-		0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-		0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-		0x10, 0x11, 0x12, 0x13, 0x14, 0x15
-	};
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	struct dm_fm_voice v;
-	struct dm_fm_note n;
-	struct dm_fm_params p;
-	unsigned int io;
-	unsigned int regb;
-
-	switch (cmd) {		
-	case FM_IOCTL_RESET:
-		for (regb = 0xb0; regb < 0xb9; regb++) {
-			outb(regb, s->iosynth);
-			outb(0, s->iosynth+1);
-			outb(regb, s->iosynth+2);
-			outb(0, s->iosynth+3);
-		}
-		return 0;
-
-	case FM_IOCTL_PLAY_NOTE:
-		if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
-			return -EFAULT;
-		if (n.voice >= 18)
-			return -EINVAL;
-		if (n.voice >= 9) {
-			regb = n.voice - 9;
-			io = s->iosynth+2;
-		} else {
-			regb = n.voice;
-			io = s->iosynth;
-		}
-		outb(0xa0 + regb, io);
-		outb(n.fnum & 0xff, io+1);
-		outb(0xb0 + regb, io);
-		outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
-		return 0;
-
-	case FM_IOCTL_SET_VOICE:
-		if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
-			return -EFAULT;
-		if (v.voice >= 18)
-			return -EINVAL;
-		regb = op_offset[v.voice];
-		io = s->iosynth + ((v.op & 1) << 1);
-		outb(0x20 + regb, io);
-		outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | 
-		     ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
-		outb(0x40 + regb, io);
-		outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
-		outb(0x60 + regb, io);
-		outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
-		outb(0x80 + regb, io);
-		outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
-		outb(0xe0 + regb, io);
-		outb(v.waveform & 0x7, io+1);
-		if (n.voice >= 9) {
-			regb = n.voice - 9;
-			io = s->iosynth+2;
-		} else {
-			regb = n.voice;
-			io = s->iosynth;
-		}
-		outb(0xc0 + regb, io);
-		outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
-		     (v.connection & 1), io+1);
-		return 0;
-		
-	case FM_IOCTL_SET_PARAMS:
-		if (copy_from_user(&p, (void *__user )arg, sizeof(p)))
-			return -EFAULT;
-		outb(0x08, s->iosynth);
-		outb((p.kbd_split & 1) << 6, s->iosynth+1);
-		outb(0xbd, s->iosynth);
-		outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
-		     ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1);
-		return 0;
-
-	case FM_IOCTL_SET_OPL:
-		outb(4, s->iosynth+2);
-		outb(arg, s->iosynth+3);
-		return 0;
-
-	case FM_IOCTL_SET_MODE:
-		outb(5, s->iosynth+2);
-		outb(arg & 1, s->iosynth+3);
-		return 0;
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static int sv_dmfm_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	struct list_head *list;
-	struct sv_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct sv_state, devs);
-		if (s->dev_dmfm == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & FMODE_DMFM) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	/* init the stuff */
-	outb(1, s->iosynth);
-	outb(0x20, s->iosynth+1); /* enable waveforms */
-	outb(4, s->iosynth+2);
-	outb(0, s->iosynth+3);  /* no 4op enabled */
-	outb(5, s->iosynth+2);
-	outb(1, s->iosynth+3);  /* enable OPL3 */
-	s->open_mode |= FMODE_DMFM;
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int sv_dmfm_release(struct inode *inode, struct file *file)
-{
-	struct sv_state *s = (struct sv_state *)file->private_data;
-	unsigned int regb;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	mutex_lock(&s->open_mutex);
-	s->open_mode &= ~FMODE_DMFM;
-	for (regb = 0xb0; regb < 0xb9; regb++) {
-		outb(regb, s->iosynth);
-		outb(0, s->iosynth+1);
-		outb(regb, s->iosynth+2);
-		outb(0, s->iosynth+3);
-	}
-	wake_up(&s->open_wait);
-	mutex_unlock(&s->open_mutex);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations sv_dmfm_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= sv_dmfm_ioctl,
-	.open		= sv_dmfm_open,
-	.release	= sv_dmfm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int reverb[NR_DEVICE];
-
-#if 0
-static int wavetable[NR_DEVICE];
-#endif
-
-static unsigned int devindex;
-
-module_param_array(reverb, bool, NULL, 0);
-MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM");
-#if 0
-MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled");
-#endif
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("S3 SonicVibes Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-	int mixch;
-	int vol;
-} initvol[] __devinitdata = {
-	{ SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE1, 0x4040 },
-	{ SOUND_MIXER_WRITE_CD, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE, 0x4040 },
-	{ SOUND_MIXER_WRITE_MIC, 0x4040 },
-	{ SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE2, 0x4040 },
-	{ SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-	{ SOUND_MIXER_WRITE_PCM, 0x4040 }
-};
-
-#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
-				 (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit sv_register_gameport(struct sv_state *s, int io_port)
-{
-	struct gameport *gp;
-
-	if (!request_region(io_port, SV_EXTENT_GAME, "S3 SonicVibes Gameport")) {
-		printk(KERN_ERR "sv: gameport io ports are in use\n");
-		return -EBUSY;
-	}
-
-	s->gameport = gp = gameport_allocate_port();
-	if (!gp) {
-		printk(KERN_ERR "sv: can not allocate memory for gameport\n");
-		release_region(io_port, SV_EXTENT_GAME);
-		return -ENOMEM;
-	}
-
-	gameport_set_name(gp, "S3 SonicVibes Gameport");
-	gameport_set_phys(gp, "isa%04x/gameport0", io_port);
-	gp->dev.parent = &s->dev->dev;
-	gp->io = io_port;
-
-	gameport_register_port(gp);
-
-	return 0;
-}
-
-static inline void sv_unregister_gameport(struct sv_state *s)
-{
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, SV_EXTENT_GAME);
-	}
-}
-#else
-static inline int sv_register_gameport(struct sv_state *s, int io_port) { return -ENOSYS; }
-static inline void sv_unregister_gameport(struct sv_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-	static char __devinitdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
-       	struct sv_state *s;
-	mm_segment_t fs;
-	int i, val, ret;
-	int gpio;
-	char *ddmaname;
-	unsigned ddmanamelen;
-
-	if ((ret=pci_enable_device(pcidev)))
-		return ret;
-
-	if (!RSRCISIOREGION(pcidev, RESOURCE_SB) ||
-	    !RSRCISIOREGION(pcidev, RESOURCE_ENH) ||
-	    !RSRCISIOREGION(pcidev, RESOURCE_SYNTH) ||
-	    !RSRCISIOREGION(pcidev, RESOURCE_MIDI) ||
-	    !RSRCISIOREGION(pcidev, RESOURCE_GAME))
-		return -ENODEV;
-	if (pcidev->irq == 0)
-		return -ENODEV;
-	if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK)) {
-		printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n");
-		return -ENODEV;
-	}
-	/* try to allocate a DDMA resource if not already available */
-	if (!RSRCISIOREGION(pcidev, RESOURCE_DDMA)) {
-		pcidev->resource[RESOURCE_DDMA].start = 0;
-		pcidev->resource[RESOURCE_DDMA].end = 2*SV_EXTENT_DMA-1;
-		pcidev->resource[RESOURCE_DDMA].flags = PCI_BASE_ADDRESS_SPACE_IO | IORESOURCE_IO;
-		ddmanamelen = strlen(sv_ddma_name)+1;
-		if (!(ddmaname = kmalloc(ddmanamelen, GFP_KERNEL)))
-			return -1;
-		memcpy(ddmaname, sv_ddma_name, ddmanamelen);
-		pcidev->resource[RESOURCE_DDMA].name = ddmaname;
-		if (pci_assign_resource(pcidev, RESOURCE_DDMA)) {
-			pcidev->resource[RESOURCE_DDMA].name = NULL;
-			kfree(ddmaname);
-			printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n");
-			return -EBUSY;
-		}
-	}
-	if (!(s = kmalloc(sizeof(struct sv_state), GFP_KERNEL))) {
-		printk(KERN_WARNING "sv: out of memory\n");
-		return -ENOMEM;
-	}
-	memset(s, 0, sizeof(struct sv_state));
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac.wait);
-	init_waitqueue_head(&s->open_wait);
-	init_waitqueue_head(&s->midi.iwait);
-	init_waitqueue_head(&s->midi.owait);
-	mutex_init(&s->open_mutex);
-	spin_lock_init(&s->lock);
-	s->magic = SV_MAGIC;
-	s->dev = pcidev;
-	s->iosb = pci_resource_start(pcidev, RESOURCE_SB);
-	s->ioenh = pci_resource_start(pcidev, RESOURCE_ENH);
-	s->iosynth = pci_resource_start(pcidev, RESOURCE_SYNTH);
-	s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI);
-	s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA);
-	s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
-	gpio = pci_resource_start(pcidev, RESOURCE_GAME);
-	pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9);  /* enable and use extended mode */
-	pci_write_config_dword(pcidev, 0x48, s->iodmac | 9);  /* enable */
-	printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#x %#x %#x\n",
-	       s->iosb, s->ioenh, s->iosynth, s->iomidi, gpio, s->iodmaa, s->iodmac);
-	s->irq = pcidev->irq;
-	
-	/* hack */
-	pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12);  /* wavetable base address */
-
-	ret = -EBUSY;
-	if (!request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM")) {
-		printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1);
-		goto err_region5;
-	}
-	if (!request_region(s->iodmaa, SV_EXTENT_DMA, "S3 SonicVibes DMAA")) {
-		printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmaa, s->iodmaa+SV_EXTENT_DMA-1);
-		goto err_region4;
-	}
-	if (!request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC")) {
-		printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmac, s->iodmac+SV_EXTENT_DMA-1);
-		goto err_region3;
-	}
-	if (!request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi")) {
-		printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1);
-		goto err_region2;
-	}
-	if (!request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth")) {
-		printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1);
-		goto err_region1;
-	}
-
-	/* initialize codec registers */
-	outb(0x80, s->ioenh + SV_CODEC_CONTROL); /* assert reset */
-	udelay(50);
-	outb(0x00, s->ioenh + SV_CODEC_CONTROL); /* deassert reset */
-	udelay(50);
-	outb(SV_CCTRL_INTADRIVE | SV_CCTRL_ENHANCED /*| SV_CCTRL_WAVETABLE */
-	     | (reverb[devindex] ? SV_CCTRL_REVERB : 0), s->ioenh + SV_CODEC_CONTROL);
-	inb(s->ioenh + SV_CODEC_STATUS); /* clear ints */
-	wrindir(s, SV_CIDRIVECONTROL, 0);  /* drive current 16mA */
-	wrindir(s, SV_CIENABLE, s->enable = 0);  /* disable DMAA and DMAC */
-	outb(~(SV_CINTMASK_DMAA | SV_CINTMASK_DMAC), s->ioenh + SV_CODEC_INTMASK);
-	/* outb(0xff, s->iodmaa + SV_DMA_RESET); */
-	/* outb(0xff, s->iodmac + SV_DMA_RESET); */
-	inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
-	wrindir(s, SV_CIADCCLKSOURCE, 0); /* use pll as ADC clock source */
-	wrindir(s, SV_CIANALOGPWRDOWN, 0); /* power up the analog parts of the device */
-	wrindir(s, SV_CIDIGITALPWRDOWN, 0); /* power up the digital parts of the device */
-	setpll(s, SV_CIADCPLLM, 8000);
-	wrindir(s, SV_CISRSSPACE, 0x80); /* SRS off */
-	wrindir(s, SV_CIPCMSR0, (8000 * 65536 / FULLRATE) & 0xff);
-	wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff);
-	wrindir(s, SV_CIADCOUTPUT, 0);
-	/* request irq */
-	if ((ret=request_irq(s->irq,sv_interrupt,IRQF_SHARED,"S3 SonicVibes",s))) {
-		printk(KERN_ERR "sv: irq %u in use\n", s->irq);
-		goto err_irq;
-	}
-	printk(KERN_INFO "sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n",
-	       s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION));
-	/* register devices */
-	if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0) {
-		ret = s->dev_audio;
-		goto err_dev1;
-	}
-	if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops, -1)) < 0) {
-		ret = s->dev_mixer;
-		goto err_dev2;
-	}
-	if ((s->dev_midi = register_sound_midi(&sv_midi_fops, -1)) < 0) {
-		ret = s->dev_midi;
-		goto err_dev3;
-	}
-	if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0) {
-		ret = s->dev_dmfm;
-		goto err_dev4;
-	}
-	pci_set_master(pcidev);  /* enable bus mastering */
-	/* initialize the chips */
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	val = SOUND_MASK_LINE|SOUND_MASK_SYNTH;
-	mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-	for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-		val = initvol[i].vol;
-		mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-	}
-	set_fs(fs);
-	/* register gameport */
-	sv_register_gameport(s, gpio);
-	/* store it in the driver field */
-	pci_set_drvdata(pcidev, s);
-	/* put it into driver list */
-	list_add_tail(&s->devs, &devs);
-	/* increment devindex */
-	if (devindex < NR_DEVICE-1)
-		devindex++;
-	return 0;
-
- err_dev4:
-	unregister_sound_midi(s->dev_midi);
- err_dev3:
-	unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-	unregister_sound_dsp(s->dev_audio);
- err_dev1:
-	printk(KERN_ERR "sv: cannot register misc device\n");
-	free_irq(s->irq, s);
- err_irq:
-	release_region(s->iosynth, SV_EXTENT_SYNTH);
- err_region1:
-	release_region(s->iomidi, SV_EXTENT_MIDI);
- err_region2:
-	release_region(s->iodmac, SV_EXTENT_DMA);
- err_region3:
-	release_region(s->iodmaa, SV_EXTENT_DMA);
- err_region4:
-	release_region(s->ioenh, SV_EXTENT_ENH);
- err_region5:
-	kfree(s);
-	return ret;
-}
-
-static void __devexit sv_remove(struct pci_dev *dev)
-{
-	struct sv_state *s = pci_get_drvdata(dev);
-
-	if (!s)
-		return;
-	list_del(&s->devs);
-	outb(~0, s->ioenh + SV_CODEC_INTMASK);  /* disable ints */
-	synchronize_irq(s->irq);
-	inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
-	wrindir(s, SV_CIENABLE, 0);     /* disable DMAA and DMAC */
-	/*outb(0, s->iodmaa + SV_DMA_RESET);*/
-	/*outb(0, s->iodmac + SV_DMA_RESET);*/
-	free_irq(s->irq, s);
-	sv_unregister_gameport(s);
-	release_region(s->iodmac, SV_EXTENT_DMA);
-	release_region(s->iodmaa, SV_EXTENT_DMA);
-	release_region(s->ioenh, SV_EXTENT_ENH);
-	release_region(s->iomidi, SV_EXTENT_MIDI);
-	release_region(s->iosynth, SV_EXTENT_SYNTH);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->dev_mixer);
-	unregister_sound_midi(s->dev_midi);
-	unregister_sound_special(s->dev_dmfm);
-	kfree(s);
-	pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SONICVIBES, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver sv_driver = {
-       .name		= "sonicvibes",
-       .id_table	= id_table,
-       .probe		= sv_probe,
-       .remove		= __devexit_p(sv_remove),
-};
- 
-static int __init init_sonicvibes(void)
-{
-	printk(KERN_INFO "sv: version v0.31 time " __TIME__ " " __DATE__ "\n");
-#if 0
-	if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
-		printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
-#endif
-	return pci_register_driver(&sv_driver);
-}
-
-static void __exit cleanup_sonicvibes(void)
-{
-	printk(KERN_INFO "sv: unloading\n");
-	pci_unregister_driver(&sv_driver);
- 	if (wavetable_mem)
-		free_pages(wavetable_mem, 20-PAGE_SHIFT);
-}
-
-module_init(init_sonicvibes);
-module_exit(cleanup_sonicvibes);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */
-
-static int __init sonicvibes_setup(char *str)
-{
-	static unsigned __initdata nr_dev = 0;
-
-	if (nr_dev >= NR_DEVICE)
-		return 0;
-#if 0
-	if (get_option(&str, &reverb[nr_dev]) == 2)
-		(void)get_option(&str, &wavetable[nr_dev]);
-#else
-	(void)get_option(&str, &reverb[nr_dev]);
-#endif
-
-	nr_dev++;
-	return 1;
-}
-
-__setup("sonicvibes=", sonicvibes_setup);
-
-#endif /* MODULE */
diff --git a/sound/oss/sound_calls.h b/sound/oss/sound_calls.h
index 1ae0750..87d8ad4 100644
--- a/sound/oss/sound_calls.h
+++ b/sound/oss/sound_calls.h
@@ -13,8 +13,6 @@
 void DMAbuf_init(int dev, int dma1, int dma2);
 void DMAbuf_deinit(int dev);
 int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode);
-int DMAbuf_open_dma (int dev);
-void DMAbuf_close_dma (int dev);
 void DMAbuf_inputintr(int dev);
 void DMAbuf_outputintr(int dev, int underflow_flag);
 struct dma_buffparms;
@@ -73,7 +71,6 @@
 int MIDIbuf_avail(int dev);
 
 void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
-void MIDIbuf_init(void);
 
 
 /*	From soundcard.c	*/
diff --git a/sound/oss/sound_syms.c b/sound/oss/sound_syms.c
deleted file mode 100644
index cb7c33f..0000000
--- a/sound/oss/sound_syms.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *	The sound core exports the following symbols to the rest of
- *	modulespace.
- *
- *      (C) Copyright 1997      Alan Cox, Licensed under the GNU GPL
- *
- *	Thu May 27 1999 Andrew J. Kroll <ag784@freenet..buffalo..edu>
- *	left out exported symbol... fixed
- */
-
-#include <linux/module.h>
-#include "sound_config.h"
-#include "sound_calls.h"
-
-char sound_syms_symbol;
-
-EXPORT_SYMBOL(mixer_devs);
-EXPORT_SYMBOL(audio_devs);
-EXPORT_SYMBOL(num_mixers);
-EXPORT_SYMBOL(num_audiodevs);
-
-EXPORT_SYMBOL(midi_devs);
-EXPORT_SYMBOL(num_midis);
-EXPORT_SYMBOL(synth_devs);
-
-EXPORT_SYMBOL(sound_timer_devs);
-
-EXPORT_SYMBOL(sound_install_audiodrv);
-EXPORT_SYMBOL(sound_install_mixer);
-EXPORT_SYMBOL(sound_alloc_dma);
-EXPORT_SYMBOL(sound_free_dma);
-EXPORT_SYMBOL(sound_open_dma);
-EXPORT_SYMBOL(sound_close_dma);
-EXPORT_SYMBOL(sound_alloc_mididev);
-EXPORT_SYMBOL(sound_alloc_mixerdev);
-EXPORT_SYMBOL(sound_alloc_timerdev);
-EXPORT_SYMBOL(sound_alloc_synthdev);
-EXPORT_SYMBOL(sound_unload_audiodev);
-EXPORT_SYMBOL(sound_unload_mididev);
-EXPORT_SYMBOL(sound_unload_mixerdev);
-EXPORT_SYMBOL(sound_unload_timerdev);
-EXPORT_SYMBOL(sound_unload_synthdev);
-
-EXPORT_SYMBOL(load_mixer_volumes);
-
-EXPORT_SYMBOL(conf_printf);
-EXPORT_SYMBOL(conf_printf2);
-
-MODULE_DESCRIPTION("OSS Sound subsystem");
-MODULE_AUTHOR("Hannu Savolainen, et al.");
diff --git a/sound/oss/sound_timer.c b/sound/oss/sound_timer.c
index bc2777d..f0f0c19 100644
--- a/sound/oss/sound_timer.c
+++ b/sound/oss/sound_timer.c
@@ -1,5 +1,5 @@
 /*
- * sound/sound_timer.c
+ * sound/oss/sound_timer.c
  */
 /*
  * Copyright (C) by Hannu Savolainen 1993-1997
@@ -76,6 +76,7 @@
 	tmr_ctr = 0;
 	usecs_per_tmr = new_usecs;
 }
+EXPORT_SYMBOL(sound_timer_syncinterval);
 
 static void tmr_reset(void)
 {
@@ -300,6 +301,7 @@
 	}
 	spin_unlock_irqrestore(&lock,flags);
 }
+EXPORT_SYMBOL(sound_timer_interrupt);
 
 void  sound_timer_init(struct sound_lowlev_timer *t, char *name)
 {
@@ -321,3 +323,5 @@
 	strcpy(sound_timer.info.name, name);
 	sound_timer_devs[n] = &sound_timer;
 }
+EXPORT_SYMBOL(sound_timer_init);
+
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 0860d67..2344d09 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/sound/soundcard.c
+ * linux/sound/oss/soundcard.c
  *
  * Sound card driver for Linux
  *
@@ -107,6 +107,7 @@
 		mixer_vols[n].levels[i] = levels[i];
 	return mixer_vols[n].levels;
 }
+EXPORT_SYMBOL(load_mixer_volumes);
 
 static int set_mixer_levels(void __user * arg)
 {
@@ -541,12 +542,6 @@
 	int             err;
 	int i, j;
 	
-	/* drag in sound_syms.o */
-	{
-		extern char sound_syms_symbol;
-		sound_syms_symbol = 0;
-	}
-
 #ifdef CONFIG_PCI
 	if(dmabug)
 		isa_dma_bridge_buggy = dmabug;
@@ -614,6 +609,8 @@
 module_init(oss_init);
 module_exit(oss_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("OSS Sound subsystem");
+MODULE_AUTHOR("Hannu Savolainen, et al.");
 
 
 int sound_alloc_dma(int chn, char *deviceID)
@@ -627,6 +624,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(sound_alloc_dma);
 
 int sound_open_dma(int chn, char *deviceID)
 {
@@ -642,6 +640,7 @@
 	dma_alloc_map[chn] = DMA_MAP_BUSY;
 	return 0;
 }
+EXPORT_SYMBOL(sound_open_dma);
 
 void sound_free_dma(int chn)
 {
@@ -652,6 +651,7 @@
 	free_dma(chn);
 	dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
 }
+EXPORT_SYMBOL(sound_free_dma);
 
 void sound_close_dma(int chn)
 {
@@ -661,6 +661,7 @@
 	}
 	dma_alloc_map[chn] = DMA_MAP_FREE;
 }
+EXPORT_SYMBOL(sound_close_dma);
 
 static void do_sequencer_timer(unsigned long dummy)
 {
@@ -714,6 +715,7 @@
 	printk("\n");
 #endif
 }
+EXPORT_SYMBOL(conf_printf);
 
 void conf_printf2(char *name, int base, int irq, int dma, int dma2)
 {
@@ -734,3 +736,5 @@
 	printk("\n");
 #endif
 }
+EXPORT_SYMBOL(conf_printf2);
+
diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c
index 9ed5211..51f2fa6 100644
--- a/sound/oss/sscape.c
+++ b/sound/oss/sscape.c
@@ -1,5 +1,5 @@
 /*
- * sound/sscape.c
+ * sound/oss/sscape.c
  *
  * Low level driver for Ensoniq SoundScape
  *
diff --git a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c
index c9d0451..1075344 100644
--- a/sound/oss/sys_timer.c
+++ b/sound/oss/sys_timer.c
@@ -1,5 +1,5 @@
 /*
- * sound/sys_timer.c
+ * sound/oss/sys_timer.c
  *
  * The default timer for the Level 2 sequencer interface
  * Uses the (1/HZ sec) timer of kernel.
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index ce79cd8..147c816 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -1862,7 +1862,7 @@
 	unsigned swptr;
 	int cnt;
 
-	pr_debug("trident: trident_read called, count = %d\n", count);
+	pr_debug("trident: trident_read called, count = %zd\n", count);
 
 	VALIDATE_STATE(state);
 
@@ -1978,7 +1978,7 @@
 	unsigned int copy_count;
 	int lret; /* for lock_set_fmt */
 
-	pr_debug("trident: trident_write called, count = %d\n", count);
+	pr_debug("trident: trident_write called, count = %zd\n", count);
 
 	VALIDATE_STATE(state);
 
diff --git a/sound/oss/trix.c b/sound/oss/trix.c
index d1f1f15..e04169e 100644
--- a/sound/oss/trix.c
+++ b/sound/oss/trix.c
@@ -1,5 +1,5 @@
 /*
- * sound/trix.c
+ * sound/oss/trix.c
  *
  * Low level driver for the MediaTrix AudioTrix Pro
  * (MT-0002-PC Control Chip)
diff --git a/sound/oss/tuning.h b/sound/oss/tuning.h
index 858e1fe..a73e3dd 100644
--- a/sound/oss/tuning.h
+++ b/sound/oss/tuning.h
@@ -1,13 +1,11 @@
-#ifdef SEQUENCER_C
-
-unsigned short semitone_tuning[24] = 
+static unsigned short semitone_tuning[24] =
 {
 /*   0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, 
 /*   8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784, 
 /*  16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755
 };
 
-unsigned short cent_tuning[100] =
+static unsigned short cent_tuning[100] =
 {
 /*   0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041, 
 /*   8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087, 
@@ -23,7 +21,3 @@
 /*  88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564, 
 /*  96 */ 10570, 10576, 10582, 10589
 };
-#else
-extern unsigned short semitone_tuning[24];
-extern unsigned short cent_tuning[100];
-#endif
diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c
index a3d75ba..8e18b6e 100644
--- a/sound/oss/uart401.c
+++ b/sound/oss/uart401.c
@@ -1,5 +1,5 @@
 /*
- * sound/uart401.c
+ * sound/oss/uart401.c
  *
  * MPU-401 UART driver (formerly uart401_midi.c)
  *
diff --git a/sound/oss/uart6850.c b/sound/oss/uart6850.c
index 74ae75f..501d3e6 100644
--- a/sound/oss/uart6850.c
+++ b/sound/oss/uart6850.c
@@ -1,5 +1,5 @@
 /*
- * sound/uart6850.c
+ * sound/oss/uart6850.c
  *
  *
  * Copyright (C) by Hannu Savolainen 1993-1997
diff --git a/sound/oss/v_midi.c b/sound/oss/v_midi.c
index a7ef04f..d952b22 100644
--- a/sound/oss/v_midi.c
+++ b/sound/oss/v_midi.c
@@ -1,5 +1,5 @@
 /*
- * sound/v_midi.c
+ * sound/oss/v_midi.c
  *
  * The low level driver for the Sound Blaster DS chips.
  *
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index 22d2662..59a2f28 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/sound/waveartist.c
+ * linux/sound/oss/waveartist.c
  *
  * The low level driver for the RWA010 Rockwell Wave Artist
  * codec chip used in the Rebel.com NetWinder.
diff --git a/sound/oss/waveartist.h b/sound/oss/waveartist.h
index 2033fb8..dac4ca9 100644
--- a/sound/oss/waveartist.h
+++ b/sound/oss/waveartist.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/sound/waveartist.h
+ * linux/sound/oss/waveartist.h
  *
  * def file for Rockwell RWA010 chip set, as installed in Rebel.com NetWinder
  */
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
deleted file mode 100644
index 1dec395..0000000
--- a/sound/oss/wavfront.c
+++ /dev/null
@@ -1,3554 +0,0 @@
-/*  -*- linux-c -*-
- *
- * sound/wavfront.c
- *
- * A Linux driver for Turtle Beach WaveFront Series (Maui, Tropez, Tropez Plus)
- *
- * This driver supports the onboard wavetable synthesizer (an ICS2115),
- * including patch, sample and program loading and unloading, conversion
- * of GUS patches during loading, and full user-level access to all
- * WaveFront commands. It tries to provide semi-intelligent patch and
- * sample management as well.
- *
- * It also provides support for the ICS emulation of an MPU-401.  Full
- * support for the ICS emulation's "virtual MIDI mode" is provided in
- * wf_midi.c.
- *
- * Support is also provided for the Tropez Plus' onboard FX processor,
- * a Yamaha YSS225. Currently, code exists to configure the YSS225,
- * and there is an interface allowing tweaking of any of its memory
- * addresses. However, I have been unable to decipher the logical
- * positioning of the configuration info for various effects, so for
- * now, you just get the YSS225 in the same state as Turtle Beach's
- * "SETUPSND.EXE" utility leaves it.
- *
- * The boards' DAC/ADC (a Crystal CS4232) is supported by cs4232.[co],
- * This chip also controls the configuration of the card: the wavefront
- * synth is logical unit 4.
- *
- *
- * Supported devices:
- *
- *   /dev/dsp                      - using cs4232+ad1848 modules, OSS compatible
- *   /dev/midiNN and /dev/midiNN+1 - using wf_midi code, OSS compatible
- *   /dev/synth00                  - raw synth interface
- * 
- **********************************************************************
- *
- * Copyright (C) by Paul Barton-Davis 1998
- *
- * Some portions of this file are taken from work that is
- * copyright (C) by Hannu Savolainen 1993-1996
- *
- * Although the relevant code here is all new, the handling of
- * sample/alias/multi- samples is entirely based on a driver by Matt
- * Martin and Rutger Nijlunsing which demonstrated how to get things
- * to work correctly. The GUS patch loading code has been almost
- * unaltered by me, except to fit formatting and function names in the
- * rest of the file. Many thanks to them.
- *
- * Appreciation and thanks to Hannu Savolainen for his early work on the Maui
- * driver, and answering a few questions while this one was developed.
- *
- * Absolutely NO thanks to Turtle Beach/Voyetra and Yamaha for their
- * complete lack of help in developing this driver, and in particular
- * for their utter silence in response to questions about undocumented
- * aspects of configuring a WaveFront soundcard, particularly the
- * effects processor.
- *
- * $Id: wavfront.c,v 0.7 1998/09/09 15:47:36 pbd Exp $
- *
- * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000	Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *		Added some __init and __initdata to entries in yss225.c
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/ptrace.h>
-#include <linux/fcntl.h>
-#include <linux/syscalls.h>
-#include <linux/ioport.h>    
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/config.h>
-
-#include <linux/delay.h>
-
-#include "sound_config.h"
-
-#include <linux/wavefront.h>
-
-#define _MIDI_SYNTH_C_
-#define MIDI_SYNTH_NAME	"WaveFront MIDI"
-#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-/* Compile-time control of the extent to which OSS is supported.
-
-   I consider /dev/sequencer to be an anachronism, but given its
-   widespread usage by various Linux MIDI software, it seems worth
-   offering support to it if it's not too painful. Instead of using
-   /dev/sequencer, I recommend:
-
-     for synth programming and patch loading: /dev/synthNN
-     for kernel-synchronized MIDI sequencing: the ALSA sequencer
-     for direct MIDI control: /dev/midiNN
-
-   I have never tried static compilation into the kernel. The #if's
-   for this are really just notes to myself about what the code is
-   for.
-*/
-
-#define OSS_SUPPORT_SEQ            0x1  /* use of /dev/sequencer */
-#define OSS_SUPPORT_STATIC_INSTALL 0x2  /* static compilation into kernel */
-
-#define OSS_SUPPORT_LEVEL          0x1  /* just /dev/sequencer for now */
-
-#if    OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-static int (*midi_load_patch) (int devno, int format, const char __user *addr,
-			       int offs, int count, int pmgr_flag) = NULL;
-#endif /* OSS_SUPPORT_SEQ */
-
-/* if WF_DEBUG not defined, no run-time debugging messages will
-   be available via the debug flag setting. Given the current
-   beta state of the driver, this will remain set until a future 
-   version.
-*/
-
-#define WF_DEBUG 1
-
-#ifdef WF_DEBUG
-
-/* Thank goodness for gcc's preprocessor ... */
-
-#define DPRINT(cond, format, args...) \
-       if ((dev.debug & (cond)) == (cond)) { \
-	     printk (KERN_DEBUG LOGNAME format, ## args); \
-       }
-#else
-#define DPRINT(cond, format, args...)
-#endif
-
-#define LOGNAME "WaveFront: "
-
-/* bitmasks for WaveFront status port value */
-
-#define STAT_RINTR_ENABLED	0x01
-#define STAT_CAN_READ		0x02
-#define STAT_INTR_READ		0x04
-#define STAT_WINTR_ENABLED	0x10
-#define STAT_CAN_WRITE		0x20
-#define STAT_INTR_WRITE		0x40
-
-/*** Module-accessible parameters ***************************************/
-
-static int wf_raw;     /* we normally check for "raw state" to firmware
-			   loading. if set, then during driver loading, the
-			   state of the board is ignored, and we reset the
-			   board and load the firmware anyway.
-			*/
-		   
-static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
-		          whatever state it is when the driver is loaded.
-		          The default is to download the microprogram and
-		          associated coefficients to set it up for "default"
-		          operation, whatever that means.
-		       */
-
-static int debug_default;  /* you can set this to control debugging
-			      during driver loading. it takes any combination
-			      of the WF_DEBUG_* flags defined in
-			      wavefront.h
-			   */
-
-/* XXX this needs to be made firmware and hardware version dependent */
-
-static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
-					            version of the WaveFront OS
-					          */
-
-static int wait_polls = 2000; /* This is a number of tries we poll the
-				 status register before resorting to sleeping.
-				 WaveFront being an ISA card each poll takes
-				 about 1.2us. So before going to
-			         sleep we wait up to 2.4ms in a loop.
-			     */
-
-static int sleep_length = HZ/100; /* This says how long we're going to
-				     sleep between polls.
-			             10ms sounds reasonable for fast response.
-			          */
-
-static int sleep_tries = 50;       /* Wait for status 0.5 seconds total. */
-
-static int reset_time = 2; /* hundreths of a second we wait after a HW reset for
-			      the expected interrupt.
-			   */
-
-static int ramcheck_time = 20;    /* time in seconds to wait while ROM code
-			             checks on-board RAM.
-			          */
-
-static int osrun_time = 10;  /* time in seconds we wait for the OS to
-			        start running.
-			     */
-
-module_param(wf_raw, int, 0);
-module_param(fx_raw, int, 0);
-module_param(debug_default, int, 0);
-module_param(wait_polls, int, 0);
-module_param(sleep_length, int, 0);
-module_param(sleep_tries, int, 0);
-module_param(ospath, charp, 0);
-module_param(reset_time, int, 0);
-module_param(ramcheck_time, int, 0);
-module_param(osrun_time, int, 0);
-
-/***************************************************************************/
-
-/* Note: because this module doesn't export any symbols, this really isn't
-   a global variable, even if it looks like one. I was quite confused by
-   this when I started writing this as a (newer) module -- pbd.
-*/
-
-struct wf_config {
-	int devno;            /* device number from kernel */
-	int irq;              /* "you were one, one of the few ..." */
-	int base;             /* low i/o port address */
-
-#define mpu_data_port    base 
-#define mpu_command_port base + 1 /* write semantics */
-#define mpu_status_port  base + 1 /* read semantics */
-#define data_port        base + 2 
-#define status_port      base + 3 /* read semantics */
-#define control_port     base + 3 /* write semantics  */
-#define block_port       base + 4 /* 16 bit, writeonly */
-#define last_block_port  base + 6 /* 16 bit, writeonly */
-
-	/* FX ports. These are mapped through the ICS2115 to the YS225.
-	   The ICS2115 takes care of flipping the relevant pins on the
-	   YS225 so that access to each of these ports does the right
-	   thing. Note: these are NOT documented by Turtle Beach.
-	*/
-
-#define fx_status       base + 8 
-#define fx_op           base + 8 
-#define fx_lcr          base + 9 
-#define fx_dsp_addr     base + 0xa
-#define fx_dsp_page     base + 0xb 
-#define fx_dsp_lsb      base + 0xc 
-#define fx_dsp_msb      base + 0xd 
-#define fx_mod_addr     base + 0xe
-#define fx_mod_data     base + 0xf 
-
-	volatile int irq_ok;               /* set by interrupt handler */
-        volatile int irq_cnt;              /* ditto */
-	int opened;                        /* flag, holds open(2) mode */
-	char debug;                        /* debugging flags */
-	int freemem;                       /* installed RAM, in bytes */ 
-
-	int synth_dev;                     /* devno for "raw" synth */
-	int mididev;                       /* devno for internal MIDI */
-	int ext_mididev;                   /* devno for external MIDI */ 
-        int fx_mididev;                    /* devno for FX MIDI interface */
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-	int oss_dev;                      /* devno for OSS sequencer synth */
-#endif /* OSS_SUPPORT_SEQ */
-
-	char fw_version[2];                /* major = [0], minor = [1] */
-	char hw_version[2];                /* major = [0], minor = [1] */
-	char israw;                        /* needs Motorola microcode */
-	char has_fx;                       /* has FX processor (Tropez+) */
-	char prog_status[WF_MAX_PROGRAM];  /* WF_SLOT_* */
-	char patch_status[WF_MAX_PATCH];   /* WF_SLOT_* */
-	char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */
-	int samples_used;                  /* how many */
-	char interrupts_on;                /* h/w MPU interrupts enabled ? */
-	char rom_samples_rdonly;           /* can we write on ROM samples */
-	wait_queue_head_t interrupt_sleeper; 
-} dev;
-
-static DEFINE_SPINLOCK(lock);
-static int  detect_wffx(void);
-static int  wffx_ioctl (wavefront_fx_info *);
-static int  wffx_init (void);
-
-static int wavefront_delete_sample (int sampnum);
-static int wavefront_find_free_sample (void);
-
-/* From wf_midi.c */
-
-extern int  virtual_midi_enable  (void);
-extern int  virtual_midi_disable (void);
-extern int  detect_wf_mpu (int, int);
-extern int  install_wf_mpu (void);
-extern int  uninstall_wf_mpu (void);
-
-typedef struct {
-	int cmd;
-	char *action;
-	unsigned int read_cnt;
-	unsigned int write_cnt;
-	int need_ack;
-} wavefront_command;
-
-static struct {
-	int errno;
-	const char *errstr;
-} wavefront_errors[] = {
-	{ 0x01, "Bad sample number" },
-	{ 0x02, "Out of sample memory" },
-	{ 0x03, "Bad patch number" },
-	{ 0x04, "Error in number of voices" },
-	{ 0x06, "Sample load already in progress" },
-	{ 0x0B, "No sample load request pending" },
-	{ 0x0E, "Bad MIDI channel number" },
-	{ 0x10, "Download Record Error" },
-	{ 0x80, "Success" },
-	{ 0 }
-};
-
-#define NEEDS_ACK 1
-
-static wavefront_command wavefront_commands[] = {
-	{ WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK },
-	{ WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0},
-	{ WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK },
-	{ WFC_GET_NVOICES, "get number of voices", 1, 0, 0 },
-	{ WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK },
-	{ WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 },
-	{ WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK },
-	{ WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK },
-	{ WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 },
-	{ WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK },
-	{ WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK },
-	{ WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK },
-	{ WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK },
-	{ WFC_MIDI_STATUS, "report midi status", 1, 0, 0 },
-	{ WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 },
-	{ WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 },
-	{ WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 },
-	{ WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 },
-	{ WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 },
-	{ WFC_DOWNLOAD_SAMPLE, "download sample",
-	  0, WF_SAMPLE_BYTES, NEEDS_ACK },
-	{ WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK},
-	{ WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header",
-	  0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK },
-	{ WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 },
-
-	/* This command requires a variable number of bytes to be written.
-	   There is a hack in wavefront_cmd() to support this. The actual
-	   count is passed in as the read buffer ptr, cast appropriately.
-	   Ugh.
-	*/
-
-	{ WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK },
-
-	/* This one is a hack as well. We just read the first byte of the
-	   response, don't fetch an ACK, and leave the rest to the 
-	   calling function. Ugly, ugly, ugly.
-	*/
-
-	{ WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 },
-	{ WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias",
-	  0, WF_ALIAS_BYTES, NEEDS_ACK },
-	{ WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0},
-	{ WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK },
-	{ WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 },
-	{ WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" },
-	{ WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 },
-	{ WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK },
-	{ WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 },
-	{ WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK },
-	{ WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 },
-	{ WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9,
-	  NEEDS_ACK},
-	{ WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0},
-	{ WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel",
-	  0, 1, NEEDS_ACK },
-	{ WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK },
-	{ WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers",
-	  32, 0, 0 },
-	{ WFC_NOOP, "the no-op command", 0, 0, NEEDS_ACK },
-	{ 0x00 }
-};
-
-static const char *
-wavefront_errorstr (int errnum)
-
-{
-	int i;
-
-	for (i = 0; wavefront_errors[i].errstr; i++) {
-		if (wavefront_errors[i].errno == errnum) {
-			return wavefront_errors[i].errstr;
-		}
-	}
-
-	return "Unknown WaveFront error";
-}
-
-static wavefront_command *
-wavefront_get_command (int cmd) 
-
-{
-	int i;
-
-	for (i = 0; wavefront_commands[i].cmd != 0; i++) {
-		if (cmd == wavefront_commands[i].cmd) {
-			return &wavefront_commands[i];
-		}
-	}
-
-	return (wavefront_command *) 0;
-}
-
-static inline int
-wavefront_status (void) 
-
-{
-	return inb (dev.status_port);
-}
-
-static int
-wavefront_wait (int mask)
-
-{
-	int i;
-
-	for (i = 0; i < wait_polls; i++)
-		if (wavefront_status() & mask)
-			return 1;
-
-	for (i = 0; i < sleep_tries; i++) {
-
-		if (wavefront_status() & mask) {
-			set_current_state(TASK_RUNNING);
-			return 1;
-		}
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(sleep_length);
-		if (signal_pending(current))
-			break;
-	}
-
-	set_current_state(TASK_RUNNING);
-	return 0;
-}
-
-static int
-wavefront_read (void)
-
-{
-	if (wavefront_wait (STAT_CAN_READ))
-		return inb (dev.data_port);
-
-	DPRINT (WF_DEBUG_DATA, "read timeout.\n");
-
-	return -1;
-}
-
-static int
-wavefront_write (unsigned char data)
-
-{
-	if (wavefront_wait (STAT_CAN_WRITE)) {
-		outb (data, dev.data_port);
-		return 0;
-	}
-
-	DPRINT (WF_DEBUG_DATA, "write timeout.\n");
-
-	return -1;
-}
-
-static int
-wavefront_cmd (int cmd, unsigned char *rbuf, unsigned char *wbuf)
-
-{
-	int ack;
-	int i;
-	int c;
-	wavefront_command *wfcmd;
-
-	if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
-		printk (KERN_WARNING LOGNAME "command 0x%x not supported.\n",
-			cmd);
-		return 1;
-	}
-
-	/* Hack to handle the one variable-size write command. See
-	   wavefront_send_multisample() for the other half of this
-	   gross and ugly strategy.
-	*/
-
-	if (cmd == WFC_DOWNLOAD_MULTISAMPLE) {
-		wfcmd->write_cnt = (unsigned int) rbuf;
-		rbuf = NULL;
-	}
-
-	DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n",
-			       cmd, wfcmd->action, wfcmd->read_cnt,
-			       wfcmd->write_cnt, wfcmd->need_ack);
-    
-	if (wavefront_write (cmd)) { 
-		DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request "
-						     "0x%x [%s].\n",
-						     cmd, wfcmd->action);
-		return 1;
-	} 
-
-	if (wfcmd->write_cnt > 0) {
-		DPRINT (WF_DEBUG_DATA, "writing %d bytes "
-					"for 0x%x\n",
-					wfcmd->write_cnt, cmd);
-
-		for (i = 0; i < wfcmd->write_cnt; i++) {
-			if (wavefront_write (wbuf[i])) {
-				DPRINT (WF_DEBUG_IO, "bad write for byte "
-						      "%d of 0x%x [%s].\n",
-						      i, cmd, wfcmd->action);
-				return 1;
-			}
-
-			DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n",
-						i, wbuf[i]);
-		}
-	}
-
-	if (wfcmd->read_cnt > 0) {
-		DPRINT (WF_DEBUG_DATA, "reading %d ints "
-					"for 0x%x\n",
-					wfcmd->read_cnt, cmd);
-
-		for (i = 0; i < wfcmd->read_cnt; i++) {
-
-			if ((c = wavefront_read()) == -1) {
-				DPRINT (WF_DEBUG_IO, "bad read for byte "
-						      "%d of 0x%x [%s].\n",
-						      i, cmd, wfcmd->action);
-				return 1;
-			}
-
-			/* Now handle errors. Lots of special cases here */
-	    
-			if (c == 0xff) { 
-				if ((c = wavefront_read ()) == -1) {
-					DPRINT (WF_DEBUG_IO, "bad read for "
-							      "error byte at "
-							      "read byte %d "
-							      "of 0x%x [%s].\n",
-							      i, cmd,
-							      wfcmd->action);
-					return 1;
-				}
-
-				/* Can you believe this madness ? */
-
-				if (c == 1 &&
-				    wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) {
-					rbuf[0] = WF_ST_EMPTY;
-					return (0);
-
-				} else if (c == 3 &&
-					   wfcmd->cmd == WFC_UPLOAD_PATCH) {
-
-					return 3;
-
-				} else if (c == 1 &&
-					   wfcmd->cmd == WFC_UPLOAD_PROGRAM) {
-
-					return 1;
-
-				} else {
-
-					DPRINT (WF_DEBUG_IO, "error %d (%s) "
-							      "during "
-							      "read for byte "
-							      "%d of 0x%x "
-							      "[%s].\n",
-							      c,
-							      wavefront_errorstr (c),
-							      i, cmd,
-							      wfcmd->action);
-					return 1;
-
-				}
-		
-		} else {
-				rbuf[i] = c;
-			}
-			
-			DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]);
-		}
-	}
-	
-	if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {
-
-		DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd);
-
-		/* Some commands need an ACK, but return zero instead
-		   of the standard value.
-		*/
-	    
-		if ((ack = wavefront_read()) == 0) {
-			ack = WF_ACK;
-		}
-	
-		if (ack != WF_ACK) {
-			if (ack == -1) {
-				DPRINT (WF_DEBUG_IO, "cannot read ack for "
-						      "0x%x [%s].\n",
-						      cmd, wfcmd->action);
-				return 1;
-		
-			} else {
-				int err = -1; /* something unknown */
-
-				if (ack == 0xff) { /* explicit error */
-		    
-					if ((err = wavefront_read ()) == -1) {
-						DPRINT (WF_DEBUG_DATA,
-							"cannot read err "
-							"for 0x%x [%s].\n",
-							cmd, wfcmd->action);
-					}
-				}
-				
-				DPRINT (WF_DEBUG_IO, "0x%x [%s] "
-					"failed (0x%x, 0x%x, %s)\n",
-					cmd, wfcmd->action, ack, err,
-					wavefront_errorstr (err));
-				
-				return -err;
-			}
-		}
-		
-		DPRINT (WF_DEBUG_DATA, "ack received "
-					"for 0x%x [%s]\n",
-					cmd, wfcmd->action);
-	} else {
-
-		DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need "
-				       "ACK (%d,%d,%d)\n",
-				       cmd, wfcmd->action, wfcmd->read_cnt,
-				       wfcmd->write_cnt, wfcmd->need_ack);
-	}
-
-	return 0;
-	
-}
-
-/***********************************************************************
-WaveFront: data munging   
-
-Things here are weird. All data written to the board cannot 
-have its most significant bit set. Any data item with values 
-potentially > 0x7F (127) must be split across multiple bytes.
-
-Sometimes, we need to munge numeric values that are represented on
-the x86 side as 8-32 bit values. Sometimes, we need to munge data
-that is represented on the x86 side as an array of bytes. The most
-efficient approach to handling both cases seems to be to use 2
-different functions for munging and 2 for de-munging. This avoids
-weird casting and worrying about bit-level offsets.
-
-**********************************************************************/
-
-static 
-unsigned char *
-munge_int32 (unsigned int src,
-	     unsigned char *dst,
-	     unsigned int dst_size)
-{
-	int i;
-
-	for (i = 0;i < dst_size; i++) {
-		*dst = src & 0x7F;  /* Mask high bit of LSB */
-		src = src >> 7;     /* Rotate Right 7 bits  */
-	                            /* Note: we leave the upper bits in place */ 
-
-		dst++;
- 	};
-	return dst;
-};
-
-static int 
-demunge_int32 (unsigned char* src, int src_size)
-
-{
-	int i;
- 	int outval = 0;
-	
- 	for (i = src_size - 1; i >= 0; i--) {
-		outval=(outval<<7)+src[i];
-	}
-
-	return outval;
-};
-
-static 
-unsigned char *
-munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size)
-
-{
-	int i;
-	unsigned int last = dst_size / 2;
-
-	for (i = 0; i < last; i++) {
-		*dst++ = src[i] & 0x7f;
-		*dst++ = src[i] >> 7;
-	}
-	return dst;
-}
-
-static 
-unsigned char *
-demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes)
-
-{
-	int i;
-	unsigned char *end = src + src_bytes;
-    
-	end = src + src_bytes;
-
-	/* NOTE: src and dst *CAN* point to the same address */
-
-	for (i = 0; src != end; i++) {
-		dst[i] = *src++;
-		dst[i] |= (*src++)<<7;
-	}
-
-	return dst;
-}
-
-/***********************************************************************
-WaveFront: sample, patch and program management.
-***********************************************************************/
-
-static int
-wavefront_delete_sample (int sample_num)
-
-{
-	unsigned char wbuf[2];
-	int x;
-
-	wbuf[0] = sample_num & 0x7f;
-	wbuf[1] = sample_num >> 7;
-
-	if ((x = wavefront_cmd (WFC_DELETE_SAMPLE, NULL, wbuf)) == 0) {
-		dev.sample_status[sample_num] = WF_ST_EMPTY;
-	}
-
-	return x;
-}
-
-static int
-wavefront_get_sample_status (int assume_rom)
-
-{
-	int i;
-	unsigned char rbuf[32], wbuf[32];
-	unsigned int    sc_real, sc_alias, sc_multi;
-
-	/* check sample status */
-    
-	if (wavefront_cmd (WFC_GET_NSAMPLES, rbuf, wbuf)) {
-		printk (KERN_WARNING LOGNAME "cannot request sample count.\n");
-		return -1;
-	} 
-    
-	sc_real = sc_alias = sc_multi = dev.samples_used = 0;
-    
-	for (i = 0; i < WF_MAX_SAMPLE; i++) {
-	
-		wbuf[0] = i & 0x7f;
-		wbuf[1] = i >> 7;
-
-		if (wavefront_cmd (WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
-			printk (KERN_WARNING LOGNAME
-				"cannot identify sample "
-				"type of slot %d\n", i);
-			dev.sample_status[i] = WF_ST_EMPTY;
-			continue;
-		}
-
-		dev.sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
-
-		if (assume_rom) {
-			dev.sample_status[i] |= WF_SLOT_ROM;
-		}
-
-		switch (rbuf[0] & WF_ST_MASK) {
-		case WF_ST_SAMPLE:
-			sc_real++;
-			break;
-		case WF_ST_MULTISAMPLE:
-			sc_multi++;
-			break;
-		case WF_ST_ALIAS:
-			sc_alias++;
-			break;
-		case WF_ST_EMPTY:
-			break;
-
-		default:
-			printk (KERN_WARNING LOGNAME "unknown sample type for "
-				"slot %d (0x%x)\n", 
-				i, rbuf[0]);
-		}
-
-		if (rbuf[0] != WF_ST_EMPTY) {
-			dev.samples_used++;
-		} 
-	}
-
-	printk (KERN_INFO LOGNAME
-		"%d samples used (%d real, %d aliases, %d multi), "
-		"%d empty\n", dev.samples_used, sc_real, sc_alias, sc_multi,
-		WF_MAX_SAMPLE - dev.samples_used);
-
-
-	return (0);
-
-}
-
-static int
-wavefront_get_patch_status (void)
-
-{
-	unsigned char patchbuf[WF_PATCH_BYTES];
-	unsigned char patchnum[2];
-	wavefront_patch *p;
-	int i, x, cnt, cnt2;
-
-	for (i = 0; i < WF_MAX_PATCH; i++) {
-		patchnum[0] = i & 0x7f;
-		patchnum[1] = i >> 7;
-
-		if ((x = wavefront_cmd (WFC_UPLOAD_PATCH, patchbuf,
-					patchnum)) == 0) {
-
-			dev.patch_status[i] |= WF_SLOT_FILLED;
-			p = (wavefront_patch *) patchbuf;
-			dev.sample_status
-				[p->sample_number|(p->sample_msb<<7)] |=
-				WF_SLOT_USED;
-	    
-		} else if (x == 3) { /* Bad patch number */
-			dev.patch_status[i] = 0;
-		} else {
-			printk (KERN_ERR LOGNAME "upload patch "
-				"error 0x%x\n", x);
-			dev.patch_status[i] = 0;
-			return 1;
-		}
-	}
-
-	/* program status has already filled in slot_used bits */
-
-	for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
-		if (dev.patch_status[i] & WF_SLOT_FILLED) {
-			cnt++;
-		}
-		if (dev.patch_status[i] & WF_SLOT_USED) {
-			cnt2++;
-		}
-	
-	}
-	printk (KERN_INFO LOGNAME
-		"%d patch slots filled, %d in use\n", cnt, cnt2);
-
-	return (0);
-}
-
-static int
-wavefront_get_program_status (void)
-
-{
-	unsigned char progbuf[WF_PROGRAM_BYTES];
-	wavefront_program prog;
-	unsigned char prognum;
-	int i, x, l, cnt;
-
-	for (i = 0; i < WF_MAX_PROGRAM; i++) {
-		prognum = i;
-
-		if ((x = wavefront_cmd (WFC_UPLOAD_PROGRAM, progbuf,
-					&prognum)) == 0) {
-
-			dev.prog_status[i] |= WF_SLOT_USED;
-
-			demunge_buf (progbuf, (unsigned char *) &prog,
-				     WF_PROGRAM_BYTES);
-
-			for (l = 0; l < WF_NUM_LAYERS; l++) {
-				if (prog.layer[l].mute) {
-					dev.patch_status
-						[prog.layer[l].patch_number] |=
-						WF_SLOT_USED;
-				}
-			}
-		} else if (x == 1) { /* Bad program number */
-			dev.prog_status[i] = 0;
-		} else {
-			printk (KERN_ERR LOGNAME "upload program "
-				"error 0x%x\n", x);
-			dev.prog_status[i] = 0;
-		}
-	}
-
-	for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
-		if (dev.prog_status[i]) {
-			cnt++;
-		}
-	}
-
-	printk (KERN_INFO LOGNAME "%d programs slots in use\n", cnt);
-
-	return (0);
-}
-
-static int
-wavefront_send_patch (wavefront_patch_info *header)
-
-{
-	unsigned char buf[WF_PATCH_BYTES+2];
-	unsigned char *bptr;
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n",
-				      header->number);
-
-	dev.patch_status[header->number] |= WF_SLOT_FILLED;
-
-	bptr = buf;
-	bptr = munge_int32 (header->number, buf, 2);
-	munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
-    
-	if (wavefront_cmd (WFC_DOWNLOAD_PATCH, NULL, buf)) {
-		printk (KERN_ERR LOGNAME "download patch failed\n");
-		return -(EIO);
-	}
-
-	return (0);
-}
-
-static int
-wavefront_send_program (wavefront_patch_info *header)
-
-{
-	unsigned char buf[WF_PROGRAM_BYTES+1];
-	int i;
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n",
-		header->number);
-
-	dev.prog_status[header->number] = WF_SLOT_USED;
-
-	/* XXX need to zero existing SLOT_USED bit for program_status[i]
-	   where `i' is the program that's being (potentially) overwritten.
-	*/
-    
-	for (i = 0; i < WF_NUM_LAYERS; i++) {
-		if (header->hdr.pr.layer[i].mute) {
-			dev.patch_status[header->hdr.pr.layer[i].patch_number] |=
-				WF_SLOT_USED;
-
-			/* XXX need to mark SLOT_USED for sample used by
-			   patch_number, but this means we have to load it. Ick.
-			*/
-		}
-	}
-
-	buf[0] = header->number;
-	munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
-    
-	if (wavefront_cmd (WFC_DOWNLOAD_PROGRAM, NULL, buf)) {
-		printk (KERN_WARNING LOGNAME "download patch failed\n");	
-		return -(EIO);
-	}
-
-	return (0);
-}
-
-static int
-wavefront_freemem (void)
-
-{
-	char rbuf[8];
-
-	if (wavefront_cmd (WFC_REPORT_FREE_MEMORY, rbuf, NULL)) {
-		printk (KERN_WARNING LOGNAME "can't get memory stats.\n");
-		return -1;
-	} else {
-		return demunge_int32 (rbuf, 4);
-	}
-}
-
-static int
-wavefront_send_sample (wavefront_patch_info *header,
-		       UINT16 __user *dataptr,
-		       int data_is_unsigned)
-
-{
-	/* samples are downloaded via a 16-bit wide i/o port
-	   (you could think of it as 2 adjacent 8-bit wide ports
-	   but its less efficient that way). therefore, all
-	   the blocksizes and so forth listed in the documentation,
-	   and used conventionally to refer to sample sizes,
-	   which are given in 8-bit units (bytes), need to be
-	   divided by 2.
-        */
-
-	UINT16 sample_short;
-	UINT32 length;
-	UINT16 __user *data_end = NULL;
-	unsigned int i;
-	const int max_blksize = 4096/2;
-	unsigned int written;
-	unsigned int blocksize;
-	int dma_ack;
-	int blocknum;
-	unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES];
-	unsigned char *shptr;
-	int skip = 0;
-	int initial_skip = 0;
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
-				      "type %d, %d bytes from %p\n",
-				      header->size ? "" : "header ", 
-				      header->number, header->subkey,
-				      header->size,
-				      header->dataptr);
-
-	if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
-		int x;
-
-		if ((x = wavefront_find_free_sample ()) < 0) {
-			return -ENOMEM;
-		}
-		printk (KERN_DEBUG LOGNAME "unspecified sample => %d\n", x);
-		header->number = x;
-	}
-
-	if (header->size) {
-
-		/* XXX it's a debatable point whether or not RDONLY semantics
-		   on the ROM samples should cover just the sample data or
-		   the sample header. For now, it only covers the sample data,
-		   so anyone is free at all times to rewrite sample headers.
-
-		   My reason for this is that we have the sample headers
-		   available in the WFB file for General MIDI, and so these
-		   can always be reset if needed. The sample data, however,
-		   cannot be recovered without a complete reset and firmware
-		   reload of the ICS2115, which is a very expensive operation.
-
-		   So, doing things this way allows us to honor the notion of
-		   "RESETSAMPLES" reasonably cheaply. Note however, that this
-		   is done purely at user level: there is no WFB parser in
-		   this driver, and so a complete reset (back to General MIDI,
-		   or theoretically some other configuration) is the
-		   responsibility of the user level library. 
-
-		   To try to do this in the kernel would be a little
-		   crazy: we'd need 158K of kernel space just to hold
-		   a copy of the patch/program/sample header data.
-		*/
-
-		if (dev.rom_samples_rdonly) {
-			if (dev.sample_status[header->number] & WF_SLOT_ROM) {
-				printk (KERN_ERR LOGNAME "sample slot %d "
-					"write protected\n",
-					header->number);
-				return -EACCES;
-			}
-		}
-
-		wavefront_delete_sample (header->number);
-	}
-
-	if (header->size) {
-		dev.freemem = wavefront_freemem ();
-
-		if (dev.freemem < header->size) {
-			printk (KERN_ERR LOGNAME
-				"insufficient memory to "
-				"load %d byte sample.\n",
-				header->size);
-			return -ENOMEM;
-		}
-	
-	}
-
-	skip = WF_GET_CHANNEL(&header->hdr.s);
-
-	if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) {
-		printk (KERN_ERR LOGNAME "channel selection only "
-			"possible on 16-bit samples");
-		return -(EINVAL);
-	}
-
-	switch (skip) {
-	case 0:
-		initial_skip = 0;
-		skip = 1;
-		break;
-	case 1:
-		initial_skip = 0;
-		skip = 2;
-		break;
-	case 2:
-		initial_skip = 1;
-		skip = 2;
-		break;
-	case 3:
-		initial_skip = 2;
-		skip = 3;
-		break;
-	case 4:
-		initial_skip = 3;
-		skip = 4;
-		break;
-	case 5:
-		initial_skip = 4;
-		skip = 5;
-		break;
-	case 6:
-		initial_skip = 5;
-		skip = 6;
-		break;
-	}
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => "
-				      "initial skip = %d, skip = %d\n",
-				      WF_GET_CHANNEL (&header->hdr.s),
-				      initial_skip, skip);
-    
-	/* Be safe, and zero the "Unused" bits ... */
-
-	WF_SET_CHANNEL(&header->hdr.s, 0);
-
-	/* adjust size for 16 bit samples by dividing by two.  We always
-	   send 16 bits per write, even for 8 bit samples, so the length
-	   is always half the size of the sample data in bytes.
-	*/
-
-	length = header->size / 2;
-
-	/* the data we're sent has not been munged, and in fact, the
-	   header we have to send isn't just a munged copy either.
-	   so, build the sample header right here.
-	*/
-
-	shptr = &sample_hdr[0];
-
-	shptr = munge_int32 (header->number, shptr, 2);
-
-	if (header->size) {
-		shptr = munge_int32 (length, shptr, 4);
-	}
-
-	/* Yes, a 4 byte result doesn't contain all of the offset bits,
-	   but the offset only uses 24 bits.
-	*/
-
-	shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleStartOffset),
-			     shptr, 4);
-	shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopStartOffset),
-			     shptr, 4);
-	shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopEndOffset),
-			     shptr, 4);
-	shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleEndOffset),
-			     shptr, 4);
-	
-	/* This one is truly weird. What kind of weirdo decided that in
-	   a system dominated by 16 and 32 bit integers, they would use
-	   a just 12 bits ?
-	*/
-	
-	shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3);
-	
-	/* Why is this nybblified, when the MSB is *always* zero ? 
-	   Anyway, we can't take address of bitfield, so make a
-	   good-faith guess at where it starts.
-	*/
-	
-	shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
-			     shptr, 2);
-
-	if (wavefront_cmd (header->size ?
-			   WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
-			   NULL, sample_hdr)) {
-		printk (KERN_WARNING LOGNAME "sample %sdownload refused.\n",
-			header->size ? "" : "header ");
-		return -(EIO);
-	}
-
-	if (header->size == 0) {
-		goto sent; /* Sorry. Just had to have one somewhere */
-	}
-    
-	data_end = dataptr + length;
-
-	/* Do any initial skip over an unused channel's data */
-
-	dataptr += initial_skip;
-    
-	for (written = 0, blocknum = 0;
-	     written < length; written += max_blksize, blocknum++) {
-	
-		if ((length - written) > max_blksize) {
-			blocksize = max_blksize;
-		} else {
-			/* round to nearest 16-byte value */
-			blocksize = ((length-written+7)&~0x7);
-		}
-
-		if (wavefront_cmd (WFC_DOWNLOAD_BLOCK, NULL, NULL)) {
-			printk (KERN_WARNING LOGNAME "download block "
-				"request refused.\n");
-			return -(EIO);
-		}
-
-		for (i = 0; i < blocksize; i++) {
-
-			if (dataptr < data_end) {
-		
-				__get_user (sample_short, dataptr);
-				dataptr += skip;
-		
-				if (data_is_unsigned) { /* GUS ? */
-
-					if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) {
-			
-						/* 8 bit sample
-						 resolution, sign
-						 extend both bytes.
-						*/
-			
-						((unsigned char*)
-						 &sample_short)[0] += 0x7f;
-						((unsigned char*)
-						 &sample_short)[1] += 0x7f;
-			
-					} else {
-			
-						/* 16 bit sample
-						 resolution, sign
-						 extend the MSB.
-						*/
-			
-						sample_short += 0x7fff;
-					}
-				}
-
-			} else {
-
-				/* In padding section of final block:
-
-				   Don't fetch unsupplied data from
-				   user space, just continue with
-				   whatever the final value was.
-				*/
-			}
-	    
-			if (i < blocksize - 1) {
-				outw (sample_short, dev.block_port);
-			} else {
-				outw (sample_short, dev.last_block_port);
-			}
-		}
-
-		/* Get "DMA page acknowledge", even though its really
-		   nothing to do with DMA at all.
-		*/
-	
-		if ((dma_ack = wavefront_read ()) != WF_DMA_ACK) {
-			if (dma_ack == -1) {
-				printk (KERN_ERR LOGNAME "upload sample "
-					"DMA ack timeout\n");
-				return -(EIO);
-			} else {
-				printk (KERN_ERR LOGNAME "upload sample "
-					"DMA ack error 0x%x\n",
-					dma_ack);
-				return -(EIO);
-			}
-		}
-	}
-
-	dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
-
-	/* Note, label is here because sending the sample header shouldn't
-	   alter the sample_status info at all.
-	*/
-
- sent:
-	return (0);
-}
-
-static int
-wavefront_send_alias (wavefront_patch_info *header)
-
-{
-	unsigned char alias_hdr[WF_ALIAS_BYTES];
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is "
-				      "alias for %d\n",
-				      header->number,
-				      header->hdr.a.OriginalSample);
-    
-	munge_int32 (header->number, &alias_hdr[0], 2);
-	munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
-	munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset),
-		     &alias_hdr[4], 4);
-	munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset),
-		     &alias_hdr[8], 4);
-	munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset),
-		     &alias_hdr[12], 4);
-	munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset),
-		     &alias_hdr[16], 4);
-	munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
-	munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);
-
-	if (wavefront_cmd (WFC_DOWNLOAD_SAMPLE_ALIAS, NULL, alias_hdr)) {
-		printk (KERN_ERR LOGNAME "download alias failed.\n");
-		return -(EIO);
-	}
-
-	dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
-
-	return (0);
-}
-
-static int
-wavefront_send_multisample (wavefront_patch_info *header)
-{
-	int i;
-	int num_samples;
-	unsigned char msample_hdr[WF_MSAMPLE_BYTES];
-
-	munge_int32 (header->number, &msample_hdr[0], 2);
-
-	/* You'll recall at this point that the "number of samples" value
-	   in a wavefront_multisample struct is actually the log2 of the
-	   real number of samples.
-	*/
-
-	num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
-	msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n",
-				      header->number,
-				      header->hdr.ms.NumberOfSamples,
-				      num_samples);
-
-	for (i = 0; i < num_samples; i++) {
-		DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n",
-		       i, header->hdr.ms.SampleNumber[i]);
-		munge_int32 (header->hdr.ms.SampleNumber[i],
-		     &msample_hdr[3+(i*2)], 2);
-	}
-    
-	/* Need a hack here to pass in the number of bytes
-	   to be written to the synth. This is ugly, and perhaps
-	   one day, I'll fix it.
-	*/
-
-	if (wavefront_cmd (WFC_DOWNLOAD_MULTISAMPLE, 
-			   (unsigned char *) ((num_samples*2)+3),
-			   msample_hdr)) {
-		printk (KERN_ERR LOGNAME "download of multisample failed.\n");
-		return -(EIO);
-	}
-
-	dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
-
-	return (0);
-}
-
-static int
-wavefront_fetch_multisample (wavefront_patch_info *header)
-{
-	int i;
-	unsigned char log_ns[1];
-	unsigned char number[2];
-	int num_samples;
-
-	munge_int32 (header->number, number, 2);
-    
-	if (wavefront_cmd (WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
-		printk (KERN_ERR LOGNAME "upload multisample failed.\n");
-		return -(EIO);
-	}
-    
-	DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n",
-				header->number, log_ns[0]);
-
-	header->hdr.ms.NumberOfSamples = log_ns[0];
-
-	/* get the number of samples ... */
-
-	num_samples = (1 << log_ns[0]);
-    
-	for (i = 0; i < num_samples; i++) {
-		s8 d[2];
-	
-		if ((d[0] = wavefront_read ()) == -1) {
-			printk (KERN_ERR LOGNAME "upload multisample failed "
-				"during sample loop.\n");
-			return -(EIO);
-		}
-
-		if ((d[1] = wavefront_read ()) == -1) {
-			printk (KERN_ERR LOGNAME "upload multisample failed "
-				"during sample loop.\n");
-			return -(EIO);
-		}
-	
-		header->hdr.ms.SampleNumber[i] =
-			demunge_int32 ((unsigned char *) d, 2);
-	
-		DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n",
-					i, header->hdr.ms.SampleNumber[i]);
-	}
-
-	return (0);
-}
-
-
-static int
-wavefront_send_drum (wavefront_patch_info *header)
-
-{
-	unsigned char drumbuf[WF_DRUM_BYTES];
-	wavefront_drum *drum = &header->hdr.d;
-	int i;
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI "
-		"note %d, patch = %d\n", 
-		header->number, drum->PatchNumber);
-
-	drumbuf[0] = header->number & 0x7f;
-
-	for (i = 0; i < 4; i++) {
-		munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
-	}
-
-	if (wavefront_cmd (WFC_DOWNLOAD_EDRUM_PROGRAM, NULL, drumbuf)) {
-		printk (KERN_ERR LOGNAME "download drum failed.\n");
-		return -(EIO);
-	}
-
-	return (0);
-}
-
-static int 
-wavefront_find_free_sample (void)
-
-{
-	int i;
-
-	for (i = 0; i < WF_MAX_SAMPLE; i++) {
-		if (!(dev.sample_status[i] & WF_SLOT_FILLED)) {
-			return i;
-		}
-	}
-	printk (KERN_WARNING LOGNAME "no free sample slots!\n");
-	return -1;
-}
-
-static int 
-wavefront_find_free_patch (void)
-
-{
-	int i;
-
-	for (i = 0; i < WF_MAX_PATCH; i++) {
-		if (!(dev.patch_status[i] & WF_SLOT_FILLED)) {
-			return i;
-		}
-	}
-	printk (KERN_WARNING LOGNAME "no free patch slots!\n");
-	return -1;
-}
-
-static int 
-log2_2048(int n)
-
-{
-	int tbl[]={0, 0, 2048, 3246, 4096, 4755, 5294, 5749, 6143,
-		   6492, 6803, 7084, 7342, 7578, 7797, 8001, 8192,
-		   8371, 8540, 8699, 8851, 8995, 9132, 9264, 9390,
-		   9510, 9626, 9738, 9845, 9949, 10049, 10146};
-	int i;
-
-	/* Returns 2048*log2(n) */
-
-	/* FIXME: this is like doing integer math
-	   on quantum particles (RuN) */
-
-	i=0;
-	while(n>=32*256) {
-		n>>=8;
-		i+=2048*8;
-	}
-	while(n>=32) {
-		n>>=1;
-		i+=2048;
-	}
-	i+=tbl[n];
-	return(i);
-}
-
-static int
-wavefront_load_gus_patch (int devno, int format, const char __user *addr,
-			  int offs, int count, int pmgr_flag)
-{
-	struct patch_info guspatch;
-	wavefront_patch_info *samp, *pat, *prog;
-	wavefront_patch *patp;
-	wavefront_sample *sampp;
-	wavefront_program *progp;
-
-	int i,base_note;
-	long sizeof_patch;
-	int rc = -ENOMEM;
-
-	samp = kmalloc(3 * sizeof(wavefront_patch_info), GFP_KERNEL);
-	if (!samp)
-		goto free_fail;
-	pat = samp + 1;
-	prog = pat + 1;
-
-	/* Copy in the header of the GUS patch */
-
-	sizeof_patch = (long) &guspatch.data[0] - (long) &guspatch; 
-	if (copy_from_user(&((char *) &guspatch)[offs],
-			   &(addr)[offs], sizeof_patch - offs)) {
-		rc = -EFAULT;
-		goto free_fail;
-	}
-
-	if ((i = wavefront_find_free_patch ()) == -1) {
-		rc = -EBUSY;
-		goto free_fail;
-	}
-	pat->number = i;
-	pat->subkey = WF_ST_PATCH;
-	patp = &pat->hdr.p;
-
-	if ((i = wavefront_find_free_sample ()) == -1) {
-		rc = -EBUSY;
-		goto free_fail;
-	}
-	samp->number = i;
-	samp->subkey = WF_ST_SAMPLE;
-	samp->size = guspatch.len;
-	sampp = &samp->hdr.s;
-
-	prog->number = guspatch.instr_no;
-	progp = &prog->hdr.pr;
-
-	/* Setup the patch structure */
-
-	patp->amplitude_bias=guspatch.volume;
-	patp->portamento=0;
-	patp->sample_number= samp->number & 0xff;
-	patp->sample_msb= samp->number >> 8;
-	patp->pitch_bend= /*12*/ 0;
-	patp->mono=1;
-	patp->retrigger=1;
-	patp->nohold=(guspatch.mode & WAVE_SUSTAIN_ON) ? 0:1;
-	patp->frequency_bias=0;
-	patp->restart=0;
-	patp->reuse=0;
-	patp->reset_lfo=1;
-	patp->fm_src2=0;
-	patp->fm_src1=WF_MOD_MOD_WHEEL;
-	patp->am_src=WF_MOD_PRESSURE;
-	patp->am_amount=127;
-	patp->fc1_mod_amount=0;
-	patp->fc2_mod_amount=0; 
-	patp->fm_amount1=0;
-	patp->fm_amount2=0;
-	patp->envelope1.attack_level=127;
-	patp->envelope1.decay1_level=127;
-	patp->envelope1.decay2_level=127;
-	patp->envelope1.sustain_level=127;
-	patp->envelope1.release_level=0;
-	patp->envelope2.attack_velocity=127;
-	patp->envelope2.attack_level=127;
-	patp->envelope2.decay1_level=127;
-	patp->envelope2.decay2_level=127;
-	patp->envelope2.sustain_level=127;
-	patp->envelope2.release_level=0;
-	patp->envelope2.attack_velocity=127;
-	patp->randomizer=0;
-
-	/* Program for this patch */
-
-	progp->layer[0].patch_number= pat->number; /* XXX is this right ? */
-	progp->layer[0].mute=1;
-	progp->layer[0].pan_or_mod=1;
-	progp->layer[0].pan=7;
-	progp->layer[0].mix_level=127  /* guspatch.volume */;
-	progp->layer[0].split_type=0;
-	progp->layer[0].split_point=0;
-	progp->layer[0].play_below=0;
-
-	for (i = 1; i < 4; i++) {
-		progp->layer[i].mute=0;
-	}
-
-	/* Sample data */
-
-	sampp->SampleResolution=((~guspatch.mode & WAVE_16_BITS)<<1);
-
-	for (base_note=0;
-	     note_to_freq (base_note) < guspatch.base_note;
-	     base_note++);
-
-	if ((guspatch.base_note-note_to_freq(base_note))
-	    >(note_to_freq(base_note)-guspatch.base_note))
-		base_note++;
-
-	printk(KERN_DEBUG "ref freq=%d,base note=%d\n",
-	       guspatch.base_freq,
-	       base_note);
-
-	sampp->FrequencyBias = (29550 - log2_2048(guspatch.base_freq)
-				+ base_note*171);
-	printk(KERN_DEBUG "Freq Bias is %d\n", sampp->FrequencyBias);
-	sampp->Loop=(guspatch.mode & WAVE_LOOPING) ? 1:0;
-	sampp->sampleStartOffset.Fraction=0;
-	sampp->sampleStartOffset.Integer=0;
-	sampp->loopStartOffset.Fraction=0;
-	sampp->loopStartOffset.Integer=guspatch.loop_start
-		>>((guspatch.mode&WAVE_16_BITS) ? 1:0);
-	sampp->loopEndOffset.Fraction=0;
-	sampp->loopEndOffset.Integer=guspatch.loop_end
-		>>((guspatch.mode&WAVE_16_BITS) ? 1:0);
-	sampp->sampleEndOffset.Fraction=0;
-	sampp->sampleEndOffset.Integer=guspatch.len >> (guspatch.mode&1);
-	sampp->Bidirectional=(guspatch.mode&WAVE_BIDIR_LOOP) ? 1:0;
-	sampp->Reverse=(guspatch.mode&WAVE_LOOP_BACK) ? 1:0;
-
-	/* Now ship it down */
-
-	wavefront_send_sample (samp,
-			       (unsigned short __user *) &(addr)[sizeof_patch],
-			       (guspatch.mode & WAVE_UNSIGNED) ? 1:0);
-	wavefront_send_patch (pat);
-	wavefront_send_program (prog);
-
-	/* Now pan as best we can ... use the slave/internal MIDI device
-	   number if it exists (since it talks to the WaveFront), or the
-	   master otherwise.
-	*/
-
-	if (dev.mididev > 0) {
-		midi_synth_controller (dev.mididev, guspatch.instr_no, 10,
-				       ((guspatch.panning << 4) > 127) ?
-				       127 : (guspatch.panning << 4));
-	}
-	rc = 0;
-
-free_fail:
-	kfree(samp);
-	return rc;
-}
-
-static int
-wavefront_load_patch (const char __user *addr)
-
-
-{
-	wavefront_patch_info header;
-	
-	if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) -
-			    sizeof(wavefront_any))) {
-		printk (KERN_WARNING LOGNAME "bad address for load patch.\n");
-		return -EFAULT;
-	}
-
-	DPRINT (WF_DEBUG_LOAD_PATCH, "download "
-				      "Sample type: %d "
-				      "Sample number: %d "
-				      "Sample size: %d\n",
-				      header.subkey,
-				      header.number,
-				      header.size);
-
-	switch (header.subkey) {
-	case WF_ST_SAMPLE:  /* sample or sample_header, based on patch->size */
-
-		if (copy_from_user((unsigned char *) &header.hdr.s,
-				   (unsigned char __user *) header.hdrptr,
-				   sizeof (wavefront_sample)))
-			return -EFAULT;
-
-		return wavefront_send_sample (&header, header.dataptr, 0);
-
-	case WF_ST_MULTISAMPLE:
-
-		if (copy_from_user(&header.hdr.s, header.hdrptr,
-				   sizeof(wavefront_multisample)))
-			return -EFAULT;
-
-		return wavefront_send_multisample (&header);
-
-
-	case WF_ST_ALIAS:
-
-		if (copy_from_user(&header.hdr.a, header.hdrptr,
-				   sizeof (wavefront_alias)))
-			return -EFAULT;
-
-		return wavefront_send_alias (&header);
-
-	case WF_ST_DRUM:
-		if (copy_from_user(&header.hdr.d, header.hdrptr,
-				   sizeof (wavefront_drum)))
-			return -EFAULT;
-
-		return wavefront_send_drum (&header);
-
-	case WF_ST_PATCH:
-		if (copy_from_user(&header.hdr.p, header.hdrptr,
-				   sizeof (wavefront_patch)))
-			return -EFAULT;
-
-		return wavefront_send_patch (&header);
-
-	case WF_ST_PROGRAM:
-		if (copy_from_user(&header.hdr.pr, header.hdrptr,
-				   sizeof (wavefront_program)))
-			return -EFAULT;
-
-		return wavefront_send_program (&header);
-
-	default:
-		printk (KERN_ERR LOGNAME "unknown patch type %d.\n",
-			header.subkey);
-		return -(EINVAL);
-	}
-
-	return 0;
-}
-
-/***********************************************************************
-WaveFront: /dev/sequencer{,2} and other hardware-dependent interfaces
-***********************************************************************/
-
-static void
-process_sample_hdr (UCHAR8 *buf)
-
-{
-	wavefront_sample s;
-	UCHAR8 *ptr;
-
-	ptr = buf;
-
-	/* The board doesn't send us an exact copy of a "wavefront_sample"
-	   in response to an Upload Sample Header command. Instead, we 
-	   have to convert the data format back into our data structure,
-	   just as in the Download Sample command, where we have to do
-	   something very similar in the reverse direction.
-	*/
-
-	*((UINT32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
-	*((UINT32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
-	*((UINT32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
-	*((UINT32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
-	*((UINT32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3;
-
-	s.SampleResolution = *ptr & 0x3;
-	s.Loop = *ptr & 0x8;
-	s.Bidirectional = *ptr & 0x10;
-	s.Reverse = *ptr & 0x40;
-
-	/* Now copy it back to where it came from */
-
-	memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample));
-}
-
-static int
-wavefront_synth_control (int cmd, wavefront_control *wc)
-
-{
-	unsigned char patchnumbuf[2];
-	int i;
-
-	DPRINT (WF_DEBUG_CMD, "synth control with "
-		"cmd 0x%x\n", wc->cmd);
-
-	/* Pre-handling of or for various commands */
-
-	switch (wc->cmd) {
-	case WFC_DISABLE_INTERRUPTS:
-		printk (KERN_INFO LOGNAME "interrupts disabled.\n");
-		outb (0x80|0x20, dev.control_port);
-		dev.interrupts_on = 0;
-		return 0;
-
-	case WFC_ENABLE_INTERRUPTS:
-		printk (KERN_INFO LOGNAME "interrupts enabled.\n");
-		outb (0x80|0x40|0x20, dev.control_port);
-		dev.interrupts_on = 1;
-		return 0;
-
-	case WFC_INTERRUPT_STATUS:
-		wc->rbuf[0] = dev.interrupts_on;
-		return 0;
-
-	case WFC_ROMSAMPLES_RDONLY:
-		dev.rom_samples_rdonly = wc->wbuf[0];
-		wc->status = 0;
-		return 0;
-
-	case WFC_IDENTIFY_SLOT_TYPE:
-		i = wc->wbuf[0] | (wc->wbuf[1] << 7);
-		if (i <0 || i >= WF_MAX_SAMPLE) {
-			printk (KERN_WARNING LOGNAME "invalid slot ID %d\n",
-				i);
-			wc->status = EINVAL;
-			return 0;
-		}
-		wc->rbuf[0] = dev.sample_status[i];
-		wc->status = 0;
-		return 0;
-
-	case WFC_DEBUG_DRIVER:
-		dev.debug = wc->wbuf[0];
-		printk (KERN_INFO LOGNAME "debug = 0x%x\n", dev.debug);
-		return 0;
-
-	case WFC_FX_IOCTL:
-		wffx_ioctl ((wavefront_fx_info *) &wc->wbuf[0]);
-		return 0;
-
-	case WFC_UPLOAD_PATCH:
-		munge_int32 (*((UINT32 *) wc->wbuf), patchnumbuf, 2);
-		memcpy (wc->wbuf, patchnumbuf, 2);
-		break;
-
-	case WFC_UPLOAD_MULTISAMPLE:
-		/* multisamples have to be handled differently, and
-		   cannot be dealt with properly by wavefront_cmd() alone.
-		*/
-		wc->status = wavefront_fetch_multisample
-			((wavefront_patch_info *) wc->rbuf);
-		return 0;
-
-	case WFC_UPLOAD_SAMPLE_ALIAS:
-		printk (KERN_INFO LOGNAME "support for sample alias upload "
-			"being considered.\n");
-		wc->status = EINVAL;
-		return -EINVAL;
-	}
-
-	wc->status = wavefront_cmd (wc->cmd, wc->rbuf, wc->wbuf);
-
-	/* Post-handling of certain commands.
-
-	   In particular, if the command was an upload, demunge the data
-	   so that the user-level doesn't have to think about it.
-	*/
-
-	if (wc->status == 0) {
-		switch (wc->cmd) {
-			/* intercept any freemem requests so that we know
-			   we are always current with the user-level view
-			   of things.
-			*/
-
-		case WFC_REPORT_FREE_MEMORY:
-			dev.freemem = demunge_int32 (wc->rbuf, 4);
-			break;
-
-		case WFC_UPLOAD_PATCH:
-			demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES);
-			break;
-
-		case WFC_UPLOAD_PROGRAM:
-			demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES);
-			break;
-
-		case WFC_UPLOAD_EDRUM_PROGRAM:
-			demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1);
-			break;
-
-		case WFC_UPLOAD_SAMPLE_HEADER:
-			process_sample_hdr (wc->rbuf);
-			break;
-
-		case WFC_UPLOAD_SAMPLE_ALIAS:
-			printk (KERN_INFO LOGNAME "support for "
-				"sample aliases still "
-				"being considered.\n");
-			break;
-
-		case WFC_VMIDI_OFF:
-			if (virtual_midi_disable () < 0) {
-				return -(EIO);
-			}
-			break;
-
-		case WFC_VMIDI_ON:
-			if (virtual_midi_enable () < 0) {
-				return -(EIO);
-			}
-			break;
-		}
-	}
-
-	return 0;
-}
-
-
-/***********************************************************************/
-/* WaveFront: Linux file system interface (for access via raw synth)    */
-/***********************************************************************/
-
-static int 
-wavefront_open (struct inode *inode, struct file *file)
-{
-	/* XXX fix me */
-	dev.opened = file->f_flags;
-	return 0;
-}
-
-static int
-wavefront_release(struct inode *inode, struct file *file)
-{
-	lock_kernel();
-	dev.opened = 0;
-	dev.debug = 0;
-	unlock_kernel();
-	return 0;
-}
-
-static int
-wavefront_ioctl(struct inode *inode, struct file *file,
-		unsigned int cmd, unsigned long arg)
-{
-	wavefront_control wc;
-	int err;
-
-	switch (cmd) {
-
-	case WFCTL_WFCMD:
-		if (copy_from_user(&wc, (void __user *) arg, sizeof (wc)))
-			return -EFAULT;
-		
-		if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-			if (copy_to_user ((void __user *) arg, &wc, sizeof (wc)))
-				return -EFAULT;
-		}
-
-		return err;
-		
-	case WFCTL_LOAD_SPP:
-		return wavefront_load_patch ((const char __user *) arg);
-		
-	default:
-		printk (KERN_WARNING LOGNAME "invalid ioctl %#x\n", cmd);
-		return -(EINVAL);
-
-	}
-	return 0;
-}
-
-static /*const*/ struct file_operations wavefront_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= wavefront_ioctl,
-	.open		= wavefront_open,
-	.release	= wavefront_release,
-};
-
-
-/***********************************************************************/
-/* WaveFront: OSS installation and support interface                   */
-/***********************************************************************/
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-
-static struct synth_info wavefront_info =
-{"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT,
- 0, 32, 0, 0, SYNTH_CAP_INPUT};
-
-static int
-wavefront_oss_open (int devno, int mode)
-
-{
-	dev.opened = mode;
-	return 0;
-}
-
-static void
-wavefront_oss_close (int devno)
-
-{
-	dev.opened = 0;
-	dev.debug = 0;
-	return;
-}
-
-static int
-wavefront_oss_ioctl (int devno, unsigned int cmd, void __user * arg)
-
-{
-	wavefront_control wc;
-	int err;
-
-	switch (cmd) {
-	case SNDCTL_SYNTH_INFO:
-		if(copy_to_user(arg, &wavefront_info, sizeof (wavefront_info)))
-			return -EFAULT;
-		return 0;
-
-	case SNDCTL_SEQ_RESETSAMPLES:
-//		printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n");
-		return 0; /* don't force an error */
-
-	case SNDCTL_SEQ_PERCMODE:
-		return 0; /* don't force an error */
-
-	case SNDCTL_SYNTH_MEMAVL:
-		if ((dev.freemem = wavefront_freemem ()) < 0) {
-			printk (KERN_ERR LOGNAME "cannot get memory size\n");
-			return -EIO;
-		} else {
-			return dev.freemem;
-		}
-		break;
-
-	case SNDCTL_SYNTH_CONTROL:
-		if(copy_from_user (&wc, arg, sizeof (wc)))
-			err = -EFAULT;
-		else if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-			if(copy_to_user (arg, &wc, sizeof (wc)))
-				err = -EFAULT;
-		}
-
-		return err;
-
-	default:
-		return -(EINVAL);
-	}
-}
-
-static int
-wavefront_oss_load_patch (int devno, int format, const char __user *addr,
-			  int offs, int count, int pmgr_flag)
-{
-
-	if (format == SYSEX_PATCH) {	/* Handled by midi_synth.c */
-		if (midi_load_patch == NULL) {
-			printk (KERN_ERR LOGNAME
-				"SYSEX not loadable: "
-				"no midi patch loader!\n");
-			return -(EINVAL);
-		}
-
-		return midi_load_patch (devno, format, addr,
-					offs, count, pmgr_flag);
-
-	} else if (format == GUS_PATCH) {
-		return wavefront_load_gus_patch (devno, format,
-						 addr, offs, count, pmgr_flag);
-
-	} else if (format != WAVEFRONT_PATCH) {
-		printk (KERN_ERR LOGNAME "unknown patch format %d\n", format);
-		return -(EINVAL);
-	}
-
-	if (count < sizeof (wavefront_patch_info)) {
-		printk (KERN_ERR LOGNAME "sample header too short\n");
-		return -(EINVAL);
-	}
-
-	/* "addr" points to a user-space wavefront_patch_info */
-
-	return wavefront_load_patch (addr);
-}	
-
-static struct synth_operations wavefront_operations =
-{
-	.owner		= THIS_MODULE,
-	.id		= "WaveFront",
-	.info		= &wavefront_info,
-	.midi_dev	= 0,
-	.synth_type	= SYNTH_TYPE_SAMPLE,
-	.synth_subtype	= SAMPLE_TYPE_WAVEFRONT,
-	.open		= wavefront_oss_open,
-	.close		= wavefront_oss_close,
-	.ioctl		= wavefront_oss_ioctl,
-	.kill_note	= midi_synth_kill_note,
-	.start_note	= midi_synth_start_note,
-	.set_instr	= midi_synth_set_instr,
-	.reset		= midi_synth_reset,
-	.load_patch	= midi_synth_load_patch,
-	.aftertouch	= midi_synth_aftertouch,
-	.controller	= midi_synth_controller,
-	.panning	= midi_synth_panning,
-	.bender		= midi_synth_bender,
-	.setup_voice	= midi_synth_setup_voice
-};
-#endif /* OSS_SUPPORT_SEQ */
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
-
-static void __init attach_wavefront (struct address_info *hw_config)
-{
-    (void) install_wavefront ();
-}
-
-static int __init probe_wavefront (struct address_info *hw_config)
-{
-    return !detect_wavefront (hw_config->irq, hw_config->io_base);
-}
-
-static void __exit unload_wavefront (struct address_info *hw_config) 
-{
-    (void) uninstall_wavefront ();
-}
-
-#endif /* OSS_SUPPORT_STATIC_INSTALL */
-
-/***********************************************************************/
-/* WaveFront: Linux modular sound kernel installation interface        */
-/***********************************************************************/
-
-static irqreturn_t
-wavefrontintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-	struct wf_config *hw = dev_id;
-
-	/*
-	   Some comments on interrupts. I attempted a version of this
-	   driver that used interrupts throughout the code instead of
-	   doing busy and/or sleep-waiting. Alas, it appears that once
-	   the Motorola firmware is downloaded, the card *never*
-	   generates an RX interrupt. These are successfully generated
-	   during firmware loading, and after that wavefront_status()
-	   reports that an interrupt is pending on the card from time
-	   to time, but it never seems to be delivered to this
-	   driver. Note also that wavefront_status() continues to
-	   report that RX interrupts are enabled, suggesting that I
-	   didn't goof up and disable them by mistake.
-
-	   Thus, I stepped back to a prior version of
-	   wavefront_wait(), the only place where this really
-	   matters. Its sad, but I've looked through the code to check
-	   on things, and I really feel certain that the Motorola
-	   firmware prevents RX-ready interrupts.
-	*/
-
-	if ((wavefront_status() & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) {
-		return IRQ_NONE;
-	}
-
-	hw->irq_ok = 1;
-	hw->irq_cnt++;
-	wake_up_interruptible (&hw->interrupt_sleeper);
-	return IRQ_HANDLED;
-}
-
-/* STATUS REGISTER 
-
-0 Host Rx Interrupt Enable (1=Enabled)
-1 Host Rx Register Full (1=Full)
-2 Host Rx Interrupt Pending (1=Interrupt)
-3 Unused
-4 Host Tx Interrupt (1=Enabled)
-5 Host Tx Register empty (1=Empty)
-6 Host Tx Interrupt Pending (1=Interrupt)
-7 Unused
-*/
-
-static int
-wavefront_interrupt_bits (int irq)
-
-{
-	int bits;
-
-	switch (irq) {
-	case 9:
-		bits = 0x00;
-		break;
-	case 5:
-		bits = 0x08;
-		break;
-	case 12:
-		bits = 0x10;
-		break;
-	case 15:
-		bits = 0x18;
-		break;
-	
-	default:
-		printk (KERN_WARNING LOGNAME "invalid IRQ %d\n", irq);
-		bits = -1;
-	}
-
-	return bits;
-}
-
-static void
-wavefront_should_cause_interrupt (int val, int port, int timeout)
-
-{
-	unsigned long flags;
-
-	/* this will not help on SMP - but at least it compiles */
-	spin_lock_irqsave(&lock, flags);
-	dev.irq_ok = 0;
-	outb (val,port);
-	interruptible_sleep_on_timeout (&dev.interrupt_sleeper, timeout);
-	spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init wavefront_hw_reset (void)
-{
-	int bits;
-	int hwv[2];
-	unsigned long irq_mask;
-	short reported_irq;
-
-	/* IRQ already checked in init_module() */
-
-	bits = wavefront_interrupt_bits (dev.irq);
-
-	printk (KERN_DEBUG LOGNAME "autodetecting WaveFront IRQ\n");
-
-	irq_mask = probe_irq_on ();
-
-	outb (0x0, dev.control_port); 
-	outb (0x80 | 0x40 | bits, dev.data_port);	
-	wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
-					 dev.control_port,
-					 (reset_time*HZ)/100);
-
-	reported_irq = probe_irq_off (irq_mask);
-
-	if (reported_irq != dev.irq) {
-		if (reported_irq == 0) {
-			printk (KERN_ERR LOGNAME
-				"No unassigned interrupts detected "
-				"after h/w reset\n");
-		} else if (reported_irq < 0) {
-			printk (KERN_ERR LOGNAME
-				"Multiple unassigned interrupts detected "
-				"after h/w reset\n");
-		} else {
-			printk (KERN_ERR LOGNAME "autodetected IRQ %d not the "
-				"value provided (%d)\n", reported_irq,
-				dev.irq);
-		}
-		dev.irq = -1;
-		return 1;
-	} else {
-		printk (KERN_INFO LOGNAME "autodetected IRQ at %d\n",
-			reported_irq);
-	}
-
-	if (request_irq (dev.irq, wavefrontintr,
-			 IRQF_DISABLED|IRQF_SHARED,
-			 "wavefront synth", &dev) < 0) {
-		printk (KERN_WARNING LOGNAME "IRQ %d not available!\n",
-			dev.irq);
-		return 1;
-	}
-
-	/* try reset of port */
-      
-	outb (0x0, dev.control_port); 
-  
-	/* At this point, the board is in reset, and the H/W initialization
-	   register is accessed at the same address as the data port.
-     
-	   Bit 7 - Enable IRQ Driver	
-	   0 - Tri-state the Wave-Board drivers for the PC Bus IRQs
-	   1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus.
-     
-	   Bit 6 - MIDI Interface Select
-
-	   0 - Use the MIDI Input from the 26-pin WaveBlaster
-	   compatible header as the serial MIDI source
-	   1 - Use the MIDI Input from the 9-pin D connector as the
-	   serial MIDI source.
-     
-	   Bits 5:3 - IRQ Selection
-	   0 0 0 - IRQ 2/9
-	   0 0 1 - IRQ 5
-	   0 1 0 - IRQ 12
-	   0 1 1 - IRQ 15
-	   1 0 0 - Reserved
-	   1 0 1 - Reserved
-	   1 1 0 - Reserved
-	   1 1 1 - Reserved
-     
-	   Bits 2:1 - Reserved
-	   Bit 0 - Disable Boot ROM
-	   0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM
-	   1 - memory accesses to 03FC30-03FFFFH are directed to external 
-	   storage.
-     
-	*/
-
-	/* configure hardware: IRQ, enable interrupts, 
-	   plus external 9-pin MIDI interface selected
-	*/
-
-	outb (0x80 | 0x40 | bits, dev.data_port);	
-  
-	/* CONTROL REGISTER
-
-	   0 Host Rx Interrupt Enable (1=Enabled)      0x1
-	   1 Unused                                    0x2
-	   2 Unused                                    0x4
-	   3 Unused                                    0x8
-	   4 Host Tx Interrupt Enable                 0x10
-	   5 Mute (0=Mute; 1=Play)                    0x20
-	   6 Master Interrupt Enable (1=Enabled)      0x40
-	   7 Master Reset (0=Reset; 1=Run)            0x80
-
-	   Take us out of reset, mute output, master + TX + RX interrupts on.
-	   
-	   We'll get an interrupt presumably to tell us that the TX
-	   register is clear.
-	*/
-
-	wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
-					 dev.control_port,
-					 (reset_time*HZ)/100);
-
-	/* Note: data port is now the data port, not the h/w initialization
-	   port.
-	 */
-
-	if (!dev.irq_ok) {
-		printk (KERN_WARNING LOGNAME
-			"intr not received after h/w un-reset.\n");
-		goto gone_bad;
-	} 
-
-	dev.interrupts_on = 1;
-	
-	/* Note: data port is now the data port, not the h/w initialization
-	   port.
-
-	   At this point, only "HW VERSION" or "DOWNLOAD OS" commands
-	   will work. So, issue one of them, and wait for TX
-	   interrupt. This can take a *long* time after a cold boot,
-	   while the ISC ROM does its RAM test. The SDK says up to 4
-	   seconds - with 12MB of RAM on a Tropez+, it takes a lot
-	   longer than that (~16secs). Note that the card understands
-	   the difference between a warm and a cold boot, so
-	   subsequent ISC2115 reboots (say, caused by module
-	   reloading) will get through this much faster.
-
-	   XXX Interesting question: why is no RX interrupt received first ?
-	*/
-
-	wavefront_should_cause_interrupt(WFC_HARDWARE_VERSION, 
-					 dev.data_port, ramcheck_time*HZ);
-
-	if (!dev.irq_ok) {
-		printk (KERN_WARNING LOGNAME
-			"post-RAM-check interrupt not received.\n");
-		goto gone_bad;
-	} 
-
-	if (!wavefront_wait (STAT_CAN_READ)) {
-		printk (KERN_WARNING LOGNAME
-			"no response to HW version cmd.\n");
-		goto gone_bad;
-	}
-	
-	if ((hwv[0] = wavefront_read ()) == -1) {
-		printk (KERN_WARNING LOGNAME
-			"board not responding correctly.\n");
-		goto gone_bad;
-	}
-
-	if (hwv[0] == 0xFF) { /* NAK */
-
-		/* Board's RAM test failed. Try to read error code,
-		   and tell us about it either way.
-		*/
-		
-		if ((hwv[0] = wavefront_read ()) == -1) {
-			printk (KERN_WARNING LOGNAME "on-board RAM test failed "
-				"(bad error code).\n");
-		} else {
-			printk (KERN_WARNING LOGNAME "on-board RAM test failed "
-				"(error code: 0x%x).\n",
-				hwv[0]);
-		}
-		goto gone_bad;
-	}
-
-	/* We're OK, just get the next byte of the HW version response */
-
-	if ((hwv[1] = wavefront_read ()) == -1) {
-		printk (KERN_WARNING LOGNAME "incorrect h/w response.\n");
-		goto gone_bad;
-	}
-
-	printk (KERN_INFO LOGNAME "hardware version %d.%d\n",
-		hwv[0], hwv[1]);
-
-	return 0;
-
-
-     gone_bad:
-	if (dev.irq >= 0) {
-		free_irq (dev.irq, &dev);
-		dev.irq = -1;
-	}
-	return (1);
-}
-
-static int __init detect_wavefront (int irq, int io_base)
-{
-	unsigned char   rbuf[4], wbuf[4];
-
-	/* TB docs say the device takes up 8 ports, but we know that
-	   if there is an FX device present (i.e. a Tropez+) it really
-	   consumes 16.
-	*/
-
-	if (!request_region (io_base, 16, "wavfront")) {
-		printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
-			"already in use - ignored\n", dev.base,
-			dev.base+15);
-		return -1;
-	}
-  
-	dev.irq = irq;
-	dev.base = io_base;
-	dev.israw = 0;
-	dev.debug = debug_default;
-	dev.interrupts_on = 0;
-	dev.irq_cnt = 0;
-	dev.rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */
-
-	if (wavefront_cmd (WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
-
-		dev.fw_version[0] = rbuf[0];
-		dev.fw_version[1] = rbuf[1];
-		printk (KERN_INFO LOGNAME
-			"firmware %d.%d already loaded.\n",
-			rbuf[0], rbuf[1]);
-
-		/* check that a command actually works */
-      
-		if (wavefront_cmd (WFC_HARDWARE_VERSION,
-				   rbuf, wbuf) == 0) {
-			dev.hw_version[0] = rbuf[0];
-			dev.hw_version[1] = rbuf[1];
-		} else {
-			printk (KERN_WARNING LOGNAME "not raw, but no "
-				"hardware version!\n");
-			release_region (io_base, 16);
-			return 0;
-		}
-
-		if (!wf_raw) {
-			/* will re-acquire region in install_wavefront() */
-			release_region (io_base, 16);
-			return 1;
-		} else {
-			printk (KERN_INFO LOGNAME
-				"reloading firmware anyway.\n");
-			dev.israw = 1;
-		}
-
-	} else {
-
-		dev.israw = 1;
-		printk (KERN_INFO LOGNAME
-			"no response to firmware probe, assume raw.\n");
-
-	}
-
-	init_waitqueue_head (&dev.interrupt_sleeper);
-
-	if (wavefront_hw_reset ()) {
-		printk (KERN_WARNING LOGNAME "hardware reset failed\n");
-		release_region (io_base, 16);
-		return 0;
-	}
-
-	/* Check for FX device, present only on Tropez+ */
-
-	dev.has_fx = (detect_wffx () == 0);
-
-	/* will re-acquire region in install_wavefront() */
-	release_region (io_base, 16);
-	return 1;
-}
-
-#include "os.h"
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-
-
-static int
-wavefront_download_firmware (char *path)
-
-{
-	unsigned char section[WF_SECTION_MAX];
-	char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
-	int section_cnt_downloaded = 0;
-	int fd;
-	int c;
-	int i;
-	mm_segment_t fs;
-
-	/* This tries to be a bit cleverer than the stuff Alan Cox did for
-	   the generic sound firmware, in that it actually knows
-	   something about the structure of the Motorola firmware. In
-	   particular, it uses a version that has been stripped of the
-	   20K of useless header information, and had section lengths
-	   added, making it possible to load the entire OS without any
-	   [kv]malloc() activity, since the longest entity we ever read is
-	   42 bytes (well, WF_SECTION_MAX) long.
-	*/
-
-	fs = get_fs();
-	set_fs (get_ds());
-
-	if ((fd = sys_open (path, 0, 0)) < 0) {
-		printk (KERN_WARNING LOGNAME "Unable to load \"%s\".\n",
-			path);
-		return 1;
-	}
-
-	while (1) {
-		int x;
-
-		if ((x = sys_read (fd, &section_length, sizeof (section_length))) !=
-		    sizeof (section_length)) {
-			printk (KERN_ERR LOGNAME "firmware read error.\n");
-			goto failure;
-		}
-
-		if (section_length == 0) {
-			break;
-		}
-
-		if (sys_read (fd, section, section_length) != section_length) {
-			printk (KERN_ERR LOGNAME "firmware section "
-				"read error.\n");
-			goto failure;
-		}
-
-		/* Send command */
-	
-		if (wavefront_write (WFC_DOWNLOAD_OS)) {
-			goto failure;
-		}
-	
-		for (i = 0; i < section_length; i++) {
-			if (wavefront_write (section[i])) {
-				goto failure;
-			}
-		}
-	
-		/* get ACK */
-	
-		if (wavefront_wait (STAT_CAN_READ)) {
-
-			if ((c = inb (dev.data_port)) != WF_ACK) {
-
-				printk (KERN_ERR LOGNAME "download "
-					"of section #%d not "
-					"acknowledged, ack = 0x%x\n",
-					section_cnt_downloaded + 1, c);
-				goto failure;
-		
-			}
-
-		} else {
-			printk (KERN_ERR LOGNAME "time out for firmware ACK.\n");
-			goto failure;
-		}
-
-	}
-
-	sys_close (fd);
-	set_fs (fs);
-	return 0;
-
- failure:
-	sys_close (fd);
-	set_fs (fs);
-	printk (KERN_ERR "\nWaveFront: firmware download failed!!!\n");
-	return 1;
-}
-
-static int __init wavefront_config_midi (void)
-{
-	unsigned char rbuf[4], wbuf[4];
-    
-	if (detect_wf_mpu (dev.irq, dev.base) < 0) {
-		printk (KERN_WARNING LOGNAME
-			"could not find working MIDI device\n");
-		return -1;
-	} 
-
-	if ((dev.mididev = install_wf_mpu ()) < 0) {
-		printk (KERN_WARNING LOGNAME
-			"MIDI interfaces not configured\n");
-		return -1;
-	}
-
-	/* Route external MIDI to WaveFront synth (by default) */
-    
-	if (wavefront_cmd (WFC_MISYNTH_ON, rbuf, wbuf)) {
-		printk (KERN_WARNING LOGNAME
-			"cannot enable MIDI-IN to synth routing.\n");
-		/* XXX error ? */
-	}
-
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-	/* Get the regular MIDI patch loading function, so we can
-	   use it if we ever get handed a SYSEX patch. This is
-	   unlikely, because its so damn slow, but we may as well
-	   leave this functionality from maui.c behind, since it
-	   could be useful for sequencer applications that can
-	   only use MIDI to do patch loading.
-	*/
-
-	if (midi_devs[dev.mididev]->converter != NULL) {
-		midi_load_patch = midi_devs[dev.mididev]->converter->load_patch;
-		midi_devs[dev.mididev]->converter->load_patch =
-		    &wavefront_oss_load_patch;
-	}
-
-#endif /* OSS_SUPPORT_SEQ */
-	
-	/* Turn on Virtual MIDI, but first *always* turn it off,
-	   since otherwise consectutive reloads of the driver will
-	   never cause the hardware to generate the initial "internal" or 
-	   "external" source bytes in the MIDI data stream. This
-	   is pretty important, since the internal hardware generally will
-	   be used to generate none or very little MIDI output, and
-	   thus the only source of MIDI data is actually external. Without
-	   the switch bytes, the driver will think it all comes from
-	   the internal interface. Duh.
-	*/
-
-	if (wavefront_cmd (WFC_VMIDI_OFF, rbuf, wbuf)) { 
-		printk (KERN_WARNING LOGNAME
-			"virtual MIDI mode not disabled\n");
-		return 0; /* We're OK, but missing the external MIDI dev */
-	}
-
-	if ((dev.ext_mididev = virtual_midi_enable ()) < 0) {
-		printk (KERN_WARNING LOGNAME "no virtual MIDI access.\n");
-	} else {
-		if (wavefront_cmd (WFC_VMIDI_ON, rbuf, wbuf)) {
-			printk (KERN_WARNING LOGNAME
-				"cannot enable virtual MIDI mode.\n");
-			virtual_midi_disable ();
-		} 
-	}
-    
-	return 0;
-}
-
-static int __init wavefront_do_reset (int atboot)
-{
-	char voices[1];
-
-	if (!atboot && wavefront_hw_reset ()) {
-		printk (KERN_WARNING LOGNAME "hw reset failed.\n");
-		goto gone_bad;
-	}
-
-	if (dev.israw) {
-		if (wavefront_download_firmware (ospath)) {
-			goto gone_bad;
-		}
-
-		dev.israw = 0;
-
-		/* Wait for the OS to get running. The protocol for
-		   this is non-obvious, and was determined by
-		   using port-IO tracing in DOSemu and some
-		   experimentation here.
-		   
-		   Rather than using timed waits, use interrupts creatively.
-		*/
-
-		wavefront_should_cause_interrupt (WFC_NOOP,
-						  dev.data_port,
-						  (osrun_time*HZ));
-
-		if (!dev.irq_ok) {
-			printk (KERN_WARNING LOGNAME
-				"no post-OS interrupt.\n");
-			goto gone_bad;
-		}
-		
-		/* Now, do it again ! */
-		
-		wavefront_should_cause_interrupt (WFC_NOOP,
-						  dev.data_port, (10*HZ));
-		
-		if (!dev.irq_ok) {
-			printk (KERN_WARNING LOGNAME
-				"no post-OS interrupt(2).\n");
-			goto gone_bad;
-		}
-
-		/* OK, no (RX/TX) interrupts any more, but leave mute
-		   in effect. 
-		*/
-		
-		outb (0x80|0x40, dev.control_port); 
-
-		/* No need for the IRQ anymore */
-		
-		free_irq (dev.irq, &dev);
-
-	}
-
-	if (dev.has_fx && fx_raw) {
-		wffx_init ();
-	}
-
-	/* SETUPSND.EXE asks for sample memory config here, but since i
-	   have no idea how to interpret the result, we'll forget
-	   about it.
-	*/
-	
-	if ((dev.freemem = wavefront_freemem ()) < 0) {
-		goto gone_bad;
-	}
-		
-	printk (KERN_INFO LOGNAME "available DRAM %dk\n", dev.freemem / 1024);
-
-	if (wavefront_write (0xf0) ||
-	    wavefront_write (1) ||
-	    (wavefront_read () < 0)) {
-		dev.debug = 0;
-		printk (KERN_WARNING LOGNAME "MPU emulation mode not set.\n");
-		goto gone_bad;
-	}
-
-	voices[0] = 32;
-
-	if (wavefront_cmd (WFC_SET_NVOICES, NULL, voices)) {
-		printk (KERN_WARNING LOGNAME
-			"cannot set number of voices to 32.\n");
-		goto gone_bad;
-	}
-
-
-	return 0;
-
- gone_bad:
-	/* reset that sucker so that it doesn't bother us. */
-
-	outb (0x0, dev.control_port);
-	dev.interrupts_on = 0;
-	if (dev.irq >= 0) {
-		free_irq (dev.irq, &dev);
-	}
-	return 1;
-}
-
-static int __init wavefront_init (int atboot)
-{
-	int samples_are_from_rom;
-
-	if (dev.israw) {
-		samples_are_from_rom = 1;
-	} else {
-		/* XXX is this always true ? */
-		samples_are_from_rom = 0;
-	}
-
-	if (dev.israw || fx_raw) {
-		if (wavefront_do_reset (atboot)) {
-			return -1;
-		}
-	}
-
-	wavefront_get_sample_status (samples_are_from_rom);
-	wavefront_get_program_status ();
-	wavefront_get_patch_status ();
-
-	/* Start normal operation: unreset, master interrupt enabled, no mute
-	*/
-
-	outb (0x80|0x40|0x20, dev.control_port); 
-
-	return (0);
-}
-
-static int __init install_wavefront (void)
-{
-	if (!request_region (dev.base+2, 6, "wavefront synth"))
-		return -1;
-
-	if (dev.has_fx) {
-		if (!request_region (dev.base+8, 8, "wavefront fx")) {
-			release_region (dev.base+2, 6);
-			return -1;
-		}
-	}
-
-	if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
-		printk (KERN_ERR LOGNAME "cannot register raw synth\n");
-		goto err_out;
-	}
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-	if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
-		printk (KERN_ERR LOGNAME "Too many sequencers\n");
-		/* FIXME: leak: should unregister sound synth */
-		goto err_out;
-	} else {
-		synth_devs[dev.oss_dev] = &wavefront_operations;
-	}
-#endif /* OSS_SUPPORT_SEQ */
-
-	if (wavefront_init (1) < 0) {
-		printk (KERN_WARNING LOGNAME "initialization failed.\n");
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-		sound_unload_synthdev (dev.oss_dev);
-#endif /* OSS_SUPPORT_SEQ */ 
-
-		goto err_out;
-	}
-    
-	if (wavefront_config_midi ()) {
-		printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
-	}
-
-	return dev.oss_dev;
-
-err_out:
-	release_region (dev.base+2, 6);
-	if (dev.has_fx)
-		release_region (dev.base+8, 8);
-	return -1;
-}
-
-static void __exit uninstall_wavefront (void)
-{
-	/* the first two i/o addresses are freed by the wf_mpu code */
-	release_region (dev.base+2, 6);
-
-	if (dev.has_fx) {
-		release_region (dev.base+8, 8);
-	}
-
-	unregister_sound_synth (dev.synth_dev);
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-	sound_unload_synthdev (dev.oss_dev);
-#endif /* OSS_SUPPORT_SEQ */ 
-	uninstall_wf_mpu ();
-}
-
-/***********************************************************************/
-/*   WaveFront FX control                                              */
-/***********************************************************************/
-
-#include "yss225.h"
-
-/* Control bits for the Load Control Register
- */
-
-#define FX_LSB_TRANSFER 0x01    /* transfer after DSP LSB byte written */
-#define FX_MSB_TRANSFER 0x02    /* transfer after DSP MSB byte written */
-#define FX_AUTO_INCR    0x04    /* auto-increment DSP address after transfer */
-
-static int
-wffx_idle (void) 
-    
-{
-	int i;
-	unsigned int x = 0x80;
-    
-	for (i = 0; i < 1000; i++) {
-		x = inb (dev.fx_status);
-		if ((x & 0x80) == 0) {
-			break;
-		}
-	}
-    
-	if (x & 0x80) {
-		printk (KERN_ERR LOGNAME "FX device never idle.\n");
-		return 0;
-	}
-    
-	return (1);
-}
-
-int __init detect_wffx (void)
-{
-	/* This is a crude check, but its the best one I have for now.
-	   Certainly on the Maui and the Tropez, wffx_idle() will
-	   report "never idle", which suggests that this test should
-	   work OK.
-	*/
-
-	if (inb (dev.fx_status) & 0x80) {
-		printk (KERN_INFO LOGNAME "Hmm, probably a Maui or Tropez.\n");
-		return -1;
-	}
-
-	return 0;
-}	
-
-static void
-wffx_mute (int onoff)
-    
-{
-	if (!wffx_idle()) {
-		return;
-	}
-    
-	outb (onoff ? 0x02 : 0x00, dev.fx_op);
-}
-
-static int
-wffx_memset (int page,
-	     int addr, int cnt, unsigned short *data)
-{
-	if (page < 0 || page > 7) {
-		printk (KERN_ERR LOGNAME "FX memset: "
-			"page must be >= 0 and <= 7\n");
-		return -(EINVAL);
-	}
-
-	if (addr < 0 || addr > 0x7f) {
-		printk (KERN_ERR LOGNAME "FX memset: "
-			"addr must be >= 0 and <= 7f\n");
-		return -(EINVAL);
-	}
-
-	if (cnt == 1) {
-
-		outb (FX_LSB_TRANSFER, dev.fx_lcr);
-		outb (page, dev.fx_dsp_page);
-		outb (addr, dev.fx_dsp_addr);
-		outb ((data[0] >> 8), dev.fx_dsp_msb);
-		outb ((data[0] & 0xff), dev.fx_dsp_lsb);
-
-		printk (KERN_INFO LOGNAME "FX: addr %d:%x set to 0x%x\n",
-			page, addr, data[0]);
-	
-	} else {
-		int i;
-
-		outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-		outb (page, dev.fx_dsp_page);
-		outb (addr, dev.fx_dsp_addr);
-
-		for (i = 0; i < cnt; i++) {
-			outb ((data[i] >> 8), dev.fx_dsp_msb);
-			outb ((data[i] & 0xff), dev.fx_dsp_lsb);
-			if (!wffx_idle ()) {
-				break;
-			}
-		}
-
-		if (i != cnt) {
-			printk (KERN_WARNING LOGNAME
-				"FX memset "
-				"(0x%x, 0x%x, %p, %d) incomplete\n",
-				page, addr, data, cnt);
-			return -(EIO);
-		}
-	}
-
-	return 0;
-}
-
-static int
-wffx_ioctl (wavefront_fx_info *r)
-
-{
-	unsigned short page_data[256];
-	unsigned short *pd;
-
-	switch (r->request) {
-	case WFFX_MUTE:
-		wffx_mute (r->data[0]);
-		return 0;
-
-	case WFFX_MEMSET:
-
-		if (r->data[2] <= 0) {
-			printk (KERN_ERR LOGNAME "cannot write "
-				"<= 0 bytes to FX\n");
-			return -(EINVAL);
-		} else if (r->data[2] == 1) {
-			pd = (unsigned short *) &r->data[3];
-		} else {
-			if (r->data[2] > sizeof (page_data)) {
-				printk (KERN_ERR LOGNAME "cannot write "
-					"> 255 bytes to FX\n");
-				return -(EINVAL);
-			}
-			if (copy_from_user(page_data,
-					   (unsigned char __user *)r->data[3],
-					   r->data[2]))
-				return -EFAULT;
-			pd = page_data;
-		}
-
-		return wffx_memset (r->data[0], /* page */
-				    r->data[1], /* addr */
-				    r->data[2], /* cnt */
-				    pd);
-
-	default:
-		printk (KERN_WARNING LOGNAME
-			"FX: ioctl %d not yet supported\n",
-			r->request);
-		return -(EINVAL);
-	}
-}
-
-/* YSS225 initialization.
-
-   This code was developed using DOSEMU. The Turtle Beach SETUPSND
-   utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
-   of the port I/O done, using the Yamaha faxback document as a guide
-   to add more logic to the code. Its really pretty weird.
-
-   There was an alternative approach of just dumping the whole I/O
-   sequence as a series of port/value pairs and a simple loop
-   that output it. However, I hope that eventually I'll get more
-   control over what this code does, and so I tried to stick with
-   a somewhat "algorithmic" approach.
-*/
-
-static int __init wffx_init (void)
-{
-	int i;
-	int j;
-
-	/* Set all bits for all channels on the MOD unit to zero */
-	/* XXX But why do this twice ? */
-
-	for (j = 0; j < 2; j++) {
-		for (i = 0x10; i <= 0xff; i++) {
-	    
-			if (!wffx_idle ()) {
-				return (-1);
-			}
-	    
-			outb (i, dev.fx_mod_addr);
-			outb (0x0, dev.fx_mod_data);
-		}
-	}
-
-	if (!wffx_idle()) return (-1);
-	outb (0x02, dev.fx_op);                        /* mute on */
-
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x44, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x42, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x43, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x7c, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x7e, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x46, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x49, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x47, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x4a, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-
-	/* either because of stupidity by TB's programmers, or because it
-	   actually does something, rezero the MOD page.
-	*/
-	for (i = 0x10; i <= 0xff; i++) {
-	
-		if (!wffx_idle ()) {
-			return (-1);
-		}
-	
-		outb (i, dev.fx_mod_addr);
-		outb (0x0, dev.fx_mod_data);
-	}
-	/* load page zero */
-
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x00, dev.fx_dsp_page);
-	outb (0x00, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_zero); i += 2) {
-		outb (page_zero[i], dev.fx_dsp_msb);
-		outb (page_zero[i+1], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-
-	/* Now load page one */
-
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x01, dev.fx_dsp_page);
-	outb (0x00, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_one); i += 2) {
-		outb (page_one[i], dev.fx_dsp_msb);
-		outb (page_one[i+1], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x02, dev.fx_dsp_page);
-	outb (0x00, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_two); i++) {
-		outb (page_two[i], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x03, dev.fx_dsp_page);
-	outb (0x00, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_three); i++) {
-		outb (page_three[i], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x04, dev.fx_dsp_page);
-	outb (0x00, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_four); i++) {
-		outb (page_four[i], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-
-	/* Load memory area (page six) */
-    
-	outb (FX_LSB_TRANSFER, dev.fx_lcr); 
-	outb (0x06, dev.fx_dsp_page); 
-
-	for (i = 0; i < sizeof (page_six); i += 3) {
-		outb (page_six[i], dev.fx_dsp_addr);
-		outb (page_six[i+1], dev.fx_dsp_msb);
-		outb (page_six[i+2], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x00, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_seven); i += 2) {
-		outb (page_seven[i], dev.fx_dsp_msb);
-		outb (page_seven[i+1], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-
-	/* Now setup the MOD area. We do this algorithmically in order to
-	   save a little data space. It could be done in the same fashion
-	   as the "pages".
-	*/
-
-	for (i = 0x00; i <= 0x0f; i++) {
-		outb (0x01, dev.fx_mod_addr);
-		outb (i, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-		outb (0x02, dev.fx_mod_addr);
-		outb (0x00, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0xb0; i <= 0xbf; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x20, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0xf0; i <= 0xff; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x20, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0x10; i <= 0x1d; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0xff, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (0x1e, dev.fx_mod_addr);
-	outb (0x40, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	for (i = 0x1f; i <= 0x2d; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0xff, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (0x2e, dev.fx_mod_addr);
-	outb (0x00, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	for (i = 0x2f; i <= 0x3e; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x00, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (0x3f, dev.fx_mod_addr);
-	outb (0x20, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	for (i = 0x40; i <= 0x4d; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x00, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (0x4e, dev.fx_mod_addr);
-	outb (0x0e, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-	outb (0x4f, dev.fx_mod_addr);
-	outb (0x0e, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-
-	for (i = 0x50; i <= 0x6b; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x00, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (0x6c, dev.fx_mod_addr);
-	outb (0x40, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	outb (0x6d, dev.fx_mod_addr);
-	outb (0x00, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	outb (0x6e, dev.fx_mod_addr);
-	outb (0x40, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	outb (0x6f, dev.fx_mod_addr);
-	outb (0x40, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	for (i = 0x70; i <= 0x7f; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0xc0, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	for (i = 0x80; i <= 0xaf; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x00, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0xc0; i <= 0xdd; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x00, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (0xde, dev.fx_mod_addr);
-	outb (0x10, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-	outb (0xdf, dev.fx_mod_addr);
-	outb (0x10, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-
-	for (i = 0xe0; i <= 0xef; i++) {
-		outb (i, dev.fx_mod_addr);
-		outb (0x00, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0x00; i <= 0x0f; i++) {
-		outb (0x01, dev.fx_mod_addr);
-		outb (i, dev.fx_mod_data);
-		outb (0x02, dev.fx_mod_addr);
-		outb (0x01, dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (0x02, dev.fx_op); /* mute on */
-
-	/* Now set the coefficients and so forth for the programs above */
-
-	for (i = 0; i < sizeof (coefficients); i += 4) {
-		outb (coefficients[i], dev.fx_dsp_page);
-		outb (coefficients[i+1], dev.fx_dsp_addr);
-		outb (coefficients[i+2], dev.fx_dsp_msb);
-		outb (coefficients[i+3], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-
-	/* Some settings (?) that are too small to bundle into loops */
-
-	if (!wffx_idle()) return (-1);
-	outb (0x1e, dev.fx_mod_addr);
-	outb (0x14, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-	outb (0xde, dev.fx_mod_addr);
-	outb (0x20, dev.fx_mod_data);
-	if (!wffx_idle()) return (-1);
-	outb (0xdf, dev.fx_mod_addr);
-	outb (0x20, dev.fx_mod_data);
-    
-	/* some more coefficients */
-
-	if (!wffx_idle()) return (-1);
-	outb (0x06, dev.fx_dsp_page);
-	outb (0x78, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x40, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x03, dev.fx_dsp_addr);
-	outb (0x0f, dev.fx_dsp_msb);
-	outb (0xff, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x0b, dev.fx_dsp_addr);
-	outb (0x0f, dev.fx_dsp_msb);
-	outb (0xff, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x02, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x0a, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x46, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-	if (!wffx_idle()) return (-1);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x49, dev.fx_dsp_addr);
-	outb (0x00, dev.fx_dsp_msb);
-	outb (0x00, dev.fx_dsp_lsb);
-    
-	/* Now, for some strange reason, lets reload every page
-	   and all the coefficients over again. I have *NO* idea
-	   why this is done. I do know that no sound is produced
-	   is this phase is omitted.
-	*/
-
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x00, dev.fx_dsp_page);  
-	outb (0x10, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_zero_v2); i += 2) {
-		outb (page_zero_v2[i], dev.fx_dsp_msb);
-		outb (page_zero_v2[i+1], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x01, dev.fx_dsp_page);
-	outb (0x10, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_one_v2); i += 2) {
-		outb (page_one_v2[i], dev.fx_dsp_msb);
-		outb (page_one_v2[i+1], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	if (!wffx_idle()) return (-1);
-	if (!wffx_idle()) return (-1);
-    
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x02, dev.fx_dsp_page);
-	outb (0x10, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_two_v2); i++) {
-		outb (page_two_v2[i], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x03, dev.fx_dsp_page);
-	outb (0x10, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_three_v2); i++) {
-		outb (page_three_v2[i], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x04, dev.fx_dsp_page);
-	outb (0x10, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_four_v2); i++) {
-		outb (page_four_v2[i], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-    
-	outb (FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x06, dev.fx_dsp_page);
-
-	/* Page six v.2 is algorithmic */
-    
-	for (i = 0x10; i <= 0x3e; i += 2) {
-		outb (i, dev.fx_dsp_addr);
-		outb (0x00, dev.fx_dsp_msb);
-		outb (0x00, dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-
-	outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-	outb (0x07, dev.fx_dsp_page);
-	outb (0x10, dev.fx_dsp_addr);
-
-	for (i = 0; i < sizeof (page_seven_v2); i += 2) {
-		outb (page_seven_v2[i], dev.fx_dsp_msb);
-		outb (page_seven_v2[i+1], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0x00; i < sizeof(mod_v2); i += 2) {
-		outb (mod_v2[i], dev.fx_mod_addr);
-		outb (mod_v2[i+1], dev.fx_mod_data);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0; i < sizeof (coefficients2); i += 4) {
-		outb (coefficients2[i], dev.fx_dsp_page);
-		outb (coefficients2[i+1], dev.fx_dsp_addr);
-		outb (coefficients2[i+2], dev.fx_dsp_msb);
-		outb (coefficients2[i+3], dev.fx_dsp_lsb);
-		if (!wffx_idle()) return (-1);
-	}
-
-	for (i = 0; i < sizeof (coefficients3); i += 2) {
-		int x;
-
-		outb (0x07, dev.fx_dsp_page);
-		x = (i % 4) ? 0x4e : 0x4c;
-		outb (x, dev.fx_dsp_addr);
-		outb (coefficients3[i], dev.fx_dsp_msb);
-		outb (coefficients3[i+1], dev.fx_dsp_lsb);
-	}
-
-	outb (0x00, dev.fx_op); /* mute off */
-	if (!wffx_idle()) return (-1);
-
-	return (0);
-}
-
-static int io = -1;
-static int irq = -1;
-
-MODULE_AUTHOR      ("Paul Barton-Davis <pbd@op.net>");
-MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
-MODULE_LICENSE("GPL");
-module_param       (io, int, 0);
-module_param       (irq, int, 0);
-
-static int __init init_wavfront (void)
-{
-	printk ("Turtle Beach WaveFront Driver\n"
-		"Copyright (C) by Hannu Solvainen, "
-		"Paul Barton-Davis 1993-1998.\n");
-
-	/* XXX t'would be lovely to ask the CS4232 for these values, eh ? */
-
-	if (io == -1 || irq == -1) {
-		printk (KERN_INFO LOGNAME "irq and io options must be set.\n");
-		return -EINVAL;
-	}
-
-	if (wavefront_interrupt_bits (irq) < 0) {
-		printk (KERN_INFO LOGNAME
-			"IRQ must be 9, 5, 12 or 15 (not %d)\n", irq);
-		return -ENODEV;
-	}
-
-	if (detect_wavefront (irq, io) < 0) {
-		return -ENODEV;
-	} 
-
-	if (install_wavefront () < 0) {
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static void __exit cleanup_wavfront (void)
-{
-	uninstall_wavefront ();
-}
-
-module_init(init_wavfront);
-module_exit(cleanup_wavfront);
diff --git a/sound/oss/wf_midi.c b/sound/oss/wf_midi.c
deleted file mode 100644
index 3f3a390..0000000
--- a/sound/oss/wf_midi.c
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * sound/wf_midi.c
- *
- * The low level driver for the WaveFront ICS2115 MIDI interface(s)
- * Note that there is also an MPU-401 emulation (actually, a UART-401
- * emulation) on the CS4232 on the Tropez Plus. This code has nothing
- * to do with that interface at all.
- *
- * The interface is essentially just a UART-401, but is has the
- * interesting property of supporting what Turtle Beach called
- * "Virtual MIDI" mode. In this mode, there are effectively *two*
- * MIDI buses accessible via the interface, one that is routed
- * solely to/from the external WaveFront synthesizer and the other
- * corresponding to the pin/socket connector used to link external
- * MIDI devices to the board.
- *
- * This driver fully supports this mode, allowing two distinct
- * midi devices (/dev/midiNN and /dev/midiNN+1) to be used
- * completely independently, giving 32 channels of MIDI routing,
- * 16 to the WaveFront synth and 16 to the external MIDI bus.
- *
- * Switching between the two is accomplished externally by the driver
- * using the two otherwise unused MIDI bytes. See the code for more details.
- *
- * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c)
- *
- * The main reason to turn off Virtual MIDI mode is when you want to
- * tightly couple the WaveFront synth with an external MIDI
- * device. You won't be able to distinguish the source of any MIDI
- * data except via SysEx ID, but thats probably OK, since for the most
- * part, the WaveFront won't be sending any MIDI data at all.
- *  
- * The main reason to turn on Virtual MIDI Mode is to provide two
- * completely independent 16-channel MIDI buses, one to the
- * WaveFront and one to any external MIDI devices. Given the 32
- * voice nature of the WaveFront, its pretty easy to find a use
- * for all 16 channels driving just that synth.
- *
- */
-
-/*
- * Copyright (C) by Paul Barton-Davis 1998
- * Some portions of this file are derived from work that is:
- *
- *    CopyriGht (C) by Hannu Savolainen 1993-1996
- *
- * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include <linux/wavefront.h>
-
-#ifdef MODULE
-
-struct wf_mpu_config {
-	int             base;
-#define	DATAPORT(d)   (d)->base
-#define	COMDPORT(d)   (d)->base+1
-#define	STATPORT(d)   (d)->base+1
-
-	int             irq;
-	int             opened;
-	int             devno;
-	int             synthno;
-	int             mode;
-#define MODE_MIDI	1
-#define MODE_SYNTH	2
-
-	void            (*inputintr) (int dev, unsigned char data);
-	char isvirtual;                /* do virtual I/O stuff */
-};
-
-static struct wf_mpu_config  devs[2];
-static struct wf_mpu_config *phys_dev = &devs[0];
-static struct wf_mpu_config *virt_dev = &devs[1];
-
-static void start_uart_mode (void);
-static DEFINE_SPINLOCK(lock);
-
-#define	OUTPUT_READY	0x40
-#define	INPUT_AVAIL	0x80
-#define	MPU_ACK		0xFE
-#define	UART_MODE_ON	0x3F
-
-static inline int wf_mpu_status (void)
-{
-	return inb (STATPORT (phys_dev));
-}
-
-static inline int input_avail (void)
-{
-	return !(wf_mpu_status() & INPUT_AVAIL);
-}
-
-static inline int output_ready (void)
-{
-	return !(wf_mpu_status() & OUTPUT_READY);
-}
-
-static inline int  read_data (void)
-{
-	return inb (DATAPORT (phys_dev));
-}
-
-static inline void write_data (unsigned char byte)
-{
-	outb (byte, DATAPORT (phys_dev));
-}
-
-/*
- * States for the input scanner (should be in dev_table.h)
- */
-
-#define MST_SYSMSG		100	/* System message (sysx etc). */
-#define MST_MTC			102	/* Midi Time Code (MTC) qframe msg */
-#define MST_SONGSEL		103	/* Song select */
-#define MST_SONGPOS		104	/* Song position pointer */
-#define MST_TIMED		105	/* Leading timing byte rcvd */
-
-/* buffer space check for input scanner */
-
-#define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) \
-{printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%d\n", \
-	mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;}
-
-static unsigned char len_tab[] =	/* # of data bytes following a status
-					 */
-{
-	2,				/* 8x */
-	2,				/* 9x */
-	2,				/* Ax */
-	2,				/* Bx */
-	1,				/* Cx */
-	1,				/* Dx */
-	2,				/* Ex */
-	0				/* Fx */
-};
-
-static int
-wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic)
-
-{
-	struct midi_input_info *mi = &midi_devs[devno]->in_info;
-
-	switch (mi->m_state) {
-	case MST_INIT:
-		switch (midic) {
-		case 0xf8:
-			/* Timer overflow */
-			break;
-		
-		case 0xfc:
-			break;
-		
-		case 0xfd:
-			/* XXX do something useful with this. If there is
-			   an external MIDI timer (e.g. a hardware sequencer,
-			   a useful timer can be derived ...
-		   
-			   For now, no timer support.
-			*/
-			break;
-		
-		case 0xfe:
-			return MPU_ACK;
-			break;
-		
-		case 0xf0:
-		case 0xf1:
-		case 0xf2:
-		case 0xf3:
-		case 0xf4:
-		case 0xf5:
-		case 0xf6:
-		case 0xf7:
-			break;
-		
-		case 0xf9:
-			break;
-		
-		case 0xff:
-			mi->m_state = MST_SYSMSG;
-			break;
-		
-		default:
-			if (midic <= 0xef) {
-				mi->m_state = MST_TIMED;
-			}
-			else
-				printk (KERN_ERR "<MPU: Unknown event %02x> ",
-					midic);
-		}
-		break;
-	  
-	case MST_TIMED:
-	{
-		int             msg = ((int) (midic & 0xf0) >> 4);
-	  
-		mi->m_state = MST_DATA;
-	  
-		if (msg < 8) {	/* Data byte */
-	      
-			msg = ((int) (mi->m_prev_status & 0xf0) >> 4);
-			msg -= 8;
-			mi->m_left = len_tab[msg] - 1;
-	      
-			mi->m_ptr = 2;
-			mi->m_buf[0] = mi->m_prev_status;
-			mi->m_buf[1] = midic;
-
-			if (mi->m_left <= 0) {
-				mi->m_state = MST_INIT;
-				do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-				mi->m_ptr = 0;
-			}
-		} else if (msg == 0xf) {	/* MPU MARK */
-	      
-			mi->m_state = MST_INIT;
-
-			switch (midic) {
-			case 0xf8:
-				break;
-		    
-			case 0xf9:
-				break;
-		    
-			case 0xfc:
-				break;
-		    
-			default:
-				break;
-			}
-		} else {
-			mi->m_prev_status = midic;
-			msg -= 8;
-			mi->m_left = len_tab[msg];
-	      
-			mi->m_ptr = 1;
-			mi->m_buf[0] = midic;
-	      
-			if (mi->m_left <= 0) {
-				mi->m_state = MST_INIT;
-				do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-				mi->m_ptr = 0;
-			}
-		}
-	}
-	break;
-
-	case MST_SYSMSG:
-		switch (midic) {
-		case 0xf0:
-			mi->m_state = MST_SYSEX;
-			break;
-	    
-		case 0xf1:
-			mi->m_state = MST_MTC;
-			break;
-
-		case 0xf2:
-			mi->m_state = MST_SONGPOS;
-			mi->m_ptr = 0;
-			break;
-	    
-		case 0xf3:
-			mi->m_state = MST_SONGSEL;
-			break;
-	    
-		case 0xf6:
-			mi->m_state = MST_INIT;
-	    
-			/*
-			 *    Real time messages
-			 */
-		case 0xf8:
-			/* midi clock */
-			mi->m_state = MST_INIT;
-			/* XXX need ext MIDI timer support */
-			break;
-	    
-		case 0xfA:
-			mi->m_state = MST_INIT;
-			/* XXX need ext MIDI timer support */
-			break;
-	    
-		case 0xFB:
-			mi->m_state = MST_INIT;
-			/* XXX need ext MIDI timer support */
-			break;
-	    
-		case 0xFC:
-			mi->m_state = MST_INIT;
-			/* XXX need ext MIDI timer support */
-			break;
-	    
-		case 0xFE:
-			/* active sensing */
-			mi->m_state = MST_INIT;
-			break;
-	    
-		case 0xff:
-			mi->m_state = MST_INIT;
-			break;
-
-		default:
-			printk (KERN_ERR "unknown MIDI sysmsg %0x\n", midic);
-			mi->m_state = MST_INIT;
-		}
-		break;
-
-	case MST_MTC:
-		mi->m_state = MST_INIT;
-		break;
-
-	case MST_SYSEX:
-		if (midic == 0xf7) {
-			mi->m_state = MST_INIT;
-		} else {
-			/* XXX fix me */
-		}
-		break;
-
-	case MST_SONGPOS:
-		BUFTEST (mi);
-		mi->m_buf[mi->m_ptr++] = midic;
-		if (mi->m_ptr == 2) {
-			mi->m_state = MST_INIT;
-			mi->m_ptr = 0;
-			/* XXX need ext MIDI timer support */
-		}
-		break;
-
-	case MST_DATA:
-		BUFTEST (mi);
-		mi->m_buf[mi->m_ptr++] = midic;
-		if ((--mi->m_left) <= 0) {
-			mi->m_state = MST_INIT;
-			do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-			mi->m_ptr = 0;
-		}
-		break;
-
-	default:
-		printk (KERN_ERR "Bad state %d ", mi->m_state);
-		mi->m_state = MST_INIT;
-	}
-
-	return 1;
-}
-
-static irqreturn_t
-wf_mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
-
-{
-	struct wf_mpu_config *physical_dev = dev_id;
-	static struct wf_mpu_config *input_dev;
-	struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info;
-	int n;
-
-	if (!input_avail()) { /* not for us */
-		return IRQ_NONE;
-	}
-
-	if (mi->m_busy)
-		return IRQ_HANDLED;
-	spin_lock(&lock);
-	mi->m_busy = 1;
-
-	if (!input_dev) {
-		input_dev = physical_dev;
-	}
-
-	n = 50; /* XXX why ? */
-
-	do {
-		unsigned char c = read_data ();
-      
-		if (phys_dev->isvirtual) {
-
-			if (c == WF_EXTERNAL_SWITCH) {
-				input_dev = virt_dev;
-				continue;
-			} else if (c == WF_INTERNAL_SWITCH) { 
-				input_dev = phys_dev;
-				continue;
-			} /* else just leave it as it is */
-
-		} else {
-			input_dev = phys_dev;
-		}
-
-		if (input_dev->mode == MODE_SYNTH) {
-	  
-			wf_mpu_input_scanner (input_dev->devno,
-					      input_dev->synthno, c);
-	  
-		} else if (input_dev->opened & OPEN_READ) {
-	  
-			if (input_dev->inputintr) {
-				input_dev->inputintr (input_dev->devno, c);
-			} 
-		}
-
-	} while (input_avail() && n-- > 0);
-
-	mi->m_busy = 0;
-	spin_unlock(&lock);
-	return IRQ_HANDLED;
-}
-
-static int
-wf_mpu_open (int dev, int mode,
-	     void            (*input) (int dev, unsigned char data),
-	     void            (*output) (int dev)
-	)
-{
-	struct wf_mpu_config *devc;
-
-	if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
-		return -(ENXIO);
-
-	if (phys_dev->devno == dev) {
-		devc = phys_dev;
-	} else if (phys_dev->isvirtual && virt_dev->devno == dev) {
-		devc = virt_dev;
-	} else {
-		printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-		return -(EINVAL);
-	}
-
-	if (devc->opened) {
-		return -(EBUSY);
-	}
-
-	devc->mode = MODE_MIDI;
-	devc->opened = mode;
-	devc->synthno = 0;
-
-	devc->inputintr = input;
-	return 0;
-}
- 
-static void
-wf_mpu_close (int dev)
-{
-	struct wf_mpu_config *devc;
-
-	if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
-		return;
-
-	if (phys_dev->devno == dev) {
-		devc = phys_dev;
-	} else if (phys_dev->isvirtual && virt_dev->devno == dev) {
-		devc = virt_dev;
-	} else {
-		printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-		return;
-	}
-
-	devc->mode = 0;
-	devc->inputintr = NULL;
-	devc->opened = 0;
-}
-
-static int
-wf_mpu_out (int dev, unsigned char midi_byte)
-{
-	int             timeout;
-	unsigned long   flags;
-	static int lastoutdev = -1;
-	unsigned char switchch;
-
-	if (phys_dev->isvirtual && lastoutdev != dev) {
-      
-		if (dev == phys_dev->devno) { 
-			switchch = WF_INTERNAL_SWITCH;
-		} else if (dev == virt_dev->devno) { 
-			switchch = WF_EXTERNAL_SWITCH;
-		} else {
-			printk (KERN_ERR "WF-MPU: bad device number %d", dev);
-			return (0);
-		}
-
-		/* XXX fix me */
-      
-		for (timeout = 30000; timeout > 0 && !output_ready ();
-		     timeout--);
-      
-		spin_lock_irqsave(&lock,flags);
-      
-		if (!output_ready ()) {
-			printk (KERN_WARNING "WF-MPU: Send switch "
-				"byte timeout\n");
-			spin_unlock_irqrestore(&lock,flags);
-			return 0;
-		}
-      
-		write_data (switchch);
-		spin_unlock_irqrestore(&lock,flags);
-	} 
-
-	lastoutdev = dev;
-
-	/*
-	 * Sometimes it takes about 30000 loops before the output becomes ready
-	 * (After reset). Normally it takes just about 10 loops.
-	 */
-
-	/* XXX fix me */
-
-	for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
-
-	spin_lock_irqsave(&lock,flags);
-	if (!output_ready ()) {
-		spin_unlock_irqrestore(&lock,flags);
-		printk (KERN_WARNING "WF-MPU: Send data timeout\n");
-		return 0;
-	}
-
-	write_data (midi_byte);
-	spin_unlock_irqrestore(&lock,flags);
-
-	return 1;
-}
-
-static inline int wf_mpu_start_read (int dev) {
-	return 0;
-}
-
-static inline int wf_mpu_end_read (int dev) {
-	return 0;
-}
-
-static int wf_mpu_ioctl (int dev, unsigned cmd, void __user *arg)
-{
-	printk (KERN_WARNING
-		"WF-MPU: Intelligent mode not supported by hardware.\n");
-	return -(EINVAL);
-}
-
-static int wf_mpu_buffer_status (int dev)
-{
-	return 0;
-}
-
-static struct synth_operations wf_mpu_synth_operations[2];
-static struct midi_operations  wf_mpu_midi_operations[2];
-
-static struct midi_operations wf_mpu_midi_proto =
-{
-	.owner		= THIS_MODULE,
-	.info		= {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
-	.in_info	= {0},   /* in_info */
-	.open		= wf_mpu_open,
-	.close		= wf_mpu_close,
-	.ioctl		= wf_mpu_ioctl,
-	.outputc	= wf_mpu_out,
-	.start_read	= wf_mpu_start_read,
-	.end_read	= wf_mpu_end_read,
-	.buffer_status	= wf_mpu_buffer_status,
-};
-
-static struct synth_info wf_mpu_synth_info_proto =
-{"WaveFront MPU-401 interface", 0,
- SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
-
-static struct synth_info wf_mpu_synth_info[2];
-
-static int
-wf_mpu_synth_ioctl (int dev, unsigned int cmd, void __user *arg)
-{
-	int             midi_dev;
-	int index;
-
-	midi_dev = synth_devs[dev]->midi_dev;
-
-	if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
-		return -(ENXIO);
-
-	if (midi_dev == phys_dev->devno) {
-		index = 0;
-	} else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) {
-		index = 1;
-	} else {
-		return -(EINVAL);
-	}
-
-	switch (cmd) {
-
-	case SNDCTL_SYNTH_INFO:
-		if (copy_to_user(arg,
-			      &wf_mpu_synth_info[index],
-			      sizeof (struct synth_info)))
-			return -EFAULT;
-		return 0;
-	
-	case SNDCTL_SYNTH_MEMAVL:
-		return 0x7fffffff;
-	
-	default:
-		return -EINVAL;
-	}
-}
-
-static int
-wf_mpu_synth_open (int dev, int mode)
-{
-	int             midi_dev;
-	struct wf_mpu_config *devc;
-
-	midi_dev = synth_devs[dev]->midi_dev;
-
-	if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) {
-		return -(ENXIO);
-	}
-  
-	if (phys_dev->devno == midi_dev) {
-		devc = phys_dev;
-	} else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
-		devc = virt_dev;
-	} else {
-		printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-		return -(EINVAL);
-	}
-
-	if (devc->opened) {
-		return -(EBUSY);
-	}
-  
-	devc->mode = MODE_SYNTH;
-	devc->synthno = dev;
-	devc->opened = mode;
-	devc->inputintr = NULL;
-	return 0;
-}
-
-static void
-wf_mpu_synth_close (int dev)
-{
-	int             midi_dev;
-	struct wf_mpu_config *devc;
-
-	midi_dev = synth_devs[dev]->midi_dev;
-
-	if (phys_dev->devno == midi_dev) {
-		devc = phys_dev;
-	} else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
-		devc = virt_dev;
-	} else {
-		printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-		return;
-	}
-
-	devc->inputintr = NULL;
-	devc->opened = 0;
-	devc->mode = 0;
-}
-
-#define _MIDI_SYNTH_C_
-#define MIDI_SYNTH_NAME	"WaveFront (MIDI)"
-#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct synth_operations wf_mpu_synth_proto =
-{
-	.owner		= THIS_MODULE,
-	.id		= "WaveFront (ICS2115)",
-	.info		= NULL,  /* info field, filled in during configuration */
-	.midi_dev	= 0,     /* MIDI dev XXX should this be -1 ? */
-	.synth_type	= SYNTH_TYPE_MIDI,
-	.synth_subtype	= SAMPLE_TYPE_WAVEFRONT,
-	.open		= wf_mpu_synth_open,
-	.close		= wf_mpu_synth_close,
-	.ioctl		= wf_mpu_synth_ioctl,
-	.kill_note	= midi_synth_kill_note,
-	.start_note	= midi_synth_start_note,
-	.set_instr	= midi_synth_set_instr,
-	.reset		= midi_synth_reset,
-	.hw_control	= midi_synth_hw_control,
-	.load_patch	= midi_synth_load_patch,
-	.aftertouch	= midi_synth_aftertouch,
-	.controller	= midi_synth_controller,
-	.panning	= midi_synth_panning,
-	.bender		= midi_synth_bender,
-	.setup_voice	= midi_synth_setup_voice,
-	.send_sysex	= midi_synth_send_sysex
-};
-
-static int
-config_wf_mpu (struct wf_mpu_config *dev)
-
-{
-	int is_external;
-	char *name;
-	int index;
-
-	if (dev == phys_dev) {
-		name = "WaveFront internal MIDI";
-		is_external = 0;
-		index = 0;
-		memcpy ((char *) &wf_mpu_synth_operations[index],
-			(char *) &wf_mpu_synth_proto,
-			sizeof (struct synth_operations));
-	} else {
-		name = "WaveFront external MIDI";
-		is_external = 1;
-		index = 1;
-		/* no synth operations for an external MIDI interface */
-	}
-
-	memcpy ((char *) &wf_mpu_synth_info[dev->devno],
-		(char *) &wf_mpu_synth_info_proto,
-		sizeof (struct synth_info));
-
-	strcpy (wf_mpu_synth_info[index].name, name);
-
-	wf_mpu_synth_operations[index].midi_dev = dev->devno;
-	wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index];
-
-	memcpy ((char *) &wf_mpu_midi_operations[index],
-		(char *) &wf_mpu_midi_proto,
-		sizeof (struct midi_operations));
-  
-	if (is_external) {
-		wf_mpu_midi_operations[index].converter = NULL;
-	} else {
-		wf_mpu_midi_operations[index].converter =
-			&wf_mpu_synth_operations[index];
-	}
-
-	strcpy (wf_mpu_midi_operations[index].info.name, name);
-
-	midi_devs[dev->devno] = &wf_mpu_midi_operations[index];
-	midi_devs[dev->devno]->in_info.m_busy = 0;
-	midi_devs[dev->devno]->in_info.m_state = MST_INIT;
-	midi_devs[dev->devno]->in_info.m_ptr = 0;
-	midi_devs[dev->devno]->in_info.m_left = 0;
-	midi_devs[dev->devno]->in_info.m_prev_status = 0;
-
-	devs[index].opened = 0;
-	devs[index].mode = 0;
-
-	return (0);
-}
-
-int virtual_midi_enable (void)
-
-{
-	if ((virt_dev->devno < 0) &&
-	    (virt_dev->devno = sound_alloc_mididev()) == -1) {
-		printk (KERN_ERR
-			"WF-MPU: too many midi devices detected\n");
-		return -1;
-	}
-
-	config_wf_mpu (virt_dev);
-
-	phys_dev->isvirtual = 1;
-	return virt_dev->devno;
-}
-
-int
-virtual_midi_disable (void)
-
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&lock,flags);
-
-	wf_mpu_close (virt_dev->devno);
-	/* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
-	phys_dev->isvirtual = 0;
-
-	spin_unlock_irqrestore(&lock,flags);
-
-	return 0;
-}
-
-int __init detect_wf_mpu (int irq, int io_base)
-{
-	if (!request_region(io_base, 2, "wavefront midi")) {
-		printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n",
-			io_base);
-		return -1;
-	}
-
-	phys_dev->base = io_base;
-	phys_dev->irq = irq;
-	phys_dev->devno = -1;
-	virt_dev->devno = -1;
-
-	return 0;
-}
-
-int __init install_wf_mpu (void)
-{
-	if ((phys_dev->devno = sound_alloc_mididev()) < 0){
-
-		printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
-		release_region(phys_dev->base, 2);
-		return -1;
-	}
-
-	phys_dev->isvirtual = 0;
-
-	if (config_wf_mpu (phys_dev)) {
-
-		printk (KERN_WARNING
-			"WF-MPU: configuration for MIDI device %d failed\n",
-			phys_dev->devno);
-		sound_unload_mididev (phys_dev->devno);
-
-	}
-
-	/* OK, now we're configured to handle an interrupt ... */
-
-	if (request_irq (phys_dev->irq, wf_mpuintr, IRQF_DISABLED|IRQF_SHARED,
-			 "wavefront midi", phys_dev) < 0) {
-
-		printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
-			phys_dev->irq);
-		return -1;
-
-	}
-
-	/* This being a WaveFront (ICS-2115) emulated MPU-401, we have
-	   to switch it into UART (dumb) mode, because otherwise, it
-	   won't do anything at all.
-	*/
-  
-	start_uart_mode ();
-
-	return phys_dev->devno;
-}
- 
-void
-uninstall_wf_mpu (void)
-
-{
-	release_region (phys_dev->base, 2); 
-	free_irq (phys_dev->irq, phys_dev);
-	sound_unload_mididev (phys_dev->devno);
-
-	if (virt_dev->devno >= 0) {
-		sound_unload_mididev (virt_dev->devno);
-	}
-}
-
-static void
-start_uart_mode (void)
-
-{
-	int             ok, i;
-	unsigned long   flags;
-
-	spin_lock_irqsave(&lock,flags);
-
-	/* XXX fix me */
-
-	for (i = 0; i < 30000 && !output_ready (); i++);
-
-	outb (UART_MODE_ON, COMDPORT(phys_dev));
-
-	for (ok = 0, i = 50000; i > 0 && !ok; i--) {
-		if (input_avail ()) {
-			if (read_data () == MPU_ACK) {
-				ok = 1;
-			}
-		}
-	}
-
-	spin_unlock_irqrestore(&lock,flags);
-}
-#endif
diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
deleted file mode 100644
index 6e22472..0000000
--- a/sound/oss/ymfpci.c
+++ /dev/null
@@ -1,2692 +0,0 @@
-/*
- *  Copyright 1999 Jaroslav Kysela <perex@suse.cz>
- *  Copyright 2000 Alan Cox <alan@redhat.com>
- *  Copyright 2001 Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
- *  Copyright 2002 Pete Zaitcev <zaitcev@yahoo.com>
- *
- *  Yamaha YMF7xx driver.
- *
- *  This code is a result of high-speed collision
- *  between ymfpci.c of ALSA and cs46xx.c of Linux.
- *  -- Pete Zaitcev <zaitcev@yahoo.com>; 2000/09/18
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * TODO:
- *  - Use P44Slot for 44.1 playback (beware of idle buzzing in P44Slot).
- *  - 96KHz playback for DVD - use pitch of 2.0.
- *  - Retain DMA buffer on close, do not wait the end of frame.
- *  - Resolve XXX tagged questions.
- *  - Cannot play 5133Hz.
- *  - 2001/01/07 Consider if we can remove voice_lock, like so:
- *     : Allocate/deallocate voices in open/close under semafore.
- *     : We access voices in interrupt, that only for pcms that open.
- *    voice_lock around playback_prepare closes interrupts for insane duration.
- *  - Revisit the way voice_alloc is done - too confusing, overcomplicated.
- *    Should support various channel types, however.
- *  - Remove prog_dmabuf from read/write, leave it in open.
- *  - 2001/01/07 Replace the OPL3 part of CONFIG_SOUND_YMFPCI_LEGACY code with
- *    native synthesizer through a playback slot.
- *  - 2001/11/29 ac97_save_state
- *    Talk to Kai to remove ac97_save_state before it's too late!
- *  - Second AC97
- *  - Restore S/PDIF - Toshibas have it.
- *
- * Kai used pci_alloc_consistent for DMA buffer, which sounds a little
- * unconventional. However, given how small our fragments can be,
- * a little uncached access is perhaps better than endless flushing.
- * On i386 and other I/O-coherent architectures pci_alloc_consistent
- * is entirely harmless.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/soundcard.h>
-#include <linux/ac97_codec.h>
-#include <linux/sound.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-# include "sound_config.h"
-# include "mpu401.h"
-#endif
-#include "ymfpci.h"
-
-/*
- * I do not believe in debug levels as I never can guess what
- * part of the code is going to be problematic in the future.
- * Don't forget to run your klogd with -c 8.
- *
- * Example (do not remove):
- * #define YMFDBG(fmt, arg...)  do{ printk(KERN_DEBUG fmt, ##arg); }while(0)
- */
-#define YMFDBGW(fmt, arg...)  /* */	/* write counts */
-#define YMFDBGI(fmt, arg...)  /* */	/* interrupts */
-#define YMFDBGX(fmt, arg...)  /* */	/* ioctl */
-
-static int ymf_playback_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
-static void ymf_capture_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
-static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice);
-static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank);
-static int ymf_playback_prepare(struct ymf_state *state);
-static int ymf_capture_prepare(struct ymf_state *state);
-static struct ymf_state *ymf_state_alloc(ymfpci_t *unit);
-
-static void ymfpci_aclink_reset(struct pci_dev * pci);
-static void ymfpci_disable_dsp(ymfpci_t *unit);
-static void ymfpci_download_image(ymfpci_t *codec);
-static void ymf_memload(ymfpci_t *unit);
-
-static DEFINE_SPINLOCK(ymf_devs_lock);
-static LIST_HEAD(ymf_devs);
-
-/*
- *  constants
- */
-
-static struct pci_device_id ymf_id_tbl[] = {
-#define DEV(dev, data) \
-	{ PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \
-		(unsigned long)data }
-	DEV (PCI_DEVICE_ID_YAMAHA_724,  "YMF724"),
-	DEV (PCI_DEVICE_ID_YAMAHA_724F, "YMF724F"),
-	DEV (PCI_DEVICE_ID_YAMAHA_740,  "YMF740"),
-	DEV (PCI_DEVICE_ID_YAMAHA_740C, "YMF740C"),
-	DEV (PCI_DEVICE_ID_YAMAHA_744,  "YMF744"),
-	DEV (PCI_DEVICE_ID_YAMAHA_754,  "YMF754"),
-#undef DEV
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, ymf_id_tbl);
-
-/*
- *  common I/O routines
- */
-
-static inline void ymfpci_writeb(ymfpci_t *codec, u32 offset, u8 val)
-{
-	writeb(val, codec->reg_area_virt + offset);
-}
-
-static inline u16 ymfpci_readw(ymfpci_t *codec, u32 offset)
-{
-	return readw(codec->reg_area_virt + offset);
-}
-
-static inline void ymfpci_writew(ymfpci_t *codec, u32 offset, u16 val)
-{
-	writew(val, codec->reg_area_virt + offset);
-}
-
-static inline u32 ymfpci_readl(ymfpci_t *codec, u32 offset)
-{
-	return readl(codec->reg_area_virt + offset);
-}
-
-static inline void ymfpci_writel(ymfpci_t *codec, u32 offset, u32 val)
-{
-	writel(val, codec->reg_area_virt + offset);
-}
-
-static int ymfpci_codec_ready(ymfpci_t *codec, int secondary, int sched)
-{
-	signed long end_time;
-	u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
-	
-	end_time = jiffies + 3 * (HZ / 4);
-	do {
-		if ((ymfpci_readw(codec, reg) & 0x8000) == 0)
-			return 0;
-		if (sched) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		}
-	} while (end_time - (signed long)jiffies >= 0);
-	printk(KERN_ERR "ymfpci_codec_ready: codec %i is not ready [0x%x]\n",
-	    secondary, ymfpci_readw(codec, reg));
-	return -EBUSY;
-}
-
-static void ymfpci_codec_write(struct ac97_codec *dev, u8 reg, u16 val)
-{
-	ymfpci_t *codec = dev->private_data;
-	u32 cmd;
-
-	spin_lock(&codec->ac97_lock);
-	/* XXX Do make use of dev->id */
-	ymfpci_codec_ready(codec, 0, 0);
-	cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val;
-	ymfpci_writel(codec, YDSXGR_AC97CMDDATA, cmd);
-	spin_unlock(&codec->ac97_lock);
-}
-
-static u16 _ymfpci_codec_read(ymfpci_t *unit, u8 reg)
-{
-	int i;
-
-	if (ymfpci_codec_ready(unit, 0, 0))
-		return ~0;
-	ymfpci_writew(unit, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg);
-	if (ymfpci_codec_ready(unit, 0, 0))
-		return ~0;
-	if (unit->pci->device == PCI_DEVICE_ID_YAMAHA_744 && unit->rev < 2) {
-		for (i = 0; i < 600; i++)
-			ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
-	}
-	return ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
-}
-
-static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg)
-{
-	ymfpci_t *unit = dev->private_data;
-	u16 ret;
-	
-	spin_lock(&unit->ac97_lock);
-	ret = _ymfpci_codec_read(unit, reg);
-	spin_unlock(&unit->ac97_lock);
-	
-	return ret;
-}
-
-/*
- *  Misc routines
- */
-
-/*
- * Calculate the actual sampling rate relatetively to the base clock (48kHz).
- */
-static u32 ymfpci_calc_delta(u32 rate)
-{
-	switch (rate) {
-	case 8000:	return 0x02aaab00;
-	case 11025:	return 0x03accd00;
-	case 16000:	return 0x05555500;
-	case 22050:	return 0x07599a00;
-	case 32000:	return 0x0aaaab00;
-	case 44100:	return 0x0eb33300;
-	default:	return ((rate << 16) / 48000) << 12;
-	}
-}
-
-static u32 def_rate[8] = {
-	100, 2000, 8000, 11025, 16000, 22050, 32000, 48000
-};
-
-static u32 ymfpci_calc_lpfK(u32 rate)
-{
-	u32 i;
-	static u32 val[8] = {
-		0x00570000, 0x06AA0000, 0x18B20000, 0x20930000,
-		0x2B9A0000, 0x35A10000, 0x3EAA0000, 0x40000000
-	};
-	
-	if (rate == 44100)
-		return 0x40000000;	/* FIXME: What's the right value? */
-	for (i = 0; i < 8; i++)
-		if (rate <= def_rate[i])
-			return val[i];
-	return val[0];
-}
-
-static u32 ymfpci_calc_lpfQ(u32 rate)
-{
-	u32 i;
-	static u32 val[8] = {
-		0x35280000, 0x34A70000, 0x32020000, 0x31770000,
-		0x31390000, 0x31C90000, 0x33D00000, 0x40000000
-	};
-	
-	if (rate == 44100)
-		return 0x370A0000;
-	for (i = 0; i < 8; i++)
-		if (rate <= def_rate[i])
-			return val[i];
-	return val[0];
-}
-
-static u32 ymf_calc_lend(u32 rate)
-{
-	return (rate * YMF_SAMPF) / 48000;
-}
-
-/*
- * We ever allow only a few formats, but let's be generic, for smaller surprise.
- */
-static int ymf_pcm_format_width(int format)
-{
-	static int mask16 = AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE;
-
-	if ((format & (format-1)) != 0) {
-		printk(KERN_ERR "ymfpci: format 0x%x is not a power of 2\n", format);
-		return 8;
-	}
-
-	if (format == AFMT_IMA_ADPCM) return 4;
-	if ((format & mask16) != 0) return 16;
-	return 8;
-}
-
-static void ymf_pcm_update_shift(struct ymf_pcm_format *f)
-{
-	f->shift = 0;
-	if (f->voices == 2)
-		f->shift++;
-	if (ymf_pcm_format_width(f->format) == 16)
-		f->shift++;
-}
-
-/* Are you sure 32K is not too much? See if mpg123 skips on loaded systems. */
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-/*
- * Allocate DMA buffer
- */
-static int alloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
-{
-	void *rawbuf = NULL;
-	dma_addr_t dma_addr;
-	int order;
-	struct page *map, *mapend;
-
-	/* alloc as big a chunk as we can */
-	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
-		rawbuf = pci_alloc_consistent(unit->pci, PAGE_SIZE << order, &dma_addr);
-		if (rawbuf)
-			break;
-	}
-	if (!rawbuf)
-		return -ENOMEM;
-
-#if 0
-	printk(KERN_DEBUG "ymfpci: allocated %ld (order = %d) bytes at %p\n",
-	       PAGE_SIZE << order, order, rawbuf);
-#endif
-
-	dmabuf->ready  = dmabuf->mapped = 0;
-	dmabuf->rawbuf = rawbuf;
-	dmabuf->dma_addr = dma_addr;
-	dmabuf->buforder = order;
-
-	/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-	mapend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-	for (map = virt_to_page(rawbuf); map <= mapend; map++)
-		set_bit(PG_reserved, &map->flags);
-
-	return 0;
-}
-
-/*
- * Free DMA buffer
- */
-static void dealloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
-{
-	struct page *map, *mapend;
-
-	if (dmabuf->rawbuf) {
-		/* undo marking the pages as reserved */
-		mapend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
-		for (map = virt_to_page(dmabuf->rawbuf); map <= mapend; map++)
-			clear_bit(PG_reserved, &map->flags);
-
-		pci_free_consistent(unit->pci, PAGE_SIZE << dmabuf->buforder,
-		    dmabuf->rawbuf, dmabuf->dma_addr);
-	}
-	dmabuf->rawbuf = NULL;
-	dmabuf->mapped = dmabuf->ready = 0;
-}
-
-static int prog_dmabuf(struct ymf_state *state, int rec)
-{
-	struct ymf_dmabuf *dmabuf;
-	int w_16;
-	unsigned bufsize;
-	unsigned long flags;
-	int redzone, redfrags;
-	int ret;
-
-	w_16 = ymf_pcm_format_width(state->format.format) == 16;
-	dmabuf = rec ? &state->rpcm.dmabuf : &state->wpcm.dmabuf;
-
-	spin_lock_irqsave(&state->unit->reg_lock, flags);
-	dmabuf->hwptr = dmabuf->swptr = 0;
-	dmabuf->total_bytes = 0;
-	dmabuf->count = 0;
-	spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-
-	/* allocate DMA buffer if not allocated yet */
-	if (!dmabuf->rawbuf)
-		if ((ret = alloc_dmabuf(state->unit, dmabuf)))
-			return ret;
-
-	/*
-	 * Create fake fragment sizes and numbers for OSS ioctls.
-	 * Import what Doom might have set with SNDCTL_DSP_SETFRAGMENT.
-	 */
-	bufsize = PAGE_SIZE << dmabuf->buforder;
-	/* By default we give 4 big buffers. */
-	dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT - 2);
-	if (dmabuf->ossfragshift > 3 &&
-	    dmabuf->ossfragshift < dmabuf->fragshift) {
-		/* If OSS set smaller fragments, give more smaller buffers. */
-		dmabuf->fragshift = dmabuf->ossfragshift;
-	}
-	dmabuf->fragsize = 1 << dmabuf->fragshift;
-
-	dmabuf->numfrag = bufsize >> dmabuf->fragshift;
-	dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
-
-	if (dmabuf->ossmaxfrags >= 2) {
-		redzone = ymf_calc_lend(state->format.rate);
-		redzone <<= state->format.shift;
-		redzone *= 3;
-		redfrags = (redzone + dmabuf->fragsize-1) >> dmabuf->fragshift;
-
-		if (dmabuf->ossmaxfrags + redfrags < dmabuf->numfrag) {
-			dmabuf->numfrag = dmabuf->ossmaxfrags + redfrags;
-			dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
-		}
-	}
-
-	memset(dmabuf->rawbuf, w_16 ? 0 : 0x80, dmabuf->dmasize);
-
-	/*
-	 *	Now set up the ring 
-	 */
-
-	/* XXX   ret = rec? cap_pre(): pbk_pre();  */
-	spin_lock_irqsave(&state->unit->voice_lock, flags);
-	if (rec) {
-		if ((ret = ymf_capture_prepare(state)) != 0) {
-			spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-			return ret;
-		}
-	} else {
-		if ((ret = ymf_playback_prepare(state)) != 0) {
-			spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-			return ret;
-		}
-	}
-	spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-
-	/* set the ready flag for the dma buffer (this comment is not stupid) */
-	dmabuf->ready = 1;
-
-#if 0
-	printk(KERN_DEBUG "prog_dmabuf: rate %d format 0x%x,"
-	    " numfrag %d fragsize %d dmasize %d\n",
-	       state->format.rate, state->format.format, dmabuf->numfrag,
-	       dmabuf->fragsize, dmabuf->dmasize);
-#endif
-
-	return 0;
-}
-
-static void ymf_start_dac(struct ymf_state *state)
-{
-	ymf_playback_trigger(state->unit, &state->wpcm, 1);
-}
-
-// static void ymf_start_adc(struct ymf_state *state)
-// {
-// 	ymf_capture_trigger(state->unit, &state->rpcm, 1);
-// }
-
-/*
- * Wait until output is drained.
- * This does not kill the hardware for the sake of ioctls.
- */
-static void ymf_wait_dac(struct ymf_state *state)
-{
-	struct ymf_unit *unit = state->unit;
-	struct ymf_pcm *ypcm = &state->wpcm;
-	DECLARE_WAITQUEUE(waita, current);
-	unsigned long flags;
-
-	add_wait_queue(&ypcm->dmabuf.wait, &waita);
-
-	spin_lock_irqsave(&unit->reg_lock, flags);
-	if (ypcm->dmabuf.count != 0 && !ypcm->running) {
-		ymf_playback_trigger(unit, ypcm, 1);
-	}
-
-#if 0
-	if (file->f_flags & O_NONBLOCK) {
-		/*
-		 * XXX Our  mistake is to attach DMA buffer to state
-		 * rather than to some per-device structure.
-		 * Cannot skip waiting, can only make it shorter.
-		 */
-	}
-#endif
-
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	while (ypcm->running) {
-		spin_unlock_irqrestore(&unit->reg_lock, flags);
-		schedule();
-		spin_lock_irqsave(&unit->reg_lock, flags);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-	}
-	spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&ypcm->dmabuf.wait, &waita);
-
-	/*
-	 * This function may take up to 4 seconds to reach this point
-	 * (32K circular buffer, 8000 Hz). User notices.
-	 */
-}
-
-/* Can just stop, without wait. Or can we? */
-static void ymf_stop_adc(struct ymf_state *state)
-{
-	struct ymf_unit *unit = state->unit;
-	unsigned long flags;
-
-	spin_lock_irqsave(&unit->reg_lock, flags);
-	ymf_capture_trigger(unit, &state->rpcm, 0);
-	spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-/*
- *  Hardware start management
- */
-
-static void ymfpci_hw_start(ymfpci_t *unit)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&unit->reg_lock, flags);
-	if (unit->start_count++ == 0) {
-		ymfpci_writel(unit, YDSXGR_MODE,
-		    ymfpci_readl(unit, YDSXGR_MODE) | 3);
-		unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1;
-	}
-	spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-static void ymfpci_hw_stop(ymfpci_t *unit)
-{
-	unsigned long flags;
-	long timeout = 1000;
-
-	spin_lock_irqsave(&unit->reg_lock, flags);
-	if (--unit->start_count == 0) {
-		ymfpci_writel(unit, YDSXGR_MODE,
-		    ymfpci_readl(unit, YDSXGR_MODE) & ~3);
-		while (timeout-- > 0) {
-			if ((ymfpci_readl(unit, YDSXGR_STATUS) & 2) == 0)
-				break;
-		}
-	}
-	spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-/*
- *  Playback voice management
- */
-
-static int voice_alloc(ymfpci_t *codec, ymfpci_voice_type_t type, int pair, ymfpci_voice_t *rvoice[])
-{
-	ymfpci_voice_t *voice, *voice2;
-	int idx;
-
-	for (idx = 0; idx < YDSXG_PLAYBACK_VOICES; idx += pair ? 2 : 1) {
-		voice = &codec->voices[idx];
-		voice2 = pair ? &codec->voices[idx+1] : NULL;
-		if (voice->use || (voice2 && voice2->use))
-			continue;
-		voice->use = 1;
-		if (voice2)
-			voice2->use = 1;
-		switch (type) {
-		case YMFPCI_PCM:
-			voice->pcm = 1;
-			if (voice2)
-				voice2->pcm = 1;
-			break;
-		case YMFPCI_SYNTH:
-			voice->synth = 1;
-			break;
-		case YMFPCI_MIDI:
-			voice->midi = 1;
-			break;
-		}
-		ymfpci_hw_start(codec);
-		rvoice[0] = voice;
-		if (voice2) {
-			ymfpci_hw_start(codec);
-			rvoice[1] = voice2;
-		}
-		return 0;
-	}
-	return -EBUSY;	/* Your audio channel is open by someone else. */
-}
-
-static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice)
-{
-	ymfpci_hw_stop(unit);
-	pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
-	pvoice->ypcm = NULL;
-}
-
-/*
- */
-
-static void ymf_pcm_interrupt(ymfpci_t *codec, ymfpci_voice_t *voice)
-{
-	struct ymf_pcm *ypcm;
-	int redzone;
-	int pos, delta, swptr;
-	int played, distance;
-	struct ymf_state *state;
-	struct ymf_dmabuf *dmabuf;
-	char silence;
-
-	if ((ypcm = voice->ypcm) == NULL) {
-		return;
-	}
-	if ((state = ypcm->state) == NULL) {
-		ypcm->running = 0;	// lock it
-		return;
-	}
-	dmabuf = &ypcm->dmabuf;
-	spin_lock(&codec->reg_lock);
-	if (ypcm->running) {
-		YMFDBGI("ymfpci: %d, intr bank %d count %d start 0x%x:%x\n",
-		   voice->number, codec->active_bank, dmabuf->count,
-		   le32_to_cpu(voice->bank[0].start),
-		   le32_to_cpu(voice->bank[1].start));
-		silence = (ymf_pcm_format_width(state->format.format) == 16) ?
-		    0 : 0x80;
-		/* We need actual left-hand-side redzone size here. */
-		redzone = ymf_calc_lend(state->format.rate);
-		redzone <<= (state->format.shift + 1);
-		swptr = dmabuf->swptr;
-
-		pos = le32_to_cpu(voice->bank[codec->active_bank].start);
-		pos <<= state->format.shift;
-		if (pos < 0 || pos >= dmabuf->dmasize) {	/* ucode bug */
-			printk(KERN_ERR "ymfpci%d: runaway voice %d: hwptr %d=>%d dmasize %d\n",
-			    codec->dev_audio, voice->number,
-			    dmabuf->hwptr, pos, dmabuf->dmasize);
-			pos = 0;
-		}
-		if (pos < dmabuf->hwptr) {
-			delta = dmabuf->dmasize - dmabuf->hwptr;
-			memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta);
-			delta += pos;
-			memset(dmabuf->rawbuf, silence, pos);
-		} else {
-			delta = pos - dmabuf->hwptr;
-			memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta);
-		}
-		dmabuf->hwptr = pos;
-
-		if (dmabuf->count == 0) {
-			printk(KERN_ERR "ymfpci%d: %d: strain: hwptr %d\n",
-			    codec->dev_audio, voice->number, dmabuf->hwptr);
-			ymf_playback_trigger(codec, ypcm, 0);
-		}
-
-		if (swptr <= pos) {
-			distance = pos - swptr;
-		} else {
-			distance = dmabuf->dmasize - (swptr - pos);
-		}
-		if (distance < redzone) {
-			/*
-			 * hwptr inside redzone => DMA ran out of samples.
-			 */
-			if (delta < dmabuf->count) {
-				/*
-				 * Lost interrupt or other screwage.
-				 */
-				printk(KERN_ERR "ymfpci%d: %d: lost: delta %d"
-				    " hwptr %d swptr %d distance %d count %d\n",
-				    codec->dev_audio, voice->number, delta,
-				    dmabuf->hwptr, swptr, distance, dmabuf->count);
-			} else {
-				/*
-				 * Normal end of DMA.
-				 */
-				YMFDBGI("ymfpci%d: %d: done: delta %d"
-				    " hwptr %d swptr %d distance %d count %d\n",
-				    codec->dev_audio, voice->number, delta,
-				    dmabuf->hwptr, swptr, distance, dmabuf->count);
-			}
-			played = dmabuf->count;
-			if (ypcm->running) {
-				ymf_playback_trigger(codec, ypcm, 0);
-			}
-		} else {
-			/*
-			 * hwptr is chipping away towards a remote swptr.
-			 * Calculate other distance and apply it to count.
-			 */
-			if (swptr >= pos) {
-				distance = swptr - pos;
-			} else {
-				distance = dmabuf->dmasize - (pos - swptr);
-			}
-			if (distance < dmabuf->count) {
-				played = dmabuf->count - distance;
-			} else {
-				played = 0;
-			}
-		}
-
-		dmabuf->total_bytes += played;
-		dmabuf->count -= played;
-		if (dmabuf->count < dmabuf->dmasize / 2) {
-			wake_up(&dmabuf->wait);
-		}
-	}
-	spin_unlock(&codec->reg_lock);
-}
-
-static void ymf_cap_interrupt(ymfpci_t *unit, struct ymf_capture *cap)
-{
-	struct ymf_pcm *ypcm;
-	int redzone;
-	struct ymf_state *state;
-	struct ymf_dmabuf *dmabuf;
-	int pos, delta;
-	int cnt;
-
-	if ((ypcm = cap->ypcm) == NULL) {
-		return;
-	}
-	if ((state = ypcm->state) == NULL) {
-		ypcm->running = 0;	// lock it
-		return;
-	}
-	dmabuf = &ypcm->dmabuf;
-	spin_lock(&unit->reg_lock);
-	if (ypcm->running) {
-		redzone = ymf_calc_lend(state->format.rate);
-		redzone <<= (state->format.shift + 1);
-
-		pos = le32_to_cpu(cap->bank[unit->active_bank].start);
-		// pos <<= state->format.shift;
-		if (pos < 0 || pos >= dmabuf->dmasize) {	/* ucode bug */
-			printk(KERN_ERR "ymfpci%d: runaway capture %d: hwptr %d=>%d dmasize %d\n",
-			    unit->dev_audio, ypcm->capture_bank_number,
-			    dmabuf->hwptr, pos, dmabuf->dmasize);
-			pos = 0;
-		}
-		if (pos < dmabuf->hwptr) {
-			delta = dmabuf->dmasize - dmabuf->hwptr;
-			delta += pos;
-		} else {
-			delta = pos - dmabuf->hwptr;
-		}
-		dmabuf->hwptr = pos;
-
-		cnt = dmabuf->count;
-		cnt += delta;
-		if (cnt + redzone > dmabuf->dmasize) {
-			/* Overflow - bump swptr */
-			dmabuf->count = dmabuf->dmasize - redzone;
-			dmabuf->swptr = dmabuf->hwptr + redzone;
-			if (dmabuf->swptr >= dmabuf->dmasize) {
-				dmabuf->swptr -= dmabuf->dmasize;
-			}
-		} else {
-			dmabuf->count = cnt;
-		}
-
-		dmabuf->total_bytes += delta;
-		if (dmabuf->count) {		/* && is_sleeping  XXX */
-			wake_up(&dmabuf->wait);
-		}
-	}
-	spin_unlock(&unit->reg_lock);
-}
-
-static int ymf_playback_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd)
-{
-
-	if (ypcm->voices[0] == NULL) {
-		return -EINVAL;
-	}
-	if (cmd != 0) {
-		codec->ctrl_playback[ypcm->voices[0]->number + 1] =
-		    cpu_to_le32(ypcm->voices[0]->bank_ba);
-		if (ypcm->voices[1] != NULL)
-			codec->ctrl_playback[ypcm->voices[1]->number + 1] =
-			    cpu_to_le32(ypcm->voices[1]->bank_ba);
-		ypcm->running = 1;
-	} else {
-		codec->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
-		if (ypcm->voices[1] != NULL)
-			codec->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
-		ypcm->running = 0;
-	}
-	return 0;
-}
-
-static void ymf_capture_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd)
-{
-	u32 tmp;
-
-	if (cmd != 0) {
-		tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) | (1 << ypcm->capture_bank_number);
-		ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp);
-		ypcm->running = 1;
-	} else {
-		tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) & ~(1 << ypcm->capture_bank_number);
-		ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp);
-		ypcm->running = 0;
-	}
-}
-
-static int ymfpci_pcm_voice_alloc(struct ymf_pcm *ypcm, int voices)
-{
-	struct ymf_unit *unit;
-	int err;
-
-	unit = ypcm->state->unit;
-	if (ypcm->voices[1] != NULL && voices < 2) {
-		ymfpci_voice_free(unit, ypcm->voices[1]);
-		ypcm->voices[1] = NULL;
-	}
-	if (voices == 1 && ypcm->voices[0] != NULL)
-		return 0;		/* already allocated */
-	if (voices == 2 && ypcm->voices[0] != NULL && ypcm->voices[1] != NULL)
-		return 0;		/* already allocated */
-	if (voices > 1) {
-		if (ypcm->voices[0] != NULL && ypcm->voices[1] == NULL) {
-			ymfpci_voice_free(unit, ypcm->voices[0]);
-			ypcm->voices[0] = NULL;
-		}		
-		if ((err = voice_alloc(unit, YMFPCI_PCM, 1, ypcm->voices)) < 0)
-			return err;
-		ypcm->voices[0]->ypcm = ypcm;
-		ypcm->voices[1]->ypcm = ypcm;
-	} else {
-		if ((err = voice_alloc(unit, YMFPCI_PCM, 0, ypcm->voices)) < 0)
-			return err;
-		ypcm->voices[0]->ypcm = ypcm;
-	}
-	return 0;
-}
-
-static void ymf_pcm_init_voice(ymfpci_voice_t *voice, int stereo,
-    int rate, int w_16, unsigned long addr, unsigned int end, int spdif)
-{
-	u32 format;
-	u32 delta = ymfpci_calc_delta(rate);
-	u32 lpfQ = ymfpci_calc_lpfQ(rate);
-	u32 lpfK = ymfpci_calc_lpfK(rate);
-	ymfpci_playback_bank_t *bank;
-	int nbank;
-
-	/*
-	 * The gain is a floating point number. According to the manual,
-	 * bit 31 indicates a sign bit, bit 30 indicates an integer part,
-	 * and bits [29:15] indicate a decimal fraction part. Thus,
-	 * for a gain of 1.0 the constant of 0x40000000 is loaded.
-	 */
-	unsigned default_gain = cpu_to_le32(0x40000000);
-
-	format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000);
-	if (stereo)
-		end >>= 1;
-	if (w_16)
-		end >>= 1;
-	for (nbank = 0; nbank < 2; nbank++) {
-		bank = &voice->bank[nbank];
-		bank->format = cpu_to_le32(format);
-		bank->loop_default = 0;	/* 0-loops forever, otherwise count */
-		bank->base = cpu_to_le32(addr);
-		bank->loop_start = 0;
-		bank->loop_end = cpu_to_le32(end);
-		bank->loop_frac = 0;
-		bank->eg_gain_end = default_gain;
-		bank->lpfQ = cpu_to_le32(lpfQ);
-		bank->status = 0;
-		bank->num_of_frames = 0;
-		bank->loop_count = 0;
-		bank->start = 0;
-		bank->start_frac = 0;
-		bank->delta =
-		bank->delta_end = cpu_to_le32(delta);
-		bank->lpfK =
-		bank->lpfK_end = cpu_to_le32(lpfK);
-		bank->eg_gain = default_gain;
-		bank->lpfD1 =
-		bank->lpfD2 = 0;
-
-		bank->left_gain = 
-		bank->right_gain =
-		bank->left_gain_end =
-		bank->right_gain_end =
-		bank->eff1_gain =
-		bank->eff2_gain =
-		bank->eff3_gain =
-		bank->eff1_gain_end =
-		bank->eff2_gain_end =
-		bank->eff3_gain_end = 0;
-
-		if (!stereo) {
-			if (!spdif) {
-				bank->left_gain = 
-				bank->right_gain =
-				bank->left_gain_end =
-				bank->right_gain_end = default_gain;
-			} else {
-				bank->eff2_gain =
-				bank->eff2_gain_end =
-				bank->eff3_gain =
-				bank->eff3_gain_end = default_gain;
-			}
-		} else {
-			if (!spdif) {
-				if ((voice->number & 1) == 0) {
-					bank->left_gain =
-					bank->left_gain_end = default_gain;
-				} else {
-					bank->format |= cpu_to_le32(1);
-					bank->right_gain =
-					bank->right_gain_end = default_gain;
-				}
-			} else {
-				if ((voice->number & 1) == 0) {
-					bank->eff2_gain =
-					bank->eff2_gain_end = default_gain;
-				} else {
-					bank->format |= cpu_to_le32(1);
-					bank->eff3_gain =
-					bank->eff3_gain_end = default_gain;
-				}
-			}
-		}
-	}
-}
-
-/*
- * XXX Capture channel allocation is entirely fake at the moment.
- * We use only one channel and mark it busy as required.
- */
-static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank)
-{
-	struct ymf_capture *cap;
-	int cbank;
-
-	cbank = 1;		/* Only ADC slot is used for now. */
-	cap = &unit->capture[cbank];
-	if (cap->use)
-		return -EBUSY;
-	cap->use = 1;
-	*pbank = cbank;
-	return 0;
-}
-
-static int ymf_playback_prepare(struct ymf_state *state)
-{
-	struct ymf_pcm *ypcm = &state->wpcm;
-	int err, nvoice;
-
-	if ((err = ymfpci_pcm_voice_alloc(ypcm, state->format.voices)) < 0) {
-		/* Somebody started 32 mpg123's in parallel? */
-		printk(KERN_INFO "ymfpci%d: cannot allocate voice\n",
-		    state->unit->dev_audio);
-		return err;
-	}
-
-	for (nvoice = 0; nvoice < state->format.voices; nvoice++) {
-		ymf_pcm_init_voice(ypcm->voices[nvoice],
-		    state->format.voices == 2, state->format.rate,
-		    ymf_pcm_format_width(state->format.format) == 16,
-		    ypcm->dmabuf.dma_addr, ypcm->dmabuf.dmasize,
-		    ypcm->spdif);
-	}
-	return 0;
-}
-
-static int ymf_capture_prepare(struct ymf_state *state)
-{
-	ymfpci_t *unit = state->unit;
-	struct ymf_pcm *ypcm = &state->rpcm;
-	ymfpci_capture_bank_t * bank;
-	/* XXX This is confusing, gotta rename one of them banks... */
-	int nbank;		/* flip-flop bank */
-	int cbank;		/* input [super-]bank */
-	struct ymf_capture *cap;
-	u32 rate, format;
-
-	if (ypcm->capture_bank_number == -1) {
-		if (ymf_capture_alloc(unit, &cbank) != 0)
-			return -EBUSY;
-
-		ypcm->capture_bank_number = cbank;
-
-		cap = &unit->capture[cbank];
-		cap->bank = unit->bank_capture[cbank][0];
-		cap->ypcm = ypcm;
-		ymfpci_hw_start(unit);
-	}
-
-	// ypcm->frag_size = snd_pcm_lib_transfer_fragment(substream);
-	// frag_size is replaced with nonfragged byte-aligned rolling buffer
-	rate = ((48000 * 4096) / state->format.rate) - 1;
-	format = 0;
-	if (state->format.voices == 2)
-		format |= 2;
-	if (ymf_pcm_format_width(state->format.format) == 8)
-		format |= 1;
-	switch (ypcm->capture_bank_number) {
-	case 0:
-		ymfpci_writel(unit, YDSXGR_RECFORMAT, format);
-		ymfpci_writel(unit, YDSXGR_RECSLOTSR, rate);
-		break;
-	case 1:
-		ymfpci_writel(unit, YDSXGR_ADCFORMAT, format);
-		ymfpci_writel(unit, YDSXGR_ADCSLOTSR, rate);
-		break;
-	}
-	for (nbank = 0; nbank < 2; nbank++) {
-		bank = unit->bank_capture[ypcm->capture_bank_number][nbank];
-		bank->base = cpu_to_le32(ypcm->dmabuf.dma_addr);
-		// bank->loop_end = ypcm->dmabuf.dmasize >> state->format.shift;
-		bank->loop_end = cpu_to_le32(ypcm->dmabuf.dmasize);
-		bank->start = 0;
-		bank->num_of_loops = 0;
-	}
-#if 0 /* s/pdif */
-	if (state->digital.dig_valid)
-		/*state->digital.type == SND_PCM_DIG_AES_IEC958*/
-		ymfpci_writew(codec, YDSXGR_SPDIFOUTSTATUS,
-		    state->digital.dig_status[0] | (state->digital.dig_status[1] << 8));
-#endif
-	return 0;
-}
-
-static irqreturn_t ymf_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	ymfpci_t *codec = dev_id;
-	u32 status, nvoice, mode;
-	struct ymf_voice *voice;
-	struct ymf_capture *cap;
-
-	status = ymfpci_readl(codec, YDSXGR_STATUS);
-	if (status & 0x80000000) {
-		codec->active_bank = ymfpci_readl(codec, YDSXGR_CTRLSELECT) & 1;
-		spin_lock(&codec->voice_lock);
-		for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) {
-			voice = &codec->voices[nvoice];
-			if (voice->use)
-				ymf_pcm_interrupt(codec, voice);
-		}
-		for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) {
-			cap = &codec->capture[nvoice];
-			if (cap->use)
-				ymf_cap_interrupt(codec, cap);
-		}
-		spin_unlock(&codec->voice_lock);
-		spin_lock(&codec->reg_lock);
-		ymfpci_writel(codec, YDSXGR_STATUS, 0x80000000);
-		mode = ymfpci_readl(codec, YDSXGR_MODE) | 2;
-		ymfpci_writel(codec, YDSXGR_MODE, mode);
-		spin_unlock(&codec->reg_lock);
-	}
-
-	status = ymfpci_readl(codec, YDSXGR_INTFLAG);
-	if (status & 1) {
-		/* timer handler */
-		ymfpci_writel(codec, YDSXGR_INTFLAG, ~0);
-	}
-	return IRQ_HANDLED;
-}
-
-static void ymf_pcm_free_substream(struct ymf_pcm *ypcm)
-{
-	unsigned long flags;
-	struct ymf_unit *unit;
-
-	unit = ypcm->state->unit;
-
-	if (ypcm->type == PLAYBACK_VOICE) {
-		spin_lock_irqsave(&unit->voice_lock, flags);
-		if (ypcm->voices[1])
-			ymfpci_voice_free(unit, ypcm->voices[1]);
-		if (ypcm->voices[0])
-			ymfpci_voice_free(unit, ypcm->voices[0]);
-		spin_unlock_irqrestore(&unit->voice_lock, flags);
-	} else {
-		if (ypcm->capture_bank_number != -1) {
-			unit->capture[ypcm->capture_bank_number].use = 0;
-			ypcm->capture_bank_number = -1;
-			ymfpci_hw_stop(unit);
-		}
-	}
-}
-
-static struct ymf_state *ymf_state_alloc(ymfpci_t *unit)
-{
-	struct ymf_pcm *ypcm;
-	struct ymf_state *state;
-
-	if ((state = kmalloc(sizeof(struct ymf_state), GFP_KERNEL)) == NULL) {
-		goto out0;
-	}
-	memset(state, 0, sizeof(struct ymf_state));
-
-	ypcm = &state->wpcm;
-	ypcm->state = state;
-	ypcm->type = PLAYBACK_VOICE;
-	ypcm->capture_bank_number = -1;
-	init_waitqueue_head(&ypcm->dmabuf.wait);
-
-	ypcm = &state->rpcm;
-	ypcm->state = state;
-	ypcm->type = CAPTURE_AC97;
-	ypcm->capture_bank_number = -1;
-	init_waitqueue_head(&ypcm->dmabuf.wait);
-
-	state->unit = unit;
-
-	state->format.format = AFMT_U8;
-	state->format.rate = 8000;
-	state->format.voices = 1;
-	ymf_pcm_update_shift(&state->format);
-
-	return state;
-
-out0:
-	return NULL;
-}
-
-/* AES/IEC958 channel status bits */
-#define SND_PCM_AES0_PROFESSIONAL	(1<<0)	/* 0 = consumer, 1 = professional */
-#define SND_PCM_AES0_NONAUDIO		(1<<1)	/* 0 = audio, 1 = non-audio */
-#define SND_PCM_AES0_PRO_EMPHASIS	(7<<2)	/* mask - emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_NOTID	(0<<2)	/* emphasis not indicated */
-#define SND_PCM_AES0_PRO_EMPHASIS_NONE	(1<<2)	/* none emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_5015	(3<<2)	/* 50/15us emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_CCITT	(7<<2)	/* CCITT J.17 emphasis */
-#define SND_PCM_AES0_PRO_FREQ_UNLOCKED	(1<<5)	/* source sample frequency: 0 = locked, 1 = unlocked */
-#define SND_PCM_AES0_PRO_FS		(3<<6)	/* mask - sample frequency */
-#define SND_PCM_AES0_PRO_FS_NOTID	(0<<6)	/* fs not indicated */
-#define SND_PCM_AES0_PRO_FS_44100	(1<<6)	/* 44.1kHz */
-#define SND_PCM_AES0_PRO_FS_48000	(2<<6)	/* 48kHz */
-#define SND_PCM_AES0_PRO_FS_32000	(3<<6)	/* 32kHz */
-#define SND_PCM_AES0_CON_NOT_COPYRIGHT	(1<<2)	/* 0 = copyright, 1 = not copyright */
-#define SND_PCM_AES0_CON_EMPHASIS	(7<<3)	/* mask - emphasis */
-#define SND_PCM_AES0_CON_EMPHASIS_NONE	(0<<3)	/* none emphasis */
-#define SND_PCM_AES0_CON_EMPHASIS_5015	(1<<3)	/* 50/15us emphasis */
-#define SND_PCM_AES0_CON_MODE		(3<<6)	/* mask - mode */
-#define SND_PCM_AES1_PRO_MODE		(15<<0)	/* mask - channel mode */
-#define SND_PCM_AES1_PRO_MODE_NOTID	(0<<0)	/* not indicated */
-#define SND_PCM_AES1_PRO_MODE_STEREOPHONIC (2<<0) /* stereophonic - ch A is left */
-#define SND_PCM_AES1_PRO_MODE_SINGLE	(4<<0)	/* single channel */
-#define SND_PCM_AES1_PRO_MODE_TWO	(8<<0)	/* two channels */
-#define SND_PCM_AES1_PRO_MODE_PRIMARY	(12<<0)	/* primary/secondary */
-#define SND_PCM_AES1_PRO_MODE_BYTE3	(15<<0)	/* vector to byte 3 */
-#define SND_PCM_AES1_PRO_USERBITS	(15<<4)	/* mask - user bits */
-#define SND_PCM_AES1_PRO_USERBITS_NOTID	(0<<4)	/* not indicated */
-#define SND_PCM_AES1_PRO_USERBITS_192	(8<<4)	/* 192-bit structure */
-#define SND_PCM_AES1_PRO_USERBITS_UDEF	(12<<4)	/* user defined application */
-#define SND_PCM_AES1_CON_CATEGORY	0x7f
-#define SND_PCM_AES1_CON_GENERAL	0x00
-#define SND_PCM_AES1_CON_EXPERIMENTAL	0x40
-#define SND_PCM_AES1_CON_SOLIDMEM_MASK	0x0f
-#define SND_PCM_AES1_CON_SOLIDMEM_ID	0x08
-#define SND_PCM_AES1_CON_BROADCAST1_MASK 0x07
-#define SND_PCM_AES1_CON_BROADCAST1_ID	0x04
-#define SND_PCM_AES1_CON_DIGDIGCONV_MASK 0x07
-#define SND_PCM_AES1_CON_DIGDIGCONV_ID	0x02
-#define SND_PCM_AES1_CON_ADC_COPYRIGHT_MASK 0x1f
-#define SND_PCM_AES1_CON_ADC_COPYRIGHT_ID 0x06
-#define SND_PCM_AES1_CON_ADC_MASK	0x1f
-#define SND_PCM_AES1_CON_ADC_ID		0x16
-#define SND_PCM_AES1_CON_BROADCAST2_MASK 0x0f
-#define SND_PCM_AES1_CON_BROADCAST2_ID	0x0e
-#define SND_PCM_AES1_CON_LASEROPT_MASK	0x07
-#define SND_PCM_AES1_CON_LASEROPT_ID	0x01
-#define SND_PCM_AES1_CON_MUSICAL_MASK	0x07
-#define SND_PCM_AES1_CON_MUSICAL_ID	0x05
-#define SND_PCM_AES1_CON_MAGNETIC_MASK	0x07
-#define SND_PCM_AES1_CON_MAGNETIC_ID	0x03
-#define SND_PCM_AES1_CON_IEC908_CD	(SND_PCM_AES1_CON_LASEROPT_ID|0x00)
-#define SND_PCM_AES1_CON_NON_IEC908_CD	(SND_PCM_AES1_CON_LASEROPT_ID|0x08)
-#define SND_PCM_AES1_CON_PCM_CODER	(SND_PCM_AES1_CON_DIGDIGCONV_ID|0x00)
-#define SND_PCM_AES1_CON_SAMPLER	(SND_PCM_AES1_CON_DIGDIGCONV_ID|0x20)
-#define SND_PCM_AES1_CON_MIXER		(SND_PCM_AES1_CON_DIGDIGCONV_ID|0x10)
-#define SND_PCM_AES1_CON_RATE_CONVERTER	(SND_PCM_AES1_CON_DIGDIGCONV_ID|0x18)
-#define SND_PCM_AES1_CON_SYNTHESIZER	(SND_PCM_AES1_CON_MUSICAL_ID|0x00)
-#define SND_PCM_AES1_CON_MICROPHONE	(SND_PCM_AES1_CON_MUSICAL_ID|0x08)
-#define SND_PCM_AES1_CON_DAT		(SND_PCM_AES1_CON_MAGNETIC_ID|0x00)
-#define SND_PCM_AES1_CON_VCR		(SND_PCM_AES1_CON_MAGNETIC_ID|0x08)
-#define SND_PCM_AES1_CON_ORIGINAL	(1<<7)	/* this bits depends on the category code */
-#define SND_PCM_AES2_PRO_SBITS		(7<<0)	/* mask - sample bits */
-#define SND_PCM_AES2_PRO_SBITS_20	(2<<0)	/* 20-bit - coordination */
-#define SND_PCM_AES2_PRO_SBITS_24	(4<<0)	/* 24-bit - main audio */
-#define SND_PCM_AES2_PRO_SBITS_UDEF	(6<<0)	/* user defined application */
-#define SND_PCM_AES2_PRO_WORDLEN	(7<<3)	/* mask - source word length */
-#define SND_PCM_AES2_PRO_WORDLEN_NOTID	(0<<3)	/* not indicated */
-#define SND_PCM_AES2_PRO_WORDLEN_22_18	(2<<3)	/* 22-bit or 18-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_23_19	(4<<3)	/* 23-bit or 19-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_24_20	(5<<3)	/* 24-bit or 20-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_20_16	(6<<3)	/* 20-bit or 16-bit */
-#define SND_PCM_AES2_CON_SOURCE		(15<<0)	/* mask - source number */
-#define SND_PCM_AES2_CON_SOURCE_UNSPEC	(0<<0)	/* unspecified */
-#define SND_PCM_AES2_CON_CHANNEL	(15<<4)	/* mask - channel number */
-#define SND_PCM_AES2_CON_CHANNEL_UNSPEC	(0<<4)	/* unspecified */
-#define SND_PCM_AES3_CON_FS		(15<<0)	/* mask - sample frequency */
-#define SND_PCM_AES3_CON_FS_44100	(0<<0)	/* 44.1kHz */
-#define SND_PCM_AES3_CON_FS_48000	(2<<0)	/* 48kHz */
-#define SND_PCM_AES3_CON_FS_32000	(3<<0)	/* 32kHz */
-#define SND_PCM_AES3_CON_CLOCK		(3<<4)	/* mask - clock accuracy */
-#define SND_PCM_AES3_CON_CLOCK_1000PPM	(0<<4)	/* 1000 ppm */
-#define SND_PCM_AES3_CON_CLOCK_50PPM	(1<<4)	/* 50 ppm */
-#define SND_PCM_AES3_CON_CLOCK_VARIABLE	(2<<4)	/* variable pitch */
-
-/*
- * User interface
- */
-
-/*
- * in this loop, dmabuf.count signifies the amount of data that is
- * waiting to be copied to the user's buffer.  it is filled by the dma
- * machine and drained by this loop.
- */
-static ssize_t
-ymf_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct ymf_state *state = (struct ymf_state *)file->private_data;
-	struct ymf_dmabuf *dmabuf = &state->rpcm.dmabuf;
-	struct ymf_unit *unit = state->unit;
-	DECLARE_WAITQUEUE(waita, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned int swptr;
-	int cnt;			/* This many to go in this revolution */
-
-	if (dmabuf->mapped)
-		return -ENXIO;
-	if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-		return ret;
-	ret = 0;
-
-	add_wait_queue(&dmabuf->wait, &waita);
-	set_current_state(TASK_INTERRUPTIBLE);
-	while (count > 0) {
-		spin_lock_irqsave(&unit->reg_lock, flags);
-		if (unit->suspended) {
-			spin_unlock_irqrestore(&unit->reg_lock, flags);
-			schedule();
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (signal_pending(current)) {
-				if (!ret) ret = -EAGAIN;
-				break;
-			}
-			continue;
-		}
-		swptr = dmabuf->swptr;
-		cnt = dmabuf->dmasize - swptr;
-		if (dmabuf->count < cnt)
-			cnt = dmabuf->count;
-		spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			unsigned long tmo;
-			/* buffer is empty, start the dma machine and wait for data to be
-			   recorded */
-			spin_lock_irqsave(&state->unit->reg_lock, flags);
-			if (!state->rpcm.running) {
-				ymf_capture_trigger(state->unit, &state->rpcm, 1);
-			}
-			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret) ret = -EAGAIN;
-				break;
-			}
-			/* This isnt strictly right for the 810  but it'll do */
-			tmo = (dmabuf->dmasize * HZ) / (state->format.rate * 2);
-			tmo >>= state->format.shift;
-			/* There are two situations when sleep_on_timeout returns, one is when
-			   the interrupt is serviced correctly and the process is waked up by
-			   ISR ON TIME. Another is when timeout is expired, which means that
-			   either interrupt is NOT serviced correctly (pending interrupt) or it
-			   is TOO LATE for the process to be scheduled to run (scheduler latency)
-			   which results in a (potential) buffer overrun. And worse, there is
-			   NOTHING we can do to prevent it. */
-			tmo = schedule_timeout(tmo);
-			spin_lock_irqsave(&state->unit->reg_lock, flags);
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (tmo == 0 && dmabuf->count == 0) {
-				printk(KERN_ERR "ymfpci%d: recording schedule timeout, "
-				    "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-				    state->unit->dev_audio,
-				    dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
-				    dmabuf->hwptr, dmabuf->swptr);
-			}
-			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-			if (signal_pending(current)) {
-				if (!ret) ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-
-		if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
-			if (!ret) ret = -EFAULT;
-			break;
-		}
-
-		swptr = (swptr + cnt) % dmabuf->dmasize;
-
-		spin_lock_irqsave(&unit->reg_lock, flags);
-		if (unit->suspended) {
-			spin_unlock_irqrestore(&unit->reg_lock, flags);
-			continue;
-		}
-
-		dmabuf->swptr = swptr;
-		dmabuf->count -= cnt;
-		// spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		// spin_lock_irqsave(&unit->reg_lock, flags);
-		if (!state->rpcm.running) {
-			ymf_capture_trigger(unit, &state->rpcm, 1);
-		}
-		spin_unlock_irqrestore(&unit->reg_lock, flags);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&dmabuf->wait, &waita);
-
-	return ret;
-}
-
-static ssize_t
-ymf_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct ymf_state *state = (struct ymf_state *)file->private_data;
-	struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
-	struct ymf_unit *unit = state->unit;
-	DECLARE_WAITQUEUE(waita, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned int swptr;
-	int cnt;			/* This many to go in this revolution */
-	int redzone;
-	int delay;
-
-	YMFDBGW("ymf_write: count %d\n", count);
-
-	if (dmabuf->mapped)
-		return -ENXIO;
-	if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-		return ret;
-	ret = 0;
-
-	/*
-	 * Alan's cs46xx works without a red zone - marvel of ingenuity.
-	 * We are not so brilliant... Red zone does two things:
-	 *  1. allows for safe start after a pause as we have no way
-	 *     to know what the actual, relentlessly advancing, hwptr is.
-	 *  2. makes computations in ymf_pcm_interrupt simpler.
-	 */
-	redzone = ymf_calc_lend(state->format.rate) << state->format.shift;
-	redzone *= 3;	/* 2 redzone + 1 possible uncertainty reserve. */
-
-	add_wait_queue(&dmabuf->wait, &waita);
-	set_current_state(TASK_INTERRUPTIBLE);
-	while (count > 0) {
-		spin_lock_irqsave(&unit->reg_lock, flags);
-		if (unit->suspended) {
-			spin_unlock_irqrestore(&unit->reg_lock, flags);
-			schedule();
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (signal_pending(current)) {
-				if (!ret) ret = -EAGAIN;
-				break;
-			}
-			continue;
-		}
-		if (dmabuf->count < 0) {
-			printk(KERN_ERR
-			   "ymf_write: count %d, was legal in cs46xx\n",
-			    dmabuf->count);
-			dmabuf->count = 0;
-		}
-		if (dmabuf->count == 0) {
-			swptr = dmabuf->hwptr;
-			if (state->wpcm.running) {
-				/*
-				 * Add uncertainty reserve.
-				 */
-				cnt = ymf_calc_lend(state->format.rate);
-				cnt <<= state->format.shift;
-				if ((swptr += cnt) >= dmabuf->dmasize) {
-					swptr -= dmabuf->dmasize;
-				}
-			}
-			dmabuf->swptr = swptr;
-		} else {
-			/*
-			 * XXX This is not right if dmabuf->count is small -
-			 * about 2*x frame size or less. We cannot count on
-			 * on appending and not causing an artefact.
-			 * Should use a variation of the count==0 case above.
-			 */
-			swptr = dmabuf->swptr;
-		}
-		cnt = dmabuf->dmasize - swptr;
-		if (dmabuf->count + cnt > dmabuf->dmasize - redzone)
-			cnt = (dmabuf->dmasize - redzone) - dmabuf->count;
-		spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			YMFDBGW("ymf_write: full, count %d swptr %d\n",
-			   dmabuf->count, dmabuf->swptr);
-			/*
-			 * buffer is full, start the dma machine and
-			 * wait for data to be played
-			 */
-			spin_lock_irqsave(&unit->reg_lock, flags);
-			if (!state->wpcm.running) {
-				ymf_playback_trigger(unit, &state->wpcm, 1);
-			}
-			spin_unlock_irqrestore(&unit->reg_lock, flags);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret) ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (signal_pending(current)) {
-				if (!ret) ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
-			if (!ret) ret = -EFAULT;
-			break;
-		}
-
-		if ((swptr += cnt) >= dmabuf->dmasize) {
-			swptr -= dmabuf->dmasize;
-		}
-
-		spin_lock_irqsave(&unit->reg_lock, flags);
-		if (unit->suspended) {
-			spin_unlock_irqrestore(&unit->reg_lock, flags);
-			continue;
-		}
-		dmabuf->swptr = swptr;
-		dmabuf->count += cnt;
-
-		/*
-		 * Start here is a bad idea - may cause startup click
-		 * in /bin/play when dmabuf is not full yet.
-		 * However, some broken applications do not make
-		 * any use of SNDCTL_DSP_SYNC (Doom is the worst).
-		 * One frame is about 5.3ms, Doom write size is 46ms.
-		 */
-		delay = state->format.rate / 20;	/* 50ms */
-		delay <<= state->format.shift;
-		if (dmabuf->count >= delay && !state->wpcm.running) {
-			ymf_playback_trigger(unit, &state->wpcm, 1);
-		}
-
-		spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-	}
-
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&dmabuf->wait, &waita);
-
-	YMFDBGW("ymf_write: ret %d dmabuf.count %d\n", ret, dmabuf->count);
-	return ret;
-}
-
-static unsigned int ymf_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct ymf_state *state = (struct ymf_state *)file->private_data;
-	struct ymf_dmabuf *dmabuf;
-	int redzone;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	if (file->f_mode & FMODE_WRITE)
-		poll_wait(file, &state->wpcm.dmabuf.wait, wait);
-	if (file->f_mode & FMODE_READ)
-		poll_wait(file, &state->rpcm.dmabuf.wait, wait);
-
-	spin_lock_irqsave(&state->unit->reg_lock, flags);
-	if (file->f_mode & FMODE_READ) {
-		dmabuf = &state->rpcm.dmabuf;
-		if (dmabuf->count >= (signed)dmabuf->fragsize)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		redzone = ymf_calc_lend(state->format.rate);
-		redzone <<= state->format.shift;
-		redzone *= 3;
-
-		dmabuf = &state->wpcm.dmabuf;
-		if (dmabuf->mapped) {
-			if (dmabuf->count >= (signed)dmabuf->fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			/*
-			 * Don't select unless a full fragment is available.
-			 * Otherwise artsd does GETOSPACE, sees 0, and loops.
-			 */
-			if (dmabuf->count + redzone + dmabuf->fragsize
-			     <= dmabuf->dmasize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-
-	return mask;
-}
-
-static int ymf_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct ymf_state *state = (struct ymf_state *)file->private_data;
-	struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
-	int ret;
-	unsigned long size;
-
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf(state, 0)) != 0)
-			return ret;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf(state, 1)) != 0)
-			return ret;
-	} else 
-		return -EINVAL;
-
-	if (vma->vm_pgoff != 0)
-		return -EINVAL;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << dmabuf->buforder))
-		return -EINVAL;
-	if (remap_pfn_range(vma, vma->vm_start,
-			     virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT,
-			     size, vma->vm_page_prot))
-		return -EAGAIN;
-	dmabuf->mapped = 1;
-
-/* P3 */ printk(KERN_INFO "ymfpci: using memory mapped sound, untested!\n");
-	return 0;
-}
-
-static int ymf_ioctl(struct inode *inode, struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
-	struct ymf_state *state = (struct ymf_state *)file->private_data;
-	struct ymf_dmabuf *dmabuf;
-	unsigned long flags;
-	audio_buf_info abinfo;
-	count_info cinfo;
-	int redzone;
-	int val;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	switch (cmd) {
-	case OSS_GETVERSION:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETVER) arg 0x%lx\n", cmd, arg);
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_RESET:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(RESET)\n", cmd);
-		if (file->f_mode & FMODE_WRITE) {
-			ymf_wait_dac(state);
-			dmabuf = &state->wpcm.dmabuf;
-			spin_lock_irqsave(&state->unit->reg_lock, flags);
-			dmabuf->ready = 0;
-			dmabuf->swptr = dmabuf->hwptr;
-			dmabuf->count = dmabuf->total_bytes = 0;
-			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		}
-		if (file->f_mode & FMODE_READ) {
-			ymf_stop_adc(state);
-			dmabuf = &state->rpcm.dmabuf;
-			spin_lock_irqsave(&state->unit->reg_lock, flags);
-			dmabuf->ready = 0;
-			dmabuf->swptr = dmabuf->hwptr;
-			dmabuf->count = dmabuf->total_bytes = 0;
-			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		}
-		return 0;
-
-	case SNDCTL_DSP_SYNC:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(SYNC)\n", cmd);
-		if (file->f_mode & FMODE_WRITE) {
-			dmabuf = &state->wpcm.dmabuf;
-			if (file->f_flags & O_NONBLOCK) {
-				spin_lock_irqsave(&state->unit->reg_lock, flags);
-				if (dmabuf->count != 0 && !state->wpcm.running) {
-					ymf_start_dac(state);
-				}
-				spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-			} else {
-				ymf_wait_dac(state);
-			}
-		}
-		/* XXX What does this do for reading? dmabuf->count=0; ? */
-		return 0;
-
-	case SNDCTL_DSP_SPEED: /* set smaple rate */
-		if (get_user(val, p))
-			return -EFAULT;
-		YMFDBGX("ymf_ioctl: cmd 0x%x(SPEED) sp %d\n", cmd, val);
-		if (val >= 8000 && val <= 48000) {
-			if (file->f_mode & FMODE_WRITE) {
-				ymf_wait_dac(state);
-				dmabuf = &state->wpcm.dmabuf;
-				spin_lock_irqsave(&state->unit->reg_lock, flags);
-				dmabuf->ready = 0;
-				state->format.rate = val;
-				ymf_pcm_update_shift(&state->format);
-				spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-			}
-			if (file->f_mode & FMODE_READ) {
-				ymf_stop_adc(state);
-				dmabuf = &state->rpcm.dmabuf;
-				spin_lock_irqsave(&state->unit->reg_lock, flags);
-				dmabuf->ready = 0;
-				state->format.rate = val;
-				ymf_pcm_update_shift(&state->format);
-				spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-			}
-		}
-		return put_user(state->format.rate, p);
-
-	/*
-	 * OSS manual does not mention SNDCTL_DSP_STEREO at all.
-	 * All channels are mono and if you want stereo, you
-	 * play into two channels with SNDCTL_DSP_CHANNELS.
-	 * However, mpg123 calls it. I wonder, why Michael Hipp used it.
-	 */
-	case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-		if (get_user(val, p))
-			return -EFAULT;
-		YMFDBGX("ymf_ioctl: cmd 0x%x(STEREO) st %d\n", cmd, val);
-		if (file->f_mode & FMODE_WRITE) {
-			ymf_wait_dac(state); 
-			dmabuf = &state->wpcm.dmabuf;
-			spin_lock_irqsave(&state->unit->reg_lock, flags);
-			dmabuf->ready = 0;
-			state->format.voices = val ? 2 : 1;
-			ymf_pcm_update_shift(&state->format);
-			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		}
-		if (file->f_mode & FMODE_READ) {
-			ymf_stop_adc(state);
-			dmabuf = &state->rpcm.dmabuf;
-			spin_lock_irqsave(&state->unit->reg_lock, flags);
-			dmabuf->ready = 0;
-			state->format.voices = val ? 2 : 1;
-			ymf_pcm_update_shift(&state->format);
-			spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETBLK)\n", cmd);
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf(state, 0)))
-				return val;
-			val = state->wpcm.dmabuf.fragsize;
-			YMFDBGX("ymf_ioctl: GETBLK w %d\n", val);
-			return put_user(val, p);
-		}
-		if (file->f_mode & FMODE_READ) {
-			if ((val = prog_dmabuf(state, 1)))
-				return val;
-			val = state->rpcm.dmabuf.fragsize;
-			YMFDBGX("ymf_ioctl: GETBLK r %d\n", val);
-			return put_user(val, p);
-		}
-		return -EINVAL;
-
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETFMTS)\n", cmd);
-		return put_user(AFMT_S16_LE|AFMT_U8, p);
-
-	case SNDCTL_DSP_SETFMT: /* Select sample format */
-		if (get_user(val, p))
-			return -EFAULT;
-		YMFDBGX("ymf_ioctl: cmd 0x%x(SETFMT) fmt %d\n", cmd, val);
-		if (val == AFMT_S16_LE || val == AFMT_U8) {
-			if (file->f_mode & FMODE_WRITE) {
-				ymf_wait_dac(state);
-				dmabuf = &state->wpcm.dmabuf;
-				spin_lock_irqsave(&state->unit->reg_lock, flags);
-				dmabuf->ready = 0;
-				state->format.format = val;
-				ymf_pcm_update_shift(&state->format);
-				spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-			}
-			if (file->f_mode & FMODE_READ) {
-				ymf_stop_adc(state);
-				dmabuf = &state->rpcm.dmabuf;
-				spin_lock_irqsave(&state->unit->reg_lock, flags);
-				dmabuf->ready = 0;
-				state->format.format = val;
-				ymf_pcm_update_shift(&state->format);
-				spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-			}
-		}
-		return put_user(state->format.format, p);
-
-	case SNDCTL_DSP_CHANNELS:
-		if (get_user(val, p))
-			return -EFAULT;
-		YMFDBGX("ymf_ioctl: cmd 0x%x(CHAN) ch %d\n", cmd, val);
-		if (val != 0) {
-			if (file->f_mode & FMODE_WRITE) {
-				ymf_wait_dac(state);
-				if (val == 1 || val == 2) {
-					spin_lock_irqsave(&state->unit->reg_lock, flags);
-					dmabuf = &state->wpcm.dmabuf;
-					dmabuf->ready = 0;
-					state->format.voices = val;
-					ymf_pcm_update_shift(&state->format);
-					spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-				}
-			}
-			if (file->f_mode & FMODE_READ) {
-				ymf_stop_adc(state);
-				if (val == 1 || val == 2) {
-					spin_lock_irqsave(&state->unit->reg_lock, flags);
-					dmabuf = &state->rpcm.dmabuf;
-					dmabuf->ready = 0;
-					state->format.voices = val;
-					ymf_pcm_update_shift(&state->format);
-					spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-				}
-			}
-		}
-		return put_user(state->format.voices, p);
-
-	case SNDCTL_DSP_POST:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(POST)\n", cmd);
-		/*
-		 * Quoting OSS PG:
-		 *    The ioctl SNDCTL_DSP_POST is a lightweight version of
-		 *    SNDCTL_DSP_SYNC. It just tells to the driver that there
-		 *    is likely to be a pause in the output. This makes it
-		 *    possible for the device to handle the pause more
-		 *    intelligently. This ioctl doesn't block the application.
-		 *
-		 * The paragraph above is a clumsy way to say "flush ioctl".
-		 * This ioctl is used by mpg123.
-		 */
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
-		if (state->wpcm.dmabuf.count != 0 && !state->wpcm.running) {
-			ymf_start_dac(state);
-		}
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		return 0;
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(val, p))
-			return -EFAULT;
-		YMFDBGX("ymf_ioctl: cmd 0x%x(SETFRAG) fr 0x%04x:%04x(%d:%d)\n",
-		    cmd,
-		    (val >> 16) & 0xFFFF, val & 0xFFFF,
-		    (val >> 16) & 0xFFFF, val & 0xFFFF);
-		dmabuf = &state->wpcm.dmabuf;
-		dmabuf->ossfragshift = val & 0xffff;
-		dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
-		if (dmabuf->ossfragshift < 4)
-			dmabuf->ossfragshift = 4;
-		if (dmabuf->ossfragshift > 15)
-			dmabuf->ossfragshift = 15;
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETOSPACE)\n", cmd);
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		dmabuf = &state->wpcm.dmabuf;
-		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-			return val;
-		redzone = ymf_calc_lend(state->format.rate);
-		redzone <<= state->format.shift;
-		redzone *= 3;
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
-		abinfo.fragsize = dmabuf->fragsize;
-		abinfo.bytes = dmabuf->dmasize - dmabuf->count - redzone;
-		abinfo.fragstotal = dmabuf->numfrag;
-		abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETISPACE)\n", cmd);
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		dmabuf = &state->rpcm.dmabuf;
-		if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
-			return val;
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
-		abinfo.fragsize = dmabuf->fragsize;
-		abinfo.bytes = dmabuf->count;
-		abinfo.fragstotal = dmabuf->numfrag;
-		abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_NONBLOCK:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(NONBLOCK)\n", cmd);
-		file->f_flags |= O_NONBLOCK;
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETCAPS)\n", cmd);
-		/* return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
-			    p); */
-		return put_user(0, p);
-
-	case SNDCTL_DSP_GETIPTR:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETIPTR)\n", cmd);
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		dmabuf = &state->rpcm.dmabuf;
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
-		cinfo.bytes = dmabuf->total_bytes;
-		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-		cinfo.ptr = dmabuf->hwptr;
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		YMFDBGX("ymf_ioctl: GETIPTR ptr %d bytes %d\n",
-		    cinfo.ptr, cinfo.bytes);
-		return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETOPTR:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(GETOPTR)\n", cmd);
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		dmabuf = &state->wpcm.dmabuf;
-		spin_lock_irqsave(&state->unit->reg_lock, flags);
-		cinfo.bytes = dmabuf->total_bytes;
-		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-		cinfo.ptr = dmabuf->hwptr;
-		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-		YMFDBGX("ymf_ioctl: GETOPTR ptr %d bytes %d\n",
-		    cinfo.ptr, cinfo.bytes);
-		return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_SETDUPLEX:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(SETDUPLEX)\n", cmd);
-		return 0;		/* Always duplex */
-
-	case SOUND_PCM_READ_RATE:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(READ_RATE)\n", cmd);
-		return put_user(state->format.rate, p);
-
-	case SOUND_PCM_READ_CHANNELS:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(READ_CH)\n", cmd);
-		return put_user(state->format.voices, p);
-
-	case SOUND_PCM_READ_BITS:
-		YMFDBGX("ymf_ioctl: cmd 0x%x(READ_BITS)\n", cmd);
-		return put_user(AFMT_S16_LE, p);
-
-	case SNDCTL_DSP_MAPINBUF:
-	case SNDCTL_DSP_MAPOUTBUF:
-	case SNDCTL_DSP_SETSYNCRO:
-	case SOUND_PCM_WRITE_FILTER:
-	case SOUND_PCM_READ_FILTER:
-		YMFDBGX("ymf_ioctl: cmd 0x%x unsupported\n", cmd);
-		return -ENOTTY;
-
-	default:
-		/*
-		 * Some programs mix up audio devices and ioctls
-		 * or perhaps they expect "universal" ioctls,
-		 * for instance we get SNDCTL_TMR_CONTINUE here.
-		 * (mpg123 -g 100 ends here too - to be fixed.)
-		 */
-		YMFDBGX("ymf_ioctl: cmd 0x%x unknown\n", cmd);
-		break;
-	}
-	return -ENOTTY;
-}
-
-/*
- * open(2)
- * We use upper part of the minor to distinguish between soundcards.
- * Channels are opened with a clone open.
- */
-static int ymf_open(struct inode *inode, struct file *file)
-{
-	struct list_head *list;
-	ymfpci_t *unit = NULL;
-	int minor;
-	struct ymf_state *state;
-	int err;
-
-	minor = iminor(inode);
-	if ((minor & 0x0F) == 3) {	/* /dev/dspN */
-		;
-	} else {
-		return -ENXIO;
-	}
-
-	unit = NULL;	/* gcc warns */
-	spin_lock(&ymf_devs_lock);
-	list_for_each(list, &ymf_devs) {
-		unit = list_entry(list, ymfpci_t, ymf_devs);
-		if (((unit->dev_audio ^ minor) & ~0x0F) == 0)
-			break;
-	}
-	spin_unlock(&ymf_devs_lock);
-	if (unit == NULL)
-		return -ENODEV;
-
-	mutex_lock(&unit->open_mutex);
-
-	if ((state = ymf_state_alloc(unit)) == NULL) {
-		mutex_unlock(&unit->open_mutex);
-		return -ENOMEM;
-	}
-	list_add_tail(&state->chain, &unit->states);
-
-	file->private_data = state;
-
-	/*
-	 * ymf_read and ymf_write that we borrowed from cs46xx
-	 * allocate buffers with prog_dmabuf(). We call prog_dmabuf
-	 * here so that in case of DMA memory exhaustion open
-	 * fails rather than write.
-	 *
-	 * XXX prog_dmabuf allocates voice. Should allocate explicitly, above.
-	 */
-	if (file->f_mode & FMODE_WRITE) {
-		if (!state->wpcm.dmabuf.ready) {
-			if ((err = prog_dmabuf(state, 0)) != 0) {
-				goto out_nodma;
-			}
-		}
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!state->rpcm.dmabuf.ready) {
-			if ((err = prog_dmabuf(state, 1)) != 0) {
-				goto out_nodma;
-			}
-		}
-	}
-
-#if 0 /* test if interrupts work */
-	ymfpci_writew(unit, YDSXGR_TIMERCOUNT, 0xfffe);	/* ~ 680ms */
-	ymfpci_writeb(unit, YDSXGR_TIMERCTRL,
-	    (YDSXGR_TIMERCTRL_TEN|YDSXGR_TIMERCTRL_TIEN));
-#endif
-	mutex_unlock(&unit->open_mutex);
-
-	return nonseekable_open(inode, file);
-
-out_nodma:
-	/*
-	 * XXX Broken custom: "goto out_xxx" in other place is
-	 * a nestable exception, but here it is not nestable due to semaphore.
-	 * XXX Doubtful technique of self-describing objects....
-	 */
-	dealloc_dmabuf(unit, &state->wpcm.dmabuf);
-	dealloc_dmabuf(unit, &state->rpcm.dmabuf);
-	ymf_pcm_free_substream(&state->wpcm);
-	ymf_pcm_free_substream(&state->rpcm);
-
-	list_del(&state->chain);
-	kfree(state);
-
-	mutex_unlock(&unit->open_mutex);
-	return err;
-}
-
-static int ymf_release(struct inode *inode, struct file *file)
-{
-	struct ymf_state *state = (struct ymf_state *)file->private_data;
-	ymfpci_t *unit = state->unit;
-
-#if 0 /* test if interrupts work */
-	ymfpci_writeb(unit, YDSXGR_TIMERCTRL, 0);
-#endif
-
-	mutex_lock(&unit->open_mutex);
-
-	/*
-	 * XXX Solve the case of O_NONBLOCK close - don't deallocate here.
-	 * Deallocate when unloading the driver and we can wait.
-	 */
-	ymf_wait_dac(state);
-	ymf_stop_adc(state);		/* fortunately, it's immediate */
-	dealloc_dmabuf(unit, &state->wpcm.dmabuf);
-	dealloc_dmabuf(unit, &state->rpcm.dmabuf);
-	ymf_pcm_free_substream(&state->wpcm);
-	ymf_pcm_free_substream(&state->rpcm);
-
-	list_del(&state->chain);
-	file->private_data = NULL;	/* Can you tell I programmed Solaris */
-	kfree(state);
-
-	mutex_unlock(&unit->open_mutex);
-
-	return 0;
-}
-
-/*
- * Mixer operations are based on cs46xx.
- */
-static int ymf_open_mixdev(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	struct list_head *list;
-	ymfpci_t *unit;
-	int i;
-
-	spin_lock(&ymf_devs_lock);
-	list_for_each(list, &ymf_devs) {
-		unit = list_entry(list, ymfpci_t, ymf_devs);
-		for (i = 0; i < NR_AC97; i++) {
-			if (unit->ac97_codec[i] != NULL &&
-			    unit->ac97_codec[i]->dev_mixer == minor) {
-				spin_unlock(&ymf_devs_lock);
-				goto match;
-			}
-		}
-	}
-	spin_unlock(&ymf_devs_lock);
-	return -ENODEV;
-
- match:
-	file->private_data = unit->ac97_codec[i];
-
-	return nonseekable_open(inode, file);
-}
-
-static int ymf_ioctl_mixdev(struct inode *inode, struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
-	struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
-
-	return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int ymf_release_mixdev(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static /*const*/ struct file_operations ymf_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= ymf_read,
-	.write		= ymf_write,
-	.poll		= ymf_poll,
-	.ioctl		= ymf_ioctl,
-	.mmap		= ymf_mmap,
-	.open		= ymf_open,
-	.release	= ymf_release,
-};
-
-static /*const*/ struct file_operations ymf_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= ymf_ioctl_mixdev,
-	.open		= ymf_open_mixdev,
-	.release	= ymf_release_mixdev,
-};
-
-/*
- */
-
-static int ymf_suspend(struct pci_dev *pcidev, pm_message_t unused)
-{
-	struct ymf_unit *unit = pci_get_drvdata(pcidev);
-	unsigned long flags;
-	struct ymf_dmabuf *dmabuf;
-	struct list_head *p;
-	struct ymf_state *state;
-	struct ac97_codec *codec;
-	int i;
-
-	spin_lock_irqsave(&unit->reg_lock, flags);
-
-	unit->suspended = 1;
-
-	for (i = 0; i < NR_AC97; i++) {
-		if ((codec = unit->ac97_codec[i]) != NULL)
-			ac97_save_state(codec);
-	}
-
-	list_for_each(p, &unit->states) {
-		state = list_entry(p, struct ymf_state, chain);
-
-		dmabuf = &state->wpcm.dmabuf;
-		dmabuf->hwptr = dmabuf->swptr = 0;
-		dmabuf->total_bytes = 0;
-		dmabuf->count = 0;
-
-		dmabuf = &state->rpcm.dmabuf;
-		dmabuf->hwptr = dmabuf->swptr = 0;
-		dmabuf->total_bytes = 0;
-		dmabuf->count = 0;
-	}
-
-	ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0);
-	ymfpci_disable_dsp(unit);
-
-	spin_unlock_irqrestore(&unit->reg_lock, flags);
-	
-	return 0;
-}
-
-static int ymf_resume(struct pci_dev *pcidev)
-{
-	struct ymf_unit *unit = pci_get_drvdata(pcidev);
-	unsigned long flags;
-	struct list_head *p;
-	struct ymf_state *state;
-	struct ac97_codec *codec;
-	int i;
-
-	ymfpci_aclink_reset(unit->pci);
-	ymfpci_codec_ready(unit, 0, 1);		/* prints diag if not ready. */
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-	/* XXX At this time the legacy registers are probably deprogrammed. */
-#endif
-
-	ymfpci_download_image(unit);
-
-	ymf_memload(unit);
-
-	spin_lock_irqsave(&unit->reg_lock, flags);
-
-	if (unit->start_count) {
-		ymfpci_writel(unit, YDSXGR_MODE, 3);
-		unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1;
-	}
-
-	for (i = 0; i < NR_AC97; i++) {
-		if ((codec = unit->ac97_codec[i]) != NULL)
-			ac97_restore_state(codec);
-	}
-
-	unit->suspended = 0;
-	list_for_each(p, &unit->states) {
-		state = list_entry(p, struct ymf_state, chain);
-		wake_up(&state->wpcm.dmabuf.wait);
-		wake_up(&state->rpcm.dmabuf.wait);
-	}
-
-	spin_unlock_irqrestore(&unit->reg_lock, flags);
-	return 0;
-}
-
-/*
- *  initialization routines
- */
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-
-static int ymfpci_setup_legacy(ymfpci_t *unit, struct pci_dev *pcidev)
-{
-	int v;
-	int mpuio = -1, oplio = -1;
-
-	switch (unit->iomidi) {
-	case 0x330:
-		mpuio = 0;
-		break;
-	case 0x300:
-		mpuio = 1;
-		break;
-	case 0x332:
-		mpuio = 2;
-		break;
-	case 0x334:
-		mpuio = 3;
-		break;
-	default: ;
-	}
-
-	switch (unit->iosynth) {
-	case 0x388:
-		oplio = 0;
-		break;
-	case 0x398:
-		oplio = 1;
-		break;
-	case 0x3a0:
-		oplio = 2;
-		break;
-	case 0x3a8:
-		oplio = 3;
-		break;
-	default: ;
-	}
-
-	if (mpuio >= 0 || oplio >= 0) {
-		/* 0x0020: 1 - 10 bits of I/O address decoded, 0 - 16 bits. */
-		v = 0x001e;
-		pci_write_config_word(pcidev, PCIR_LEGCTRL, v);
-
-		switch (pcidev->device) {
-		case PCI_DEVICE_ID_YAMAHA_724:
-		case PCI_DEVICE_ID_YAMAHA_740:
-		case PCI_DEVICE_ID_YAMAHA_724F:
-		case PCI_DEVICE_ID_YAMAHA_740C:
-			v = 0x8800;
-			if (mpuio >= 0) { v |= mpuio<<4; }
-			if (oplio >= 0) { v |= oplio; }
-			pci_write_config_word(pcidev, PCIR_ELEGCTRL, v);
-			break;
-
-		case PCI_DEVICE_ID_YAMAHA_744:
-		case PCI_DEVICE_ID_YAMAHA_754:
-			v = 0x8800;
-			pci_write_config_word(pcidev, PCIR_ELEGCTRL, v);
-			if (oplio >= 0) {
-				pci_write_config_word(pcidev, PCIR_OPLADR, unit->iosynth);
-			}
-			if (mpuio >= 0) {
-				pci_write_config_word(pcidev, PCIR_MPUADR, unit->iomidi);
-			}
-			break;
-
-		default:
-			printk(KERN_ERR "ymfpci: Unknown device ID: 0x%x\n",
-			    pcidev->device);
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-static void ymfpci_aclink_reset(struct pci_dev * pci)
-{
-	u8 cmd;
-
-	/*
-	 * In the 744, 754 only 0x01 exists, 0x02 is undefined.
-	 * It does not seem to hurt to trip both regardless of revision.
-	 */
-	pci_read_config_byte(pci, PCIR_DSXGCTRL, &cmd);
-	pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-	pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd | 0x03);
-	pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-
-	pci_write_config_word(pci, PCIR_DSXPWRCTRL1, 0);
-	pci_write_config_word(pci, PCIR_DSXPWRCTRL2, 0);
-}
-
-static void ymfpci_enable_dsp(ymfpci_t *codec)
-{
-	ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000001);
-}
-
-static void ymfpci_disable_dsp(ymfpci_t *codec)
-{
-	u32 val;
-	int timeout = 1000;
-
-	val = ymfpci_readl(codec, YDSXGR_CONFIG);
-	if (val)
-		ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000000);
-	while (timeout-- > 0) {
-		val = ymfpci_readl(codec, YDSXGR_STATUS);
-		if ((val & 0x00000002) == 0)
-			break;
-	}
-}
-
-#include "ymfpci_image.h"
-
-static void ymfpci_download_image(ymfpci_t *codec)
-{
-	int i, ver_1e;
-	u16 ctrl;
-
-	ymfpci_writel(codec, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
-	ymfpci_disable_dsp(codec);
-	ymfpci_writel(codec, YDSXGR_MODE, 0x00010000);
-	ymfpci_writel(codec, YDSXGR_MODE, 0x00000000);
-	ymfpci_writel(codec, YDSXGR_MAPOFREC, 0x00000000);
-	ymfpci_writel(codec, YDSXGR_MAPOFEFFECT, 0x00000000);
-	ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0x00000000);
-	ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0x00000000);
-	ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0x00000000);
-	ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-	ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-
-	/* setup DSP instruction code */
-	for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
-		ymfpci_writel(codec, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]);
-
-	switch (codec->pci->device) {
-	case PCI_DEVICE_ID_YAMAHA_724F:
-	case PCI_DEVICE_ID_YAMAHA_740C:
-	case PCI_DEVICE_ID_YAMAHA_744:
-	case PCI_DEVICE_ID_YAMAHA_754:
-		ver_1e = 1;
-		break;
-	default:
-		ver_1e = 0;
-	}
-
-	if (ver_1e) {
-		/* setup control instruction code */
-		for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
-			ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst1E[i]);
-	} else {
-		for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
-			ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst[i]);
-	}
-
-	ymfpci_enable_dsp(codec);
-
-	/* 0.02s sounds not too bad, we may do schedule_timeout() later. */
-	mdelay(20); /* seems we need some delay after downloading image.. */
-}
-
-static int ymfpci_memalloc(ymfpci_t *codec)
-{
-	unsigned int playback_ctrl_size;
-	unsigned int bank_size_playback;
-	unsigned int bank_size_capture;
-	unsigned int bank_size_effect;
-	unsigned int size;
-	unsigned int off;
-	char *ptr;
-	dma_addr_t pba;
-	int voice, bank;
-
-	playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES;
-	bank_size_playback = ymfpci_readl(codec, YDSXGR_PLAYCTRLSIZE) << 2;
-	bank_size_capture = ymfpci_readl(codec, YDSXGR_RECCTRLSIZE) << 2;
-	bank_size_effect = ymfpci_readl(codec, YDSXGR_EFFCTRLSIZE) << 2;
-	codec->work_size = YDSXG_DEFAULT_WORK_SIZE;
-
-	size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +
-	    ((bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0xff) & ~0xff) +
-	    ((bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0xff) & ~0xff) +
-	    ((bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0xff) & ~0xff) +
-	    codec->work_size;
-
-	ptr = pci_alloc_consistent(codec->pci, size + 0xff, &pba);
-	if (ptr == NULL)
-		return -ENOMEM;
-	codec->dma_area_va = ptr;
-	codec->dma_area_ba = pba;
-	codec->dma_area_size = size + 0xff;
-
-	off = (unsigned long)ptr & 0xff;
-	if (off) {
-		ptr += 0x100 - off;
-		pba += 0x100 - off;
-	}
-
-	/*
-	 * Hardware requires only ptr[playback_ctrl_size] zeroed,
-	 * but in our judgement it is a wrong kind of savings, so clear it all.
-	 */
-	memset(ptr, 0, size);
-
-	codec->ctrl_playback = (u32 *)ptr;
-	codec->ctrl_playback_ba = pba;
-	codec->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
-	ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
-	pba += (playback_ctrl_size + 0x00ff) & ~0x00ff;
-
-	off = 0;
-	for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
-		codec->voices[voice].number = voice;
-		codec->voices[voice].bank =
-		    (ymfpci_playback_bank_t *) (ptr + off);
-		codec->voices[voice].bank_ba = pba + off;
-		off += 2 * bank_size_playback;		/* 2 banks */
-	}
-	off = (off + 0xff) & ~0xff;
-	ptr += off;
-	pba += off;
-
-	off = 0;
-	codec->bank_base_capture = pba;
-	for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
-		for (bank = 0; bank < 2; bank++) {
-			codec->bank_capture[voice][bank] =
-			    (ymfpci_capture_bank_t *) (ptr + off);
-			off += bank_size_capture;
-		}
-	off = (off + 0xff) & ~0xff;
-	ptr += off;
-	pba += off;
-
-	off = 0;
-	codec->bank_base_effect = pba;
-	for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
-		for (bank = 0; bank < 2; bank++) {
-			codec->bank_effect[voice][bank] =
-			    (ymfpci_effect_bank_t *) (ptr + off);
-			off += bank_size_effect;
-		}
-	off = (off + 0xff) & ~0xff;
-	ptr += off;
-	pba += off;
-
-	codec->work_base = pba;
-
-	return 0;
-}
-
-static void ymfpci_memfree(ymfpci_t *codec)
-{
-	ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0);
-	ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0);
-	ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0);
-	ymfpci_writel(codec, YDSXGR_WORKBASE, 0);
-	ymfpci_writel(codec, YDSXGR_WORKSIZE, 0);
-	pci_free_consistent(codec->pci,
-	    codec->dma_area_size, codec->dma_area_va, codec->dma_area_ba);
-}
-
-static void ymf_memload(ymfpci_t *unit)
-{
-
-	ymfpci_writel(unit, YDSXGR_PLAYCTRLBASE, unit->ctrl_playback_ba);
-	ymfpci_writel(unit, YDSXGR_RECCTRLBASE, unit->bank_base_capture);
-	ymfpci_writel(unit, YDSXGR_EFFCTRLBASE, unit->bank_base_effect);
-	ymfpci_writel(unit, YDSXGR_WORKBASE, unit->work_base);
-	ymfpci_writel(unit, YDSXGR_WORKSIZE, unit->work_size >> 2);
-
-	/* S/PDIF output initialization */
-	ymfpci_writew(unit, YDSXGR_SPDIFOUTCTRL, 0);
-	ymfpci_writew(unit, YDSXGR_SPDIFOUTSTATUS,
-		SND_PCM_AES0_CON_EMPHASIS_NONE |
-		(SND_PCM_AES1_CON_ORIGINAL << 8) |
-		(SND_PCM_AES1_CON_PCM_CODER << 8));
-
-	/* S/PDIF input initialization */
-	ymfpci_writew(unit, YDSXGR_SPDIFINCTRL, 0);
-
-	/* move this volume setup to mixer */
-	ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
-	ymfpci_writel(unit, YDSXGR_BUF441OUTVOL, 0);
-	ymfpci_writel(unit, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
-	ymfpci_writel(unit, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
-}
-
-static int ymf_ac97_init(ymfpci_t *unit, int num_ac97)
-{
-	struct ac97_codec *codec;
-	u16 eid;
-
-	if ((codec = ac97_alloc_codec()) == NULL)
-		return -ENOMEM;
-
-	/* initialize some basic codec information, other fields will be filled
-	   in ac97_probe_codec */
-	codec->private_data = unit;
-	codec->id = num_ac97;
-
-	codec->codec_read = ymfpci_codec_read;
-	codec->codec_write = ymfpci_codec_write;
-
-	if (ac97_probe_codec(codec) == 0) {
-		printk(KERN_ERR "ymfpci: ac97_probe_codec failed\n");
-		goto out_kfree;
-	}
-
-	eid = ymfpci_codec_read(codec, AC97_EXTENDED_ID);
-	if (eid==0xFFFF) {
-		printk(KERN_WARNING "ymfpci: no codec attached ?\n");
-		goto out_kfree;
-	}
-
-	unit->ac97_features = eid;
-
-	if ((codec->dev_mixer = register_sound_mixer(&ymf_mixer_fops, -1)) < 0) {
-		printk(KERN_ERR "ymfpci: couldn't register mixer!\n");
-		goto out_kfree;
-	}
-
-	unit->ac97_codec[num_ac97] = codec;
-
-	return 0;
- out_kfree:
-	ac97_release_codec(codec);
-	return -ENODEV;
-}
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-# ifdef MODULE
-static int mpu_io;
-static int synth_io;
-module_param(mpu_io, int, 0);
-module_param(synth_io, int, 0);
-# else
-static int mpu_io     = 0x330;
-static int synth_io   = 0x388;
-# endif
-static int assigned;
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_device_id *ent)
-{
-	u16 ctrl;
-	unsigned long base;
-	ymfpci_t *codec;
-
-	int err;
-
-	if ((err = pci_enable_device(pcidev)) != 0) {
-		printk(KERN_ERR "ymfpci: pci_enable_device failed\n");
-		return err;
-	}
-	base = pci_resource_start(pcidev, 0);
-
-	if ((codec = kmalloc(sizeof(ymfpci_t), GFP_KERNEL)) == NULL) {
-		printk(KERN_ERR "ymfpci: no core\n");
-		return -ENOMEM;
-	}
-	memset(codec, 0, sizeof(*codec));
-
-	spin_lock_init(&codec->reg_lock);
-	spin_lock_init(&codec->voice_lock);
-	spin_lock_init(&codec->ac97_lock);
-	mutex_init(&codec->open_mutex);
-	INIT_LIST_HEAD(&codec->states);
-	codec->pci = pcidev;
-
-	pci_read_config_byte(pcidev, PCI_REVISION_ID, &codec->rev);
-
-	if (request_mem_region(base, 0x8000, "ymfpci") == NULL) {
-		printk(KERN_ERR "ymfpci: unable to request mem region\n");
-		goto out_free;
-	}
-
-	if ((codec->reg_area_virt = ioremap(base, 0x8000)) == NULL) {
-		printk(KERN_ERR "ymfpci: unable to map registers\n");
-		goto out_release_region;
-	}
-
-	pci_set_master(pcidev);
-
-	printk(KERN_INFO "ymfpci: %s at 0x%lx IRQ %d\n",
-	    (char *)ent->driver_data, base, pcidev->irq);
-
-	ymfpci_aclink_reset(pcidev);
-	if (ymfpci_codec_ready(codec, 0, 1) < 0)
-		goto out_unmap;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-	if (assigned == 0) {
-		codec->iomidi = mpu_io;
-		codec->iosynth = synth_io;
-		if (ymfpci_setup_legacy(codec, pcidev) < 0)
-			goto out_unmap;
-		assigned = 1;
-	}
-#endif
-
-	ymfpci_download_image(codec);
-
-	if (ymfpci_memalloc(codec) < 0)
-		goto out_disable_dsp;
-	ymf_memload(codec);
-
-	if (request_irq(pcidev->irq, ymf_interrupt, IRQF_SHARED, "ymfpci", codec) != 0) {
-		printk(KERN_ERR "ymfpci: unable to request IRQ %d\n",
-		    pcidev->irq);
-		goto out_memfree;
-	}
-
-	/* register /dev/dsp */
-	if ((codec->dev_audio = register_sound_dsp(&ymf_fops, -1)) < 0) {
-		printk(KERN_ERR "ymfpci: unable to register dsp\n");
-		goto out_free_irq;
-	}
-
-	/*
-	 * Poke just the primary for the moment.
-	 */
-	if ((err = ymf_ac97_init(codec, 0)) != 0)
-		goto out_unregister_sound_dsp;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-	codec->opl3_data.name = "ymfpci";
-	codec->mpu_data.name  = "ymfpci";
-
-	codec->opl3_data.io_base = codec->iosynth;
-	codec->opl3_data.irq     = -1;
-
-	codec->mpu_data.io_base  = codec->iomidi;
-	codec->mpu_data.irq      = -1;	/* May be different from our PCI IRQ. */
-
-	if (codec->iomidi) {
-		if (!probe_uart401(&codec->mpu_data, THIS_MODULE)) {
-			codec->iomidi = 0;	/* XXX kludge */
-		}
-	}
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-	/* put it into driver list */
-	spin_lock(&ymf_devs_lock);
-	list_add_tail(&codec->ymf_devs, &ymf_devs);
-	spin_unlock(&ymf_devs_lock);
-	pci_set_drvdata(pcidev, codec);
-
-	return 0;
-
- out_unregister_sound_dsp:
-	unregister_sound_dsp(codec->dev_audio);
- out_free_irq:
-	free_irq(pcidev->irq, codec);
- out_memfree:
-	ymfpci_memfree(codec);
- out_disable_dsp:
-	ymfpci_disable_dsp(codec);
-	ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-	ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-	ymfpci_writel(codec, YDSXGR_STATUS, ~0);
- out_unmap:
-	iounmap(codec->reg_area_virt);
- out_release_region:
-	release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
- out_free:
-	if (codec->ac97_codec[0])
-		ac97_release_codec(codec->ac97_codec[0]);
-	return -ENODEV;
-}
-
-static void __devexit ymf_remove_one(struct pci_dev *pcidev)
-{
-	__u16 ctrl;
-	ymfpci_t *codec = pci_get_drvdata(pcidev);
-
-	/* remove from list of devices */
-	spin_lock(&ymf_devs_lock);
-	list_del(&codec->ymf_devs);
-	spin_unlock(&ymf_devs_lock);
-
-	unregister_sound_mixer(codec->ac97_codec[0]->dev_mixer);
-	ac97_release_codec(codec->ac97_codec[0]);
-	unregister_sound_dsp(codec->dev_audio);
-	free_irq(pcidev->irq, codec);
-	ymfpci_memfree(codec);
-	ymfpci_writel(codec, YDSXGR_STATUS, ~0);
-	ymfpci_disable_dsp(codec);
-	ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-	ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-	iounmap(codec->reg_area_virt);
-	release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-	if (codec->iomidi) {
-		unload_uart401(&codec->mpu_data);
-	}
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-}
-
-MODULE_AUTHOR("Jaroslav Kysela");
-MODULE_DESCRIPTION("Yamaha YMF7xx PCI Audio");
-MODULE_LICENSE("GPL");
-
-static struct pci_driver ymfpci_driver = {
-	.name		= "ymfpci",
-	.id_table	= ymf_id_tbl,
-	.probe		= ymf_probe_one,
-	.remove		= __devexit_p(ymf_remove_one),
-	.suspend	= ymf_suspend,
-	.resume		= ymf_resume
-};
-
-static int __init ymf_init_module(void)
-{
-	return pci_register_driver(&ymfpci_driver);
-}
-
-static void __exit ymf_cleanup_module (void)
-{
-	pci_unregister_driver(&ymfpci_driver);
-}
-
-module_init(ymf_init_module);
-module_exit(ymf_cleanup_module);
diff --git a/sound/oss/ymfpci.h b/sound/oss/ymfpci.h
deleted file mode 100644
index ac1785f..0000000
--- a/sound/oss/ymfpci.h
+++ /dev/null
@@ -1,361 +0,0 @@
-#ifndef __YMFPCI_H
-#define __YMFPCI_H
-
-/*
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
- *  Definitions for Yahama YMF724/740/744/754 chips
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/config.h>
-#include <linux/mutex.h>
-
-/*
- *  Direct registers
- */
-
-/* #define YMFREG(codec, reg)		(codec->port + YDSXGR_##reg) */
-
-#define	YDSXGR_INTFLAG			0x0004
-#define	YDSXGR_ACTIVITY			0x0006
-#define	YDSXGR_GLOBALCTRL		0x0008
-#define	YDSXGR_ZVCTRL			0x000A
-#define	YDSXGR_TIMERCTRL		0x0010
-#define	YDSXGR_TIMERCTRL_TEN		 0x0001
-#define	YDSXGR_TIMERCTRL_TIEN		 0x0002
-#define	YDSXGR_TIMERCOUNT		0x0012
-#define	YDSXGR_SPDIFOUTCTRL		0x0018
-#define	YDSXGR_SPDIFOUTSTATUS		0x001C
-#define	YDSXGR_EEPROMCTRL		0x0020
-#define	YDSXGR_SPDIFINCTRL		0x0034
-#define	YDSXGR_SPDIFINSTATUS		0x0038
-#define	YDSXGR_DSPPROGRAMDL		0x0048
-#define	YDSXGR_DLCNTRL			0x004C
-#define	YDSXGR_GPIOININTFLAG		0x0050
-#define	YDSXGR_GPIOININTENABLE		0x0052
-#define	YDSXGR_GPIOINSTATUS		0x0054
-#define	YDSXGR_GPIOOUTCTRL		0x0056
-#define	YDSXGR_GPIOFUNCENABLE		0x0058
-#define	YDSXGR_GPIOTYPECONFIG		0x005A
-#define	YDSXGR_AC97CMDDATA		0x0060
-#define	YDSXGR_AC97CMDADR		0x0062
-#define	YDSXGR_PRISTATUSDATA		0x0064
-#define	YDSXGR_PRISTATUSADR		0x0066
-#define	YDSXGR_SECSTATUSDATA		0x0068
-#define	YDSXGR_SECSTATUSADR		0x006A
-#define	YDSXGR_SECCONFIG		0x0070
-#define	YDSXGR_LEGACYOUTVOL		0x0080
-#define	YDSXGR_LEGACYOUTVOLL		0x0080
-#define	YDSXGR_LEGACYOUTVOLR		0x0082
-#define	YDSXGR_NATIVEDACOUTVOL		0x0084
-#define	YDSXGR_NATIVEDACOUTVOLL		0x0084
-#define	YDSXGR_NATIVEDACOUTVOLR		0x0086
-#define	YDSXGR_SPDIFOUTVOL		0x0088
-#define	YDSXGR_SPDIFOUTVOLL		0x0088
-#define	YDSXGR_SPDIFOUTVOLR		0x008A
-#define	YDSXGR_AC3OUTVOL		0x008C
-#define	YDSXGR_AC3OUTVOLL		0x008C
-#define	YDSXGR_AC3OUTVOLR		0x008E
-#define	YDSXGR_PRIADCOUTVOL		0x0090
-#define	YDSXGR_PRIADCOUTVOLL		0x0090
-#define	YDSXGR_PRIADCOUTVOLR		0x0092
-#define	YDSXGR_LEGACYLOOPVOL		0x0094
-#define	YDSXGR_LEGACYLOOPVOLL		0x0094
-#define	YDSXGR_LEGACYLOOPVOLR		0x0096
-#define	YDSXGR_NATIVEDACLOOPVOL		0x0098
-#define	YDSXGR_NATIVEDACLOOPVOLL	0x0098
-#define	YDSXGR_NATIVEDACLOOPVOLR	0x009A
-#define	YDSXGR_SPDIFLOOPVOL		0x009C
-#define	YDSXGR_SPDIFLOOPVOLL		0x009E
-#define	YDSXGR_SPDIFLOOPVOLR		0x009E
-#define	YDSXGR_AC3LOOPVOL		0x00A0
-#define	YDSXGR_AC3LOOPVOLL		0x00A0
-#define	YDSXGR_AC3LOOPVOLR		0x00A2
-#define	YDSXGR_PRIADCLOOPVOL		0x00A4
-#define	YDSXGR_PRIADCLOOPVOLL		0x00A4
-#define	YDSXGR_PRIADCLOOPVOLR		0x00A6
-#define	YDSXGR_NATIVEADCINVOL		0x00A8
-#define	YDSXGR_NATIVEADCINVOLL		0x00A8
-#define	YDSXGR_NATIVEADCINVOLR		0x00AA
-#define	YDSXGR_NATIVEDACINVOL		0x00AC
-#define	YDSXGR_NATIVEDACINVOLL		0x00AC
-#define	YDSXGR_NATIVEDACINVOLR		0x00AE
-#define	YDSXGR_BUF441OUTVOL		0x00B0
-#define	YDSXGR_BUF441OUTVOLL		0x00B0
-#define	YDSXGR_BUF441OUTVOLR		0x00B2
-#define	YDSXGR_BUF441LOOPVOL		0x00B4
-#define	YDSXGR_BUF441LOOPVOLL		0x00B4
-#define	YDSXGR_BUF441LOOPVOLR		0x00B6
-#define	YDSXGR_SPDIFOUTVOL2		0x00B8
-#define	YDSXGR_SPDIFOUTVOL2L		0x00B8
-#define	YDSXGR_SPDIFOUTVOL2R		0x00BA
-#define	YDSXGR_SPDIFLOOPVOL2		0x00BC
-#define	YDSXGR_SPDIFLOOPVOL2L		0x00BC
-#define	YDSXGR_SPDIFLOOPVOL2R		0x00BE
-#define	YDSXGR_ADCSLOTSR		0x00C0
-#define	YDSXGR_RECSLOTSR		0x00C4
-#define	YDSXGR_ADCFORMAT		0x00C8
-#define	YDSXGR_RECFORMAT		0x00CC
-#define	YDSXGR_P44SLOTSR		0x00D0
-#define	YDSXGR_STATUS			0x0100
-#define	YDSXGR_CTRLSELECT		0x0104
-#define	YDSXGR_MODE			0x0108
-#define	YDSXGR_SAMPLECOUNT		0x010C
-#define	YDSXGR_NUMOFSAMPLES		0x0110
-#define	YDSXGR_CONFIG			0x0114
-#define	YDSXGR_PLAYCTRLSIZE		0x0140
-#define	YDSXGR_RECCTRLSIZE		0x0144
-#define	YDSXGR_EFFCTRLSIZE		0x0148
-#define	YDSXGR_WORKSIZE			0x014C
-#define	YDSXGR_MAPOFREC			0x0150
-#define	YDSXGR_MAPOFEFFECT		0x0154
-#define	YDSXGR_PLAYCTRLBASE		0x0158
-#define	YDSXGR_RECCTRLBASE		0x015C
-#define	YDSXGR_EFFCTRLBASE		0x0160
-#define	YDSXGR_WORKBASE			0x0164
-#define	YDSXGR_DSPINSTRAM		0x1000
-#define	YDSXGR_CTRLINSTRAM		0x4000
-
-#define YDSXG_AC97READCMD		0x8000
-#define YDSXG_AC97WRITECMD		0x0000
-
-#define PCIR_LEGCTRL			0x40
-#define PCIR_ELEGCTRL			0x42
-#define PCIR_DSXGCTRL			0x48
-#define PCIR_DSXPWRCTRL1		0x4a
-#define PCIR_DSXPWRCTRL2		0x4e
-#define PCIR_OPLADR			0x60
-#define PCIR_SBADR			0x62
-#define PCIR_MPUADR			0x64
-
-#define YDSXG_DSPLENGTH			0x0080
-#define YDSXG_CTRLLENGTH		0x3000
-
-#define YDSXG_DEFAULT_WORK_SIZE		0x0400
-
-#define YDSXG_PLAYBACK_VOICES		64
-#define YDSXG_CAPTURE_VOICES		2
-#define YDSXG_EFFECT_VOICES		5
-
-/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
-#define NR_AC97		2
-
-#define YMF_SAMPF			256	/* Samples per frame @48000 */
-
-/*
- * The slot/voice control bank (2 of these per voice)
- */
-
-typedef struct stru_ymfpci_playback_bank {
-	u32 format;
-	u32 loop_default;
-	u32 base;			/* 32-bit address */
-	u32 loop_start;			/* 32-bit offset */
-	u32 loop_end;			/* 32-bit offset */
-	u32 loop_frac;			/* 8-bit fraction - loop_start */
-	u32 delta_end;			/* pitch delta end */
-	u32 lpfK_end;
-	u32 eg_gain_end;
-	u32 left_gain_end;
-	u32 right_gain_end;
-	u32 eff1_gain_end;
-	u32 eff2_gain_end;
-	u32 eff3_gain_end;
-	u32 lpfQ;
-	u32 status;		/* P3: Always 0 for some reason. */
-	u32 num_of_frames;
-	u32 loop_count;
-	u32 start;		/* P3: J. reads this to know where chip is. */
-	u32 start_frac;
-	u32 delta;
-	u32 lpfK;
-	u32 eg_gain;
-	u32 left_gain;
-	u32 right_gain;
-	u32 eff1_gain;
-	u32 eff2_gain;
-	u32 eff3_gain;
-	u32 lpfD1;
-	u32 lpfD2;
-} ymfpci_playback_bank_t;
-
-typedef struct stru_ymfpci_capture_bank {
-	u32 base;			/* 32-bit address (aligned at 4) */
-	u32 loop_end;			/* size in BYTES (aligned at 4) */
-	u32 start;			/* 32-bit offset */
-	u32 num_of_loops;		/* counter */
-} ymfpci_capture_bank_t;
-
-typedef struct stru_ymfpci_effect_bank {
-	u32 base;			/* 32-bit address */
-	u32 loop_end;			/* 32-bit offset */
-	u32 start;			/* 32-bit offset */
-	u32 temp;
-} ymfpci_effect_bank_t;
-
-typedef struct ymf_voice ymfpci_voice_t;
-/*
- * Throughout the code Yaroslav names YMF unit pointer "codec"
- * even though it does not correspond to any codec. Must be historic.
- * We replace it with "unit" over time.
- * AC97 parts use "codec" to denote a codec, naturally.
- */
-typedef struct ymf_unit ymfpci_t;
-
-typedef enum {
-	YMFPCI_PCM,
-	YMFPCI_SYNTH,
-	YMFPCI_MIDI
-} ymfpci_voice_type_t;
-
-struct ymf_voice {
-	// ymfpci_t *codec;
-	int number;
-	char use, pcm, synth, midi;	// bool
-	ymfpci_playback_bank_t *bank;
-	struct ymf_pcm *ypcm;
-	dma_addr_t bank_ba;
-};
-
-struct ymf_capture {
-	// struct ymf_unit *unit;
-	int use;
-	ymfpci_capture_bank_t *bank;
-	struct ymf_pcm *ypcm;
-};
-
-struct ymf_unit {
-	u8 rev;				/* PCI revision */
-	void __iomem *reg_area_virt;
-	void *dma_area_va;
-	dma_addr_t dma_area_ba;
-	unsigned int dma_area_size;
-
-	dma_addr_t bank_base_capture;
-	dma_addr_t bank_base_effect;
-	dma_addr_t work_base;
-	unsigned int work_size;
-
-	u32 *ctrl_playback;
-	dma_addr_t ctrl_playback_ba;
-	ymfpci_playback_bank_t *bank_playback[YDSXG_PLAYBACK_VOICES][2];
-	ymfpci_capture_bank_t *bank_capture[YDSXG_CAPTURE_VOICES][2];
-	ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2];
-
-	int start_count;
-	int suspended;
-
-	u32 active_bank;
-	struct ymf_voice voices[YDSXG_PLAYBACK_VOICES];
-	struct ymf_capture capture[YDSXG_CAPTURE_VOICES];
-
-	struct ac97_codec *ac97_codec[NR_AC97];
-	u16 ac97_features;
-
-	struct pci_dev *pci;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-	/* legacy hardware resources */
-	unsigned int iosynth, iomidi;
-	struct address_info opl3_data, mpu_data;
-#endif
-
-	spinlock_t reg_lock;
-	spinlock_t voice_lock;
-	spinlock_t ac97_lock;
-
-	/* soundcore stuff */
-	int dev_audio;
-	struct mutex open_mutex;
-
-	struct list_head ymf_devs;
-	struct list_head states;	/* List of states for this unit */
-};
-
-struct ymf_dmabuf {
-	dma_addr_t dma_addr;
-	void *rawbuf;
-	unsigned buforder;
-
-	/* OSS buffer management stuff */
-	unsigned numfrag;
-	unsigned fragshift;
-
-	/* our buffer acts like a circular ring */
-	unsigned hwptr;		/* where dma last started */
-	unsigned swptr;		/* where driver last clear/filled */
-	int count;		/* fill count */
-	unsigned total_bytes;	/* total bytes dmaed by hardware */
-
-	wait_queue_head_t wait;	/* put process on wait queue when no more space in buffer */
-
-	/* redundant, but makes calculations easier */
-	unsigned fragsize;
-	unsigned dmasize;	/* Total rawbuf[] size */
-
-	/* OSS stuff */
-	unsigned mapped:1;
-	unsigned ready:1;
-	unsigned ossfragshift;
-	int ossmaxfrags;
-	unsigned subdivision;
-};
-
-struct ymf_pcm_format {
-	int format;			/* OSS format */
-	int rate;			/* rate in Hz */
-	int voices;			/* number of voices */
-	int shift;			/* redundant, computed from the above */
-};
-
-typedef enum {
-	PLAYBACK_VOICE,
-	CAPTURE_REC,
-	CAPTURE_AC97,
-	EFFECT_DRY_LEFT,
-	EFFECT_DRY_RIGHT,
-	EFFECT_EFF1,
-	EFFECT_EFF2,
-	EFFECT_EFF3
-} ymfpci_pcm_type_t;
-
-/* This is variant record, but we hate unions. Little waste on pointers []. */
-struct ymf_pcm {
-	ymfpci_pcm_type_t type;
-	struct ymf_state *state;
-
-	ymfpci_voice_t *voices[2];
-	int capture_bank_number;
-
-	struct ymf_dmabuf dmabuf;
-	int running;
-	int spdif;
-};
-
-/*
- * "Software" or virtual channel, an instance of opened /dev/dsp.
- * It may have two physical channels (pcms) for duplex operations.
- */
-
-struct ymf_state {
-	struct list_head chain;
-	struct ymf_unit *unit;			/* backpointer */
-	struct ymf_pcm rpcm, wpcm;
-	struct ymf_pcm_format format;
-};
-
-#endif				/* __YMFPCI_H */
diff --git a/sound/oss/ymfpci_image.h b/sound/oss/ymfpci_image.h
deleted file mode 100644
index 112f2ff..0000000
--- a/sound/oss/ymfpci_image.h
+++ /dev/null
@@ -1,1565 +0,0 @@
-#ifndef _HWMCODE_
-#define _HWMCODE_
-
-static u32 DspInst[YDSXG_DSPLENGTH / 4] = {
-	0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
-	0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
-	0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
-	0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
-
-static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = {
-	0x000007, 0x240007, 0x0C0007, 0x1C0007,
-	0x060007, 0x700002, 0x000020, 0x030040,
-	0x007104, 0x004286, 0x030040, 0x000F0D,
-	0x000810, 0x20043A, 0x000282, 0x00020D,
-	0x000810, 0x20043A, 0x001282, 0x200E82,
-	0x001A82, 0x032D0D, 0x000810, 0x10043A,
-	0x02D38D, 0x000810, 0x18043A, 0x00010D,
-	0x020015, 0x0000FD, 0x000020, 0x038860,
-	0x039060, 0x038060, 0x038040, 0x038040,
-	0x038040, 0x018040, 0x000A7D, 0x038040,
-	0x038040, 0x018040, 0x200402, 0x000882,
-	0x08001A, 0x000904, 0x015986, 0x000007,
-	0x260007, 0x000007, 0x000007, 0x018A06,
-	0x000007, 0x030C8D, 0x000810, 0x18043A,
-	0x260007, 0x00087D, 0x018042, 0x00160A,
-	0x04A206, 0x000007, 0x00218D, 0x000810,
-	0x08043A, 0x21C206, 0x000007, 0x0007FD,
-	0x018042, 0x08000A, 0x000904, 0x029386,
-	0x000195, 0x090D04, 0x000007, 0x000820,
-	0x0000F5, 0x000B7D, 0x01F060, 0x0000FD,
-	0x032206, 0x018040, 0x000A7D, 0x038042,
-	0x13804A, 0x18000A, 0x001820, 0x059060,
-	0x058860, 0x018040, 0x0000FD, 0x018042,
-	0x70000A, 0x000115, 0x071144, 0x032386,
-	0x030000, 0x007020, 0x034A06, 0x018040,
-	0x00348D, 0x000810, 0x08043A, 0x21EA06,
-	0x000007, 0x02D38D, 0x000810, 0x18043A,
-	0x018206, 0x000007, 0x240007, 0x000F8D,
-	0x000810, 0x00163A, 0x002402, 0x005C02,
-	0x0028FD, 0x000020, 0x018040, 0x08000D,
-	0x000815, 0x510984, 0x000007, 0x00004D,
-	0x000E5D, 0x000E02, 0x00418D, 0x000810,
-	0x08043A, 0x2C8A06, 0x000007, 0x00008D,
-	0x000924, 0x000F02, 0x00458D, 0x000810,
-	0x08043A, 0x2C8A06, 0x000007, 0x00387D,
-	0x018042, 0x08000A, 0x001015, 0x010984,
-	0x018386, 0x000007, 0x01AA06, 0x000007,
-	0x0008FD, 0x018042, 0x18000A, 0x001904,
-	0x218086, 0x280007, 0x001810, 0x28043A,
-	0x280C02, 0x00000D, 0x000810, 0x28143A,
-	0x08808D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00020D, 0x189904, 0x000007,
-	0x00402D, 0x0000BD, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x055A86, 0x000007,
-	0x000100, 0x000A20, 0x00047D, 0x018040,
-	0x018042, 0x20000A, 0x003015, 0x012144,
-	0x034986, 0x000007, 0x002104, 0x034986,
-	0x000007, 0x000F8D, 0x000810, 0x280C3A,
-	0x023944, 0x06C986, 0x000007, 0x001810,
-	0x28043A, 0x08810D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x002810, 0x78003A,
-	0x00688D, 0x000810, 0x08043A, 0x288A06,
-	0x000007, 0x00400D, 0x001015, 0x189904,
-	0x292904, 0x393904, 0x000007, 0x060206,
-	0x000007, 0x0004F5, 0x00007D, 0x000020,
-	0x00008D, 0x010860, 0x018040, 0x00047D,
-	0x038042, 0x21804A, 0x18000A, 0x021944,
-	0x215886, 0x000007, 0x004075, 0x71F104,
-	0x000007, 0x010042, 0x28000A, 0x002904,
-	0x212086, 0x000007, 0x003C0D, 0x30A904,
-	0x000007, 0x00077D, 0x018042, 0x08000A,
-	0x000904, 0x07DA86, 0x00057D, 0x002820,
-	0x03B060, 0x07F206, 0x018040, 0x003020,
-	0x03A860, 0x018040, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x07FA86, 0x000007,
-	0x00057D, 0x018042, 0x28040A, 0x000E8D,
-	0x000810, 0x280C3A, 0x00000D, 0x000810,
-	0x28143A, 0x09000D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x003DFD, 0x000020,
-	0x018040, 0x00107D, 0x008D8D, 0x000810,
-	0x08043A, 0x288A06, 0x000007, 0x000815,
-	0x08001A, 0x010984, 0x095186, 0x00137D,
-	0x200500, 0x280F20, 0x338F60, 0x3B8F60,
-	0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-	0x038A60, 0x018040, 0x007FBD, 0x383DC4,
-	0x000007, 0x001A7D, 0x001375, 0x018042,
-	0x09004A, 0x10000A, 0x0B8D04, 0x139504,
-	0x000007, 0x000820, 0x019060, 0x001104,
-	0x212086, 0x010040, 0x0017FD, 0x018042,
-	0x08000A, 0x000904, 0x212286, 0x000007,
-	0x00197D, 0x038042, 0x09804A, 0x10000A,
-	0x000924, 0x001664, 0x0011FD, 0x038042,
-	0x2B804A, 0x19804A, 0x00008D, 0x218944,
-	0x000007, 0x002244, 0x0AE186, 0x000007,
-	0x001A64, 0x002A24, 0x00197D, 0x080102,
-	0x100122, 0x000820, 0x039060, 0x018040,
-	0x003DFD, 0x00008D, 0x000820, 0x018040,
-	0x001375, 0x001A7D, 0x010042, 0x09804A,
-	0x10000A, 0x00021D, 0x0189E4, 0x2992E4,
-	0x309144, 0x000007, 0x00060D, 0x000A15,
-	0x000C1D, 0x001025, 0x00A9E4, 0x012BE4,
-	0x000464, 0x01B3E4, 0x0232E4, 0x000464,
-	0x000464, 0x000464, 0x000464, 0x00040D,
-	0x08B1C4, 0x000007, 0x000820, 0x000BF5,
-	0x030040, 0x00197D, 0x038042, 0x09804A,
-	0x000A24, 0x08000A, 0x080E64, 0x000007,
-	0x100122, 0x000820, 0x031060, 0x010040,
-	0x0064AC, 0x00027D, 0x000020, 0x018040,
-	0x00107D, 0x018042, 0x0011FD, 0x3B804A,
-	0x09804A, 0x20000A, 0x000095, 0x1A1144,
-	0x00A144, 0x0D2086, 0x00040D, 0x00B984,
-	0x0D2186, 0x0018FD, 0x018042, 0x0010FD,
-	0x09804A, 0x28000A, 0x000095, 0x010924,
-	0x002A64, 0x0D1186, 0x000007, 0x002904,
-	0x0D2286, 0x000007, 0x0D2A06, 0x080002,
-	0x00008D, 0x00387D, 0x000820, 0x018040,
-	0x00127D, 0x018042, 0x10000A, 0x003904,
-	0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984,
-	0x0DA186, 0x000025, 0x0E7A06, 0x00002D,
-	0x000015, 0x00082D, 0x02C78D, 0x000820,
-	0x0EC206, 0x00000D, 0x7F8035, 0x00B984,
-	0x0E7186, 0x400025, 0x00008D, 0x110944,
-	0x000007, 0x00018D, 0x109504, 0x000007,
-	0x009164, 0x000424, 0x000424, 0x000424,
-	0x100102, 0x280002, 0x02C68D, 0x000820,
-	0x0EC206, 0x00018D, 0x00042D, 0x00008D,
-	0x109504, 0x000007, 0x00020D, 0x109184,
-	0x000007, 0x02C70D, 0x000820, 0x00008D,
-	0x0038FD, 0x018040, 0x003BFD, 0x001020,
-	0x03A860, 0x000815, 0x313184, 0x212184,
-	0x000007, 0x03B060, 0x03A060, 0x018040,
-	0x0022FD, 0x000095, 0x010924, 0x000424,
-	0x000424, 0x001264, 0x100102, 0x000820,
-	0x039060, 0x018040, 0x001924, 0x00FB8D,
-	0x00397D, 0x000820, 0x058040, 0x038042,
-	0x09844A, 0x000606, 0x08040A, 0x000424,
-	0x000424, 0x00117D, 0x018042, 0x08000A,
-	0x000A24, 0x280502, 0x280C02, 0x09800D,
-	0x000820, 0x0002FD, 0x018040, 0x200007,
-	0x0022FD, 0x018042, 0x08000A, 0x000095,
-	0x280DC4, 0x011924, 0x00197D, 0x018042,
-	0x0011FD, 0x09804A, 0x10000A, 0x0000B5,
-	0x113144, 0x0A8D04, 0x000007, 0x080A44,
-	0x129504, 0x000007, 0x0023FD, 0x001020,
-	0x038040, 0x101244, 0x000007, 0x000820,
-	0x039060, 0x018040, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x10FA86, 0x000007,
-	0x003BFD, 0x000100, 0x000A10, 0x0B807A,
-	0x13804A, 0x090984, 0x000007, 0x000095,
-	0x013D04, 0x118086, 0x10000A, 0x100002,
-	0x090984, 0x000007, 0x038042, 0x11804A,
-	0x090D04, 0x000007, 0x10000A, 0x090D84,
-	0x000007, 0x00257D, 0x000820, 0x018040,
-	0x00010D, 0x000810, 0x28143A, 0x00127D,
-	0x018042, 0x20000A, 0x00197D, 0x018042,
-	0x00117D, 0x31804A, 0x10000A, 0x003124,
-	0x01280D, 0x00397D, 0x000820, 0x058040,
-	0x038042, 0x09844A, 0x000606, 0x08040A,
-	0x300102, 0x003124, 0x000424, 0x000424,
-	0x001224, 0x280502, 0x001A4C, 0x130186,
-	0x700002, 0x00002D, 0x030000, 0x00387D,
-	0x018042, 0x10000A, 0x132A06, 0x002124,
-	0x0000AD, 0x100002, 0x00010D, 0x000924,
-	0x006B24, 0x01368D, 0x00397D, 0x000820,
-	0x058040, 0x038042, 0x09844A, 0x000606,
-	0x08040A, 0x003264, 0x00008D, 0x000A24,
-	0x001020, 0x00227D, 0x018040, 0x013C0D,
-	0x000810, 0x08043A, 0x29D206, 0x000007,
-	0x002820, 0x00207D, 0x018040, 0x00117D,
-	0x038042, 0x13804A, 0x33800A, 0x00387D,
-	0x018042, 0x08000A, 0x000904, 0x163A86,
-	0x000007, 0x00008D, 0x030964, 0x01478D,
-	0x00397D, 0x000820, 0x058040, 0x038042,
-	0x09844A, 0x000606, 0x08040A, 0x380102,
-	0x000424, 0x000424, 0x001224, 0x0002FD,
-	0x018042, 0x08000A, 0x000904, 0x14A286,
-	0x000007, 0x280502, 0x001A4C, 0x163986,
-	0x000007, 0x032164, 0x00632C, 0x003DFD,
-	0x018042, 0x08000A, 0x000095, 0x090904,
-	0x000007, 0x000820, 0x001A4C, 0x156186,
-	0x018040, 0x030000, 0x157A06, 0x002124,
-	0x00010D, 0x000924, 0x006B24, 0x015B8D,
-	0x00397D, 0x000820, 0x058040, 0x038042,
-	0x09844A, 0x000606, 0x08040A, 0x003A64,
-	0x000095, 0x001224, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x15DA86, 0x000007,
-	0x01628D, 0x000810, 0x08043A, 0x29D206,
-	0x000007, 0x14D206, 0x000007, 0x007020,
-	0x08010A, 0x10012A, 0x0020FD, 0x038860,
-	0x039060, 0x018040, 0x00227D, 0x018042,
-	0x003DFD, 0x08000A, 0x31844A, 0x000904,
-	0x16D886, 0x18008B, 0x00008D, 0x189904,
-	0x00312C, 0x17AA06, 0x000007, 0x00324C,
-	0x173386, 0x000007, 0x001904, 0x173086,
-	0x000007, 0x000095, 0x199144, 0x00222C,
-	0x003124, 0x00636C, 0x000E3D, 0x001375,
-	0x000BFD, 0x010042, 0x09804A, 0x10000A,
-	0x038AEC, 0x0393EC, 0x00224C, 0x17A986,
-	0x000007, 0x00008D, 0x189904, 0x00226C,
-	0x00322C, 0x30050A, 0x301DAB, 0x002083,
-	0x0018FD, 0x018042, 0x08000A, 0x018924,
-	0x300502, 0x001083, 0x001875, 0x010042,
-	0x10000A, 0x00008D, 0x010924, 0x001375,
-	0x330542, 0x330CCB, 0x332CCB, 0x3334CB,
-	0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB,
-	0x305C8B, 0x006083, 0x0002F5, 0x010042,
-	0x08000A, 0x000904, 0x187A86, 0x000007,
-	0x001E2D, 0x0005FD, 0x018042, 0x08000A,
-	0x028924, 0x280502, 0x00060D, 0x000810,
-	0x280C3A, 0x00008D, 0x000810, 0x28143A,
-	0x0A808D, 0x000820, 0x0002F5, 0x010040,
-	0x220007, 0x001275, 0x030042, 0x21004A,
-	0x00008D, 0x1A0944, 0x000007, 0x01980D,
-	0x000810, 0x08043A, 0x2B2206, 0x000007,
-	0x0001F5, 0x030042, 0x0D004A, 0x10000A,
-	0x089144, 0x000007, 0x000820, 0x010040,
-	0x0025F5, 0x0A3144, 0x000007, 0x000820,
-	0x032860, 0x030040, 0x00217D, 0x038042,
-	0x0B804A, 0x10000A, 0x000820, 0x031060,
-	0x030040, 0x00008D, 0x000124, 0x00012C,
-	0x000E64, 0x001A64, 0x00636C, 0x08010A,
-	0x10012A, 0x000820, 0x031060, 0x030040,
-	0x0020FD, 0x018042, 0x08000A, 0x00227D,
-	0x018042, 0x10000A, 0x000820, 0x031060,
-	0x030040, 0x00197D, 0x018042, 0x08000A,
-	0x0022FD, 0x038042, 0x10000A, 0x000820,
-	0x031060, 0x030040, 0x090D04, 0x000007,
-	0x000820, 0x030040, 0x038042, 0x0B804A,
-	0x10000A, 0x000820, 0x031060, 0x030040,
-	0x038042, 0x13804A, 0x19804A, 0x110D04,
-	0x198D04, 0x000007, 0x08000A, 0x001020,
-	0x031860, 0x030860, 0x030040, 0x00008D,
-	0x0B0944, 0x000007, 0x000820, 0x010040,
-	0x0005F5, 0x030042, 0x08000A, 0x000820,
-	0x010040, 0x0000F5, 0x010042, 0x08000A,
-	0x000904, 0x1C6086, 0x001E75, 0x030042,
-	0x01044A, 0x000C0A, 0x1C7206, 0x000007,
-	0x000402, 0x000C02, 0x00177D, 0x001AF5,
-	0x018042, 0x03144A, 0x031C4A, 0x03244A,
-	0x032C4A, 0x03344A, 0x033C4A, 0x03444A,
-	0x004C0A, 0x00043D, 0x0013F5, 0x001AFD,
-	0x030042, 0x0B004A, 0x1B804A, 0x13804A,
-	0x20000A, 0x089144, 0x19A144, 0x0389E4,
-	0x0399EC, 0x005502, 0x005D0A, 0x030042,
-	0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
-	0x089144, 0x19A144, 0x0389E4, 0x0399EC,
-	0x006502, 0x006D0A, 0x030042, 0x0B004A,
-	0x19004A, 0x2B804A, 0x13804A, 0x21804A,
-	0x30000A, 0x089144, 0x19A144, 0x2AB144,
-	0x0389E4, 0x0399EC, 0x007502, 0x007D0A,
-	0x03A9E4, 0x000702, 0x00107D, 0x000415,
-	0x018042, 0x08000A, 0x0109E4, 0x000F02,
-	0x002AF5, 0x0019FD, 0x010042, 0x09804A,
-	0x10000A, 0x000934, 0x001674, 0x0029F5,
-	0x010042, 0x10000A, 0x00917C, 0x002075,
-	0x010042, 0x08000A, 0x000904, 0x1ED286,
-	0x0026F5, 0x0027F5, 0x030042, 0x09004A,
-	0x10000A, 0x000A3C, 0x00167C, 0x001A75,
-	0x000BFD, 0x010042, 0x51804A, 0x48000A,
-	0x160007, 0x001075, 0x010042, 0x282C0A,
-	0x281D12, 0x282512, 0x001F32, 0x1E0007,
-	0x0E0007, 0x001975, 0x010042, 0x002DF5,
-	0x0D004A, 0x10000A, 0x009144, 0x1FB286,
-	0x010042, 0x28340A, 0x000E5D, 0x00008D,
-	0x000375, 0x000820, 0x010040, 0x05D2F4,
-	0x54D104, 0x00735C, 0x205386, 0x000007,
-	0x0C0007, 0x080007, 0x0A0007, 0x02040D,
-	0x000810, 0x08043A, 0x332206, 0x000007,
-	0x205A06, 0x000007, 0x080007, 0x002275,
-	0x010042, 0x20000A, 0x002104, 0x212086,
-	0x001E2D, 0x0002F5, 0x010042, 0x08000A,
-	0x000904, 0x209286, 0x000007, 0x002010,
-	0x30043A, 0x00057D, 0x0180C3, 0x08000A,
-	0x028924, 0x280502, 0x280C02, 0x0A810D,
-	0x000820, 0x0002F5, 0x010040, 0x220007,
-	0x0004FD, 0x018042, 0x70000A, 0x030000,
-	0x007020, 0x06FA06, 0x018040, 0x02180D,
-	0x000810, 0x08043A, 0x2B2206, 0x000007,
-	0x0002FD, 0x018042, 0x08000A, 0x000904,
-	0x218A86, 0x000007, 0x01F206, 0x000007,
-	0x000875, 0x0009FD, 0x00010D, 0x220A06,
-	0x000295, 0x000B75, 0x00097D, 0x00000D,
-	0x000515, 0x010042, 0x18000A, 0x001904,
-	0x287886, 0x0006F5, 0x001020, 0x010040,
-	0x0004F5, 0x000820, 0x010040, 0x000775,
-	0x010042, 0x09804A, 0x10000A, 0x001124,
-	0x000904, 0x22BA86, 0x000815, 0x080102,
-	0x101204, 0x22DA06, 0x000575, 0x081204,
-	0x000007, 0x100102, 0x000575, 0x000425,
-	0x021124, 0x100102, 0x000820, 0x031060,
-	0x010040, 0x001924, 0x287886, 0x00008D,
-	0x000464, 0x009D04, 0x278886, 0x180102,
-	0x000575, 0x010042, 0x28040A, 0x00018D,
-	0x000924, 0x280D02, 0x00000D, 0x000924,
-	0x281502, 0x10000D, 0x000820, 0x0002F5,
-	0x010040, 0x200007, 0x001175, 0x0002FD,
-	0x018042, 0x08000A, 0x000904, 0x23C286,
-	0x000007, 0x000100, 0x080B20, 0x130B60,
-	0x1B0B60, 0x030A60, 0x010040, 0x050042,
-	0x3D004A, 0x35004A, 0x2D004A, 0x20000A,
-	0x0006F5, 0x010042, 0x28140A, 0x0004F5,
-	0x010042, 0x08000A, 0x000315, 0x010D04,
-	0x24CA86, 0x004015, 0x000095, 0x010D04,
-	0x24B886, 0x100022, 0x10002A, 0x24E206,
-	0x000007, 0x333104, 0x2AA904, 0x000007,
-	0x032124, 0x280502, 0x001124, 0x000424,
-	0x000424, 0x003224, 0x00292C, 0x00636C,
-	0x25F386, 0x000007, 0x02B164, 0x000464,
-	0x000464, 0x00008D, 0x000A64, 0x280D02,
-	0x10008D, 0x000820, 0x0002F5, 0x010040,
-	0x220007, 0x00008D, 0x38B904, 0x000007,
-	0x03296C, 0x30010A, 0x0002F5, 0x010042,
-	0x08000A, 0x000904, 0x25BA86, 0x000007,
-	0x02312C, 0x28050A, 0x00008D, 0x01096C,
-	0x280D0A, 0x10010D, 0x000820, 0x0002F5,
-	0x010040, 0x220007, 0x001124, 0x000424,
-	0x000424, 0x003224, 0x300102, 0x032944,
-	0x267A86, 0x000007, 0x300002, 0x0004F5,
-	0x010042, 0x08000A, 0x000315, 0x010D04,
-	0x26C086, 0x003124, 0x000464, 0x300102,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x26CA86, 0x000007, 0x003124, 0x300502,
-	0x003924, 0x300583, 0x000883, 0x0005F5,
-	0x010042, 0x28040A, 0x00008D, 0x008124,
-	0x280D02, 0x00008D, 0x008124, 0x281502,
-	0x10018D, 0x000820, 0x0002F5, 0x010040,
-	0x220007, 0x001025, 0x000575, 0x030042,
-	0x09004A, 0x10000A, 0x0A0904, 0x121104,
-	0x000007, 0x001020, 0x050860, 0x050040,
-	0x0006FD, 0x018042, 0x09004A, 0x10000A,
-	0x0000A5, 0x0A0904, 0x121104, 0x000007,
-	0x000820, 0x019060, 0x010040, 0x0002F5,
-	0x010042, 0x08000A, 0x000904, 0x284286,
-	0x000007, 0x230A06, 0x000007, 0x000606,
-	0x000007, 0x0002F5, 0x010042, 0x08000A,
-	0x000904, 0x289286, 0x000007, 0x000100,
-	0x080B20, 0x138B60, 0x1B8B60, 0x238B60,
-	0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60,
-	0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60,
-	0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60,
-	0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60,
-	0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60,
-	0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60,
-	0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60,
-	0x000606, 0x018040, 0x00008D, 0x000A64,
-	0x280D02, 0x000A24, 0x00027D, 0x018042,
-	0x10000A, 0x001224, 0x0003FD, 0x018042,
-	0x08000A, 0x000904, 0x2A8286, 0x000007,
-	0x00018D, 0x000A24, 0x000464, 0x000464,
-	0x080102, 0x000924, 0x000424, 0x000424,
-	0x100102, 0x02000D, 0x009144, 0x2AD986,
-	0x000007, 0x0001FD, 0x018042, 0x08000A,
-	0x000A44, 0x2ABB86, 0x018042, 0x0A000D,
-	0x000820, 0x0002FD, 0x018040, 0x200007,
-	0x00027D, 0x001020, 0x000606, 0x018040,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x2B2A86, 0x000007, 0x00037D, 0x018042,
-	0x08000A, 0x000904, 0x2B5A86, 0x000007,
-	0x000075, 0x002E7D, 0x010042, 0x0B804A,
-	0x000020, 0x000904, 0x000686, 0x010040,
-	0x31844A, 0x30048B, 0x000883, 0x00008D,
-	0x000810, 0x28143A, 0x00008D, 0x000810,
-	0x280C3A, 0x000675, 0x010042, 0x08000A,
-	0x003815, 0x010924, 0x280502, 0x0B000D,
-	0x000820, 0x0002F5, 0x010040, 0x000606,
-	0x220007, 0x000464, 0x000464, 0x000606,
-	0x000007, 0x000134, 0x007F8D, 0x00093C,
-	0x281D12, 0x282512, 0x001F32, 0x0E0007,
-	0x00010D, 0x00037D, 0x000820, 0x018040,
-	0x05D2F4, 0x000007, 0x080007, 0x00037D,
-	0x018042, 0x08000A, 0x000904, 0x2D0286,
-	0x000007, 0x000606, 0x000007, 0x000007,
-	0x000012, 0x100007, 0x320007, 0x600007,
-	0x100080, 0x48001A, 0x004904, 0x2D6186,
-	0x000007, 0x001210, 0x58003A, 0x000145,
-	0x5C5D04, 0x000007, 0x000080, 0x48001A,
-	0x004904, 0x2DB186, 0x000007, 0x001210,
-	0x50003A, 0x005904, 0x2E0886, 0x000045,
-	0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524,
-	0x004224, 0x500102, 0x200502, 0x000082,
-	0x40001A, 0x004104, 0x2E3986, 0x000007,
-	0x003865, 0x40001A, 0x004020, 0x00104D,
-	0x04C184, 0x301B86, 0x000040, 0x040007,
-	0x000165, 0x000145, 0x004020, 0x000040,
-	0x000765, 0x080080, 0x40001A, 0x004104,
-	0x2EC986, 0x000007, 0x001210, 0x40003A,
-	0x004104, 0x2F2286, 0x00004D, 0x0000CD,
-	0x004810, 0x20043A, 0x000882, 0x40001A,
-	0x004104, 0x2F3186, 0x000007, 0x004820,
-	0x005904, 0x300886, 0x000040, 0x0007E5,
-	0x200480, 0x2816A0, 0x3216E0, 0x3A16E0,
-	0x4216E0, 0x021260, 0x000040, 0x000032,
-	0x400075, 0x00007D, 0x07D574, 0x200512,
-	0x000082, 0x40001A, 0x004104, 0x2FE186,
-	0x000007, 0x037206, 0x640007, 0x060007,
-	0x0000E5, 0x000020, 0x000040, 0x000A65,
-	0x000020, 0x020040, 0x020040, 0x000040,
-	0x000165, 0x000042, 0x70000A, 0x007104,
-	0x30A286, 0x000007, 0x018206, 0x640007,
-	0x050000, 0x007020, 0x000040, 0x037206,
-	0x640007, 0x000007, 0x00306D, 0x028860,
-	0x029060, 0x08000A, 0x028860, 0x008040,
-	0x100012, 0x00100D, 0x009184, 0x314186,
-	0x000E0D, 0x009184, 0x325186, 0x000007,
-	0x300007, 0x001020, 0x003B6D, 0x008040,
-	0x000080, 0x08001A, 0x000904, 0x316186,
-	0x000007, 0x001220, 0x000DED, 0x008040,
-	0x008042, 0x10000A, 0x40000D, 0x109544,
-	0x000007, 0x001020, 0x000DED, 0x008040,
-	0x008042, 0x20040A, 0x000082, 0x08001A,
-	0x000904, 0x31F186, 0x000007, 0x003B6D,
-	0x008042, 0x08000A, 0x000E15, 0x010984,
-	0x329B86, 0x600007, 0x08001A, 0x000C15,
-	0x010984, 0x328386, 0x000020, 0x1A0007,
-	0x0002ED, 0x008040, 0x620007, 0x00306D,
-	0x028042, 0x0A804A, 0x000820, 0x0A804A,
-	0x000606, 0x10804A, 0x000007, 0x282512,
-	0x001F32, 0x05D2F4, 0x54D104, 0x00735C,
-	0x000786, 0x000007, 0x0C0007, 0x0A0007,
-	0x1C0007, 0x003465, 0x020040, 0x004820,
-	0x025060, 0x40000A, 0x024060, 0x000040,
-	0x454944, 0x000007, 0x004020, 0x003AE5,
-	0x000040, 0x0028E5, 0x000042, 0x48000A,
-	0x004904, 0x386886, 0x002C65, 0x000042,
-	0x40000A, 0x0000D5, 0x454104, 0x000007,
-	0x000655, 0x054504, 0x34F286, 0x0001D5,
-	0x054504, 0x34F086, 0x002B65, 0x000042,
-	0x003AE5, 0x50004A, 0x40000A, 0x45C3D4,
-	0x000007, 0x454504, 0x000007, 0x0000CD,
-	0x444944, 0x000007, 0x454504, 0x000007,
-	0x00014D, 0x554944, 0x000007, 0x045144,
-	0x34E986, 0x002C65, 0x000042, 0x48000A,
-	0x4CD104, 0x000007, 0x04C144, 0x34F386,
-	0x000007, 0x160007, 0x002CE5, 0x040042,
-	0x40000A, 0x004020, 0x000040, 0x002965,
-	0x000042, 0x40000A, 0x004104, 0x356086,
-	0x000007, 0x002402, 0x36A206, 0x005C02,
-	0x0025E5, 0x000042, 0x40000A, 0x004274,
-	0x002AE5, 0x000042, 0x40000A, 0x004274,
-	0x500112, 0x0029E5, 0x000042, 0x40000A,
-	0x004234, 0x454104, 0x000007, 0x004020,
-	0x000040, 0x003EE5, 0x000020, 0x000040,
-	0x002DE5, 0x400152, 0x50000A, 0x045144,
-	0x364A86, 0x0000C5, 0x003EE5, 0x004020,
-	0x000040, 0x002BE5, 0x000042, 0x40000A,
-	0x404254, 0x000007, 0x002AE5, 0x004020,
-	0x000040, 0x500132, 0x040134, 0x005674,
-	0x0029E5, 0x020042, 0x42000A, 0x000042,
-	0x50000A, 0x05417C, 0x0028E5, 0x000042,
-	0x48000A, 0x0000C5, 0x4CC144, 0x371086,
-	0x0026E5, 0x0027E5, 0x020042, 0x40004A,
-	0x50000A, 0x00423C, 0x00567C, 0x0028E5,
-	0x004820, 0x000040, 0x281D12, 0x282512,
-	0x001F72, 0x002965, 0x000042, 0x40000A,
-	0x004104, 0x37AA86, 0x0E0007, 0x160007,
-	0x1E0007, 0x003EE5, 0x000042, 0x40000A,
-	0x004104, 0x37E886, 0x002D65, 0x000042,
-	0x28340A, 0x003465, 0x020042, 0x42004A,
-	0x004020, 0x4A004A, 0x50004A, 0x05D2F4,
-	0x54D104, 0x00735C, 0x385186, 0x000007,
-	0x000606, 0x080007, 0x0C0007, 0x080007,
-	0x0A0007, 0x0001E5, 0x020045, 0x004020,
-	0x000060, 0x000365, 0x000040, 0x002E65,
-	0x001A20, 0x0A1A60, 0x000040, 0x003465,
-	0x020042, 0x42004A, 0x004020, 0x4A004A,
-	0x000606, 0x50004A, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000
-};
-
-// --------------------------------------------
-//  DS-1E Controller InstructionRAM Code
-//	1999/06/21
-//	Buf441 slot is Enabled.
-// --------------------------------------------
-// 04/09  creat
-// 04/12  stop nise fix
-// 06/21  WorkingOff timming
-static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = {
-	0x000007, 0x240007, 0x0C0007, 0x1C0007,
-	0x060007, 0x700002, 0x000020, 0x030040,
-	0x007104, 0x004286, 0x030040, 0x000F0D,
-	0x000810, 0x20043A, 0x000282, 0x00020D,
-	0x000810, 0x20043A, 0x001282, 0x200E82,
-	0x00800D, 0x000810, 0x20043A, 0x001A82,
-	0x03460D, 0x000810, 0x10043A, 0x02EC0D,
-	0x000810, 0x18043A, 0x00010D, 0x020015,
-	0x0000FD, 0x000020, 0x038860, 0x039060,
-	0x038060, 0x038040, 0x038040, 0x038040,
-	0x018040, 0x000A7D, 0x038040, 0x038040,
-	0x018040, 0x200402, 0x000882, 0x08001A,
-	0x000904, 0x017186, 0x000007, 0x260007,
-	0x400007, 0x000007, 0x03258D, 0x000810,
-	0x18043A, 0x260007, 0x284402, 0x00087D,
-	0x018042, 0x00160A, 0x05A206, 0x000007,
-	0x440007, 0x00230D, 0x000810, 0x08043A,
-	0x22FA06, 0x000007, 0x0007FD, 0x018042,
-	0x08000A, 0x000904, 0x02AB86, 0x000195,
-	0x090D04, 0x000007, 0x000820, 0x0000F5,
-	0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
-	0x018040, 0x000A7D, 0x038042, 0x13804A,
-	0x18000A, 0x001820, 0x059060, 0x058860,
-	0x018040, 0x0000FD, 0x018042, 0x70000A,
-	0x000115, 0x071144, 0x033B86, 0x030000,
-	0x007020, 0x036206, 0x018040, 0x00360D,
-	0x000810, 0x08043A, 0x232206, 0x000007,
-	0x02EC0D, 0x000810, 0x18043A, 0x019A06,
-	0x000007, 0x240007, 0x000F8D, 0x000810,
-	0x00163A, 0x002402, 0x005C02, 0x0028FD,
-	0x000020, 0x018040, 0x08000D, 0x000815,
-	0x510984, 0x000007, 0x00004D, 0x000E5D,
-	0x000E02, 0x00430D, 0x000810, 0x08043A,
-	0x2E1206, 0x000007, 0x00008D, 0x000924,
-	0x000F02, 0x00470D, 0x000810, 0x08043A,
-	0x2E1206, 0x000007, 0x480480, 0x001210,
-	0x28043A, 0x00778D, 0x000810, 0x280C3A,
-	0x00068D, 0x000810, 0x28143A, 0x284402,
-	0x03258D, 0x000810, 0x18043A, 0x07FF8D,
-	0x000820, 0x0002FD, 0x018040, 0x260007,
-	0x200007, 0x0002FD, 0x018042, 0x08000A,
-	0x000904, 0x051286, 0x000007, 0x240007,
-	0x02EC0D, 0x000810, 0x18043A, 0x00387D,
-	0x018042, 0x08000A, 0x001015, 0x010984,
-	0x019B86, 0x000007, 0x01B206, 0x000007,
-	0x0008FD, 0x018042, 0x18000A, 0x001904,
-	0x22B886, 0x280007, 0x001810, 0x28043A,
-	0x280C02, 0x00000D, 0x000810, 0x28143A,
-	0x08808D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00020D, 0x189904, 0x000007,
-	0x00402D, 0x0000BD, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x065A86, 0x000007,
-	0x000100, 0x000A20, 0x00047D, 0x018040,
-	0x018042, 0x20000A, 0x003015, 0x012144,
-	0x036186, 0x000007, 0x002104, 0x036186,
-	0x000007, 0x000F8D, 0x000810, 0x280C3A,
-	0x023944, 0x07C986, 0x000007, 0x001810,
-	0x28043A, 0x08810D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x002810, 0x78003A,
-	0x00788D, 0x000810, 0x08043A, 0x2A1206,
-	0x000007, 0x00400D, 0x001015, 0x189904,
-	0x292904, 0x393904, 0x000007, 0x070206,
-	0x000007, 0x0004F5, 0x00007D, 0x000020,
-	0x00008D, 0x010860, 0x018040, 0x00047D,
-	0x038042, 0x21804A, 0x18000A, 0x021944,
-	0x229086, 0x000007, 0x004075, 0x71F104,
-	0x000007, 0x010042, 0x28000A, 0x002904,
-	0x225886, 0x000007, 0x003C0D, 0x30A904,
-	0x000007, 0x00077D, 0x018042, 0x08000A,
-	0x000904, 0x08DA86, 0x00057D, 0x002820,
-	0x03B060, 0x08F206, 0x018040, 0x003020,
-	0x03A860, 0x018040, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x08FA86, 0x000007,
-	0x00057D, 0x018042, 0x28040A, 0x000E8D,
-	0x000810, 0x280C3A, 0x00000D, 0x000810,
-	0x28143A, 0x09000D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x003DFD, 0x000020,
-	0x018040, 0x00107D, 0x009D8D, 0x000810,
-	0x08043A, 0x2A1206, 0x000007, 0x000815,
-	0x08001A, 0x010984, 0x0A5186, 0x00137D,
-	0x200500, 0x280F20, 0x338F60, 0x3B8F60,
-	0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-	0x038A60, 0x018040, 0x00107D, 0x018042,
-	0x08000A, 0x000215, 0x010984, 0x3A8186,
-	0x000007, 0x007FBD, 0x383DC4, 0x000007,
-	0x001A7D, 0x001375, 0x018042, 0x09004A,
-	0x10000A, 0x0B8D04, 0x139504, 0x000007,
-	0x000820, 0x019060, 0x001104, 0x225886,
-	0x010040, 0x0017FD, 0x018042, 0x08000A,
-	0x000904, 0x225A86, 0x000007, 0x00197D,
-	0x038042, 0x09804A, 0x10000A, 0x000924,
-	0x001664, 0x0011FD, 0x038042, 0x2B804A,
-	0x19804A, 0x00008D, 0x218944, 0x000007,
-	0x002244, 0x0C1986, 0x000007, 0x001A64,
-	0x002A24, 0x00197D, 0x080102, 0x100122,
-	0x000820, 0x039060, 0x018040, 0x003DFD,
-	0x00008D, 0x000820, 0x018040, 0x001375,
-	0x001A7D, 0x010042, 0x09804A, 0x10000A,
-	0x00021D, 0x0189E4, 0x2992E4, 0x309144,
-	0x000007, 0x00060D, 0x000A15, 0x000C1D,
-	0x001025, 0x00A9E4, 0x012BE4, 0x000464,
-	0x01B3E4, 0x0232E4, 0x000464, 0x000464,
-	0x000464, 0x000464, 0x00040D, 0x08B1C4,
-	0x000007, 0x000820, 0x000BF5, 0x030040,
-	0x00197D, 0x038042, 0x09804A, 0x000A24,
-	0x08000A, 0x080E64, 0x000007, 0x100122,
-	0x000820, 0x031060, 0x010040, 0x0064AC,
-	0x00027D, 0x000020, 0x018040, 0x00107D,
-	0x018042, 0x0011FD, 0x3B804A, 0x09804A,
-	0x20000A, 0x000095, 0x1A1144, 0x00A144,
-	0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
-	0x0018FD, 0x018042, 0x0010FD, 0x09804A,
-	0x28000A, 0x000095, 0x010924, 0x002A64,
-	0x0E4986, 0x000007, 0x002904, 0x0E5A86,
-	0x000007, 0x0E6206, 0x080002, 0x00008D,
-	0x00387D, 0x000820, 0x018040, 0x00127D,
-	0x018042, 0x10000A, 0x003904, 0x0F0986,
-	0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
-	0x000025, 0x0FB206, 0x00002D, 0x000015,
-	0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
-	0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
-	0x400025, 0x00008D, 0x110944, 0x000007,
-	0x00018D, 0x109504, 0x000007, 0x009164,
-	0x000424, 0x000424, 0x000424, 0x100102,
-	0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
-	0x00018D, 0x00042D, 0x00008D, 0x109504,
-	0x000007, 0x00020D, 0x109184, 0x000007,
-	0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
-	0x018040, 0x003BFD, 0x001020, 0x03A860,
-	0x000815, 0x313184, 0x212184, 0x000007,
-	0x03B060, 0x03A060, 0x018040, 0x0022FD,
-	0x000095, 0x010924, 0x000424, 0x000424,
-	0x001264, 0x100102, 0x000820, 0x039060,
-	0x018040, 0x001924, 0x010F0D, 0x00397D,
-	0x000820, 0x058040, 0x038042, 0x09844A,
-	0x000606, 0x08040A, 0x000424, 0x000424,
-	0x00117D, 0x018042, 0x08000A, 0x000A24,
-	0x280502, 0x280C02, 0x09800D, 0x000820,
-	0x0002FD, 0x018040, 0x200007, 0x0022FD,
-	0x018042, 0x08000A, 0x000095, 0x280DC4,
-	0x011924, 0x00197D, 0x018042, 0x0011FD,
-	0x09804A, 0x10000A, 0x0000B5, 0x113144,
-	0x0A8D04, 0x000007, 0x080A44, 0x129504,
-	0x000007, 0x0023FD, 0x001020, 0x038040,
-	0x101244, 0x000007, 0x000820, 0x039060,
-	0x018040, 0x0002FD, 0x018042, 0x08000A,
-	0x000904, 0x123286, 0x000007, 0x003BFD,
-	0x000100, 0x000A10, 0x0B807A, 0x13804A,
-	0x090984, 0x000007, 0x000095, 0x013D04,
-	0x12B886, 0x10000A, 0x100002, 0x090984,
-	0x000007, 0x038042, 0x11804A, 0x090D04,
-	0x000007, 0x10000A, 0x090D84, 0x000007,
-	0x00257D, 0x000820, 0x018040, 0x00010D,
-	0x000810, 0x28143A, 0x00127D, 0x018042,
-	0x20000A, 0x00197D, 0x018042, 0x00117D,
-	0x31804A, 0x10000A, 0x003124, 0x013B8D,
-	0x00397D, 0x000820, 0x058040, 0x038042,
-	0x09844A, 0x000606, 0x08040A, 0x300102,
-	0x003124, 0x000424, 0x000424, 0x001224,
-	0x280502, 0x001A4C, 0x143986, 0x700002,
-	0x00002D, 0x030000, 0x00387D, 0x018042,
-	0x10000A, 0x146206, 0x002124, 0x0000AD,
-	0x100002, 0x00010D, 0x000924, 0x006B24,
-	0x014A0D, 0x00397D, 0x000820, 0x058040,
-	0x038042, 0x09844A, 0x000606, 0x08040A,
-	0x003264, 0x00008D, 0x000A24, 0x001020,
-	0x00227D, 0x018040, 0x014F8D, 0x000810,
-	0x08043A, 0x2B5A06, 0x000007, 0x002820,
-	0x00207D, 0x018040, 0x00117D, 0x038042,
-	0x13804A, 0x33800A, 0x00387D, 0x018042,
-	0x08000A, 0x000904, 0x177286, 0x000007,
-	0x00008D, 0x030964, 0x015B0D, 0x00397D,
-	0x000820, 0x058040, 0x038042, 0x09844A,
-	0x000606, 0x08040A, 0x380102, 0x000424,
-	0x000424, 0x001224, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x15DA86, 0x000007,
-	0x280502, 0x001A4C, 0x177186, 0x000007,
-	0x032164, 0x00632C, 0x003DFD, 0x018042,
-	0x08000A, 0x000095, 0x090904, 0x000007,
-	0x000820, 0x001A4C, 0x169986, 0x018040,
-	0x030000, 0x16B206, 0x002124, 0x00010D,
-	0x000924, 0x006B24, 0x016F0D, 0x00397D,
-	0x000820, 0x058040, 0x038042, 0x09844A,
-	0x000606, 0x08040A, 0x003A64, 0x000095,
-	0x001224, 0x0002FD, 0x018042, 0x08000A,
-	0x000904, 0x171286, 0x000007, 0x01760D,
-	0x000810, 0x08043A, 0x2B5A06, 0x000007,
-	0x160A06, 0x000007, 0x007020, 0x08010A,
-	0x10012A, 0x0020FD, 0x038860, 0x039060,
-	0x018040, 0x00227D, 0x018042, 0x003DFD,
-	0x08000A, 0x31844A, 0x000904, 0x181086,
-	0x18008B, 0x00008D, 0x189904, 0x00312C,
-	0x18E206, 0x000007, 0x00324C, 0x186B86,
-	0x000007, 0x001904, 0x186886, 0x000007,
-	0x000095, 0x199144, 0x00222C, 0x003124,
-	0x00636C, 0x000E3D, 0x001375, 0x000BFD,
-	0x010042, 0x09804A, 0x10000A, 0x038AEC,
-	0x0393EC, 0x00224C, 0x18E186, 0x000007,
-	0x00008D, 0x189904, 0x00226C, 0x00322C,
-	0x30050A, 0x301DAB, 0x002083, 0x0018FD,
-	0x018042, 0x08000A, 0x018924, 0x300502,
-	0x001083, 0x001875, 0x010042, 0x10000A,
-	0x00008D, 0x010924, 0x001375, 0x330542,
-	0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
-	0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
-	0x006083, 0x0002F5, 0x010042, 0x08000A,
-	0x000904, 0x19B286, 0x000007, 0x001E2D,
-	0x0005FD, 0x018042, 0x08000A, 0x028924,
-	0x280502, 0x00060D, 0x000810, 0x280C3A,
-	0x00008D, 0x000810, 0x28143A, 0x0A808D,
-	0x000820, 0x0002F5, 0x010040, 0x220007,
-	0x001275, 0x030042, 0x21004A, 0x00008D,
-	0x1A0944, 0x000007, 0x01AB8D, 0x000810,
-	0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
-	0x030042, 0x0D004A, 0x10000A, 0x089144,
-	0x000007, 0x000820, 0x010040, 0x0025F5,
-	0x0A3144, 0x000007, 0x000820, 0x032860,
-	0x030040, 0x00217D, 0x038042, 0x0B804A,
-	0x10000A, 0x000820, 0x031060, 0x030040,
-	0x00008D, 0x000124, 0x00012C, 0x000E64,
-	0x001A64, 0x00636C, 0x08010A, 0x10012A,
-	0x000820, 0x031060, 0x030040, 0x0020FD,
-	0x018042, 0x08000A, 0x00227D, 0x018042,
-	0x10000A, 0x000820, 0x031060, 0x030040,
-	0x00197D, 0x018042, 0x08000A, 0x0022FD,
-	0x038042, 0x10000A, 0x000820, 0x031060,
-	0x030040, 0x090D04, 0x000007, 0x000820,
-	0x030040, 0x038042, 0x0B804A, 0x10000A,
-	0x000820, 0x031060, 0x030040, 0x038042,
-	0x13804A, 0x19804A, 0x110D04, 0x198D04,
-	0x000007, 0x08000A, 0x001020, 0x031860,
-	0x030860, 0x030040, 0x00008D, 0x0B0944,
-	0x000007, 0x000820, 0x010040, 0x0005F5,
-	0x030042, 0x08000A, 0x000820, 0x010040,
-	0x0000F5, 0x010042, 0x08000A, 0x000904,
-	0x1D9886, 0x001E75, 0x030042, 0x01044A,
-	0x000C0A, 0x1DAA06, 0x000007, 0x000402,
-	0x000C02, 0x00177D, 0x001AF5, 0x018042,
-	0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
-	0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
-	0x00043D, 0x0013F5, 0x001AFD, 0x030042,
-	0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
-	0x089144, 0x19A144, 0x0389E4, 0x0399EC,
-	0x005502, 0x005D0A, 0x030042, 0x0B004A,
-	0x1B804A, 0x13804A, 0x20000A, 0x089144,
-	0x19A144, 0x0389E4, 0x0399EC, 0x006502,
-	0x006D0A, 0x030042, 0x0B004A, 0x19004A,
-	0x2B804A, 0x13804A, 0x21804A, 0x30000A,
-	0x089144, 0x19A144, 0x2AB144, 0x0389E4,
-	0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
-	0x000702, 0x00107D, 0x000415, 0x018042,
-	0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
-	0x0019FD, 0x010042, 0x09804A, 0x10000A,
-	0x000934, 0x001674, 0x0029F5, 0x010042,
-	0x10000A, 0x00917C, 0x002075, 0x010042,
-	0x08000A, 0x000904, 0x200A86, 0x0026F5,
-	0x0027F5, 0x030042, 0x09004A, 0x10000A,
-	0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
-	0x010042, 0x51804A, 0x48000A, 0x160007,
-	0x001075, 0x010042, 0x282C0A, 0x281D12,
-	0x282512, 0x001F32, 0x1E0007, 0x0E0007,
-	0x001975, 0x010042, 0x002DF5, 0x0D004A,
-	0x10000A, 0x009144, 0x20EA86, 0x010042,
-	0x28340A, 0x000E5D, 0x00008D, 0x000375,
-	0x000820, 0x010040, 0x05D2F4, 0x54D104,
-	0x00735C, 0x218B86, 0x000007, 0x0C0007,
-	0x080007, 0x0A0007, 0x02178D, 0x000810,
-	0x08043A, 0x34B206, 0x000007, 0x219206,
-	0x000007, 0x080007, 0x002275, 0x010042,
-	0x20000A, 0x002104, 0x225886, 0x001E2D,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x21CA86, 0x000007, 0x002010, 0x30043A,
-	0x00057D, 0x0180C3, 0x08000A, 0x028924,
-	0x280502, 0x280C02, 0x0A810D, 0x000820,
-	0x0002F5, 0x010040, 0x220007, 0x0004FD,
-	0x018042, 0x70000A, 0x030000, 0x007020,
-	0x07FA06, 0x018040, 0x022B8D, 0x000810,
-	0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
-	0x018042, 0x08000A, 0x000904, 0x22C286,
-	0x000007, 0x020206, 0x000007, 0x000875,
-	0x0009FD, 0x00010D, 0x234206, 0x000295,
-	0x000B75, 0x00097D, 0x00000D, 0x000515,
-	0x010042, 0x18000A, 0x001904, 0x2A0086,
-	0x0006F5, 0x001020, 0x010040, 0x0004F5,
-	0x000820, 0x010040, 0x000775, 0x010042,
-	0x09804A, 0x10000A, 0x001124, 0x000904,
-	0x23F286, 0x000815, 0x080102, 0x101204,
-	0x241206, 0x000575, 0x081204, 0x000007,
-	0x100102, 0x000575, 0x000425, 0x021124,
-	0x100102, 0x000820, 0x031060, 0x010040,
-	0x001924, 0x2A0086, 0x00008D, 0x000464,
-	0x009D04, 0x291086, 0x180102, 0x000575,
-	0x010042, 0x28040A, 0x00018D, 0x000924,
-	0x280D02, 0x00000D, 0x000924, 0x281502,
-	0x10000D, 0x000820, 0x0002F5, 0x010040,
-	0x200007, 0x001175, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x24FA86, 0x000007,
-	0x000100, 0x080B20, 0x130B60, 0x1B0B60,
-	0x030A60, 0x010040, 0x050042, 0x3D004A,
-	0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
-	0x010042, 0x28140A, 0x0004F5, 0x010042,
-	0x08000A, 0x000315, 0x010D04, 0x260286,
-	0x004015, 0x000095, 0x010D04, 0x25F086,
-	0x100022, 0x10002A, 0x261A06, 0x000007,
-	0x333104, 0x2AA904, 0x000007, 0x032124,
-	0x280502, 0x284402, 0x001124, 0x400102,
-	0x000424, 0x000424, 0x003224, 0x00292C,
-	0x00636C, 0x277386, 0x000007, 0x02B164,
-	0x000464, 0x000464, 0x00008D, 0x000A64,
-	0x280D02, 0x10008D, 0x000820, 0x0002F5,
-	0x010040, 0x220007, 0x00008D, 0x38B904,
-	0x000007, 0x03296C, 0x30010A, 0x0002F5,
-	0x010042, 0x08000A, 0x000904, 0x270286,
-	0x000007, 0x00212C, 0x28050A, 0x00316C,
-	0x00046C, 0x00046C, 0x28450A, 0x001124,
-	0x006B64, 0x100102, 0x00008D, 0x01096C,
-	0x280D0A, 0x10010D, 0x000820, 0x0002F5,
-	0x010040, 0x220007, 0x004124, 0x000424,
-	0x000424, 0x003224, 0x300102, 0x032944,
-	0x27FA86, 0x000007, 0x300002, 0x0004F5,
-	0x010042, 0x08000A, 0x000315, 0x010D04,
-	0x284086, 0x003124, 0x000464, 0x300102,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x284A86, 0x000007, 0x284402, 0x003124,
-	0x300502, 0x003924, 0x300583, 0x000883,
-	0x0005F5, 0x010042, 0x28040A, 0x00008D,
-	0x008124, 0x280D02, 0x00008D, 0x008124,
-	0x281502, 0x10018D, 0x000820, 0x0002F5,
-	0x010040, 0x220007, 0x001025, 0x000575,
-	0x030042, 0x09004A, 0x10000A, 0x0A0904,
-	0x121104, 0x000007, 0x001020, 0x050860,
-	0x050040, 0x0006FD, 0x018042, 0x09004A,
-	0x10000A, 0x0000A5, 0x0A0904, 0x121104,
-	0x000007, 0x000820, 0x019060, 0x010040,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x29CA86, 0x000007, 0x244206, 0x000007,
-	0x000606, 0x000007, 0x0002F5, 0x010042,
-	0x08000A, 0x000904, 0x2A1A86, 0x000007,
-	0x000100, 0x080B20, 0x138B60, 0x1B8B60,
-	0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
-	0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
-	0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
-	0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
-	0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
-	0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-	0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
-	0x038A60, 0x000606, 0x018040, 0x00008D,
-	0x000A64, 0x280D02, 0x000A24, 0x00027D,
-	0x018042, 0x10000A, 0x001224, 0x0003FD,
-	0x018042, 0x08000A, 0x000904, 0x2C0A86,
-	0x000007, 0x00018D, 0x000A24, 0x000464,
-	0x000464, 0x080102, 0x000924, 0x000424,
-	0x000424, 0x100102, 0x02000D, 0x009144,
-	0x2C6186, 0x000007, 0x0001FD, 0x018042,
-	0x08000A, 0x000A44, 0x2C4386, 0x018042,
-	0x0A000D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00027D, 0x001020, 0x000606,
-	0x018040, 0x0002F5, 0x010042, 0x08000A,
-	0x000904, 0x2CB286, 0x000007, 0x00037D,
-	0x018042, 0x08000A, 0x000904, 0x2CE286,
-	0x000007, 0x000075, 0x002E7D, 0x010042,
-	0x0B804A, 0x000020, 0x000904, 0x000686,
-	0x010040, 0x31844A, 0x30048B, 0x000883,
-	0x00008D, 0x000810, 0x28143A, 0x00008D,
-	0x000810, 0x280C3A, 0x000675, 0x010042,
-	0x08000A, 0x003815, 0x010924, 0x280502,
-	0x0B000D, 0x000820, 0x0002F5, 0x010040,
-	0x000606, 0x220007, 0x000464, 0x000464,
-	0x000606, 0x000007, 0x000134, 0x007F8D,
-	0x00093C, 0x281D12, 0x282512, 0x001F32,
-	0x0E0007, 0x00010D, 0x00037D, 0x000820,
-	0x018040, 0x05D2F4, 0x000007, 0x080007,
-	0x00037D, 0x018042, 0x08000A, 0x000904,
-	0x2E8A86, 0x000007, 0x000606, 0x000007,
-	0x000007, 0x000012, 0x100007, 0x320007,
-	0x600007, 0x460007, 0x100080, 0x48001A,
-	0x004904, 0x2EF186, 0x000007, 0x001210,
-	0x58003A, 0x000145, 0x5C5D04, 0x000007,
-	0x000080, 0x48001A, 0x004904, 0x2F4186,
-	0x000007, 0x001210, 0x50003A, 0x005904,
-	0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
-	0x7FFF7D, 0x07D524, 0x004224, 0x500102,
-	0x200502, 0x000082, 0x40001A, 0x004104,
-	0x2FC986, 0x000007, 0x003865, 0x40001A,
-	0x004020, 0x00104D, 0x04C184, 0x31AB86,
-	0x000040, 0x040007, 0x000165, 0x000145,
-	0x004020, 0x000040, 0x000765, 0x080080,
-	0x40001A, 0x004104, 0x305986, 0x000007,
-	0x001210, 0x40003A, 0x004104, 0x30B286,
-	0x00004D, 0x0000CD, 0x004810, 0x20043A,
-	0x000882, 0x40001A, 0x004104, 0x30C186,
-	0x000007, 0x004820, 0x005904, 0x319886,
-	0x000040, 0x0007E5, 0x200480, 0x2816A0,
-	0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
-	0x000040, 0x000032, 0x400075, 0x00007D,
-	0x07D574, 0x200512, 0x000082, 0x40001A,
-	0x004104, 0x317186, 0x000007, 0x038A06,
-	0x640007, 0x0000E5, 0x000020, 0x000040,
-	0x000A65, 0x000020, 0x020040, 0x020040,
-	0x000040, 0x000165, 0x000042, 0x70000A,
-	0x007104, 0x323286, 0x000007, 0x060007,
-	0x019A06, 0x640007, 0x050000, 0x007020,
-	0x000040, 0x038A06, 0x640007, 0x000007,
-	0x00306D, 0x028860, 0x029060, 0x08000A,
-	0x028860, 0x008040, 0x100012, 0x00100D,
-	0x009184, 0x32D186, 0x000E0D, 0x009184,
-	0x33E186, 0x000007, 0x300007, 0x001020,
-	0x003B6D, 0x008040, 0x000080, 0x08001A,
-	0x000904, 0x32F186, 0x000007, 0x001220,
-	0x000DED, 0x008040, 0x008042, 0x10000A,
-	0x40000D, 0x109544, 0x000007, 0x001020,
-	0x000DED, 0x008040, 0x008042, 0x20040A,
-	0x000082, 0x08001A, 0x000904, 0x338186,
-	0x000007, 0x003B6D, 0x008042, 0x08000A,
-	0x000E15, 0x010984, 0x342B86, 0x600007,
-	0x08001A, 0x000C15, 0x010984, 0x341386,
-	0x000020, 0x1A0007, 0x0002ED, 0x008040,
-	0x620007, 0x00306D, 0x028042, 0x0A804A,
-	0x000820, 0x0A804A, 0x000606, 0x10804A,
-	0x000007, 0x282512, 0x001F32, 0x05D2F4,
-	0x54D104, 0x00735C, 0x000786, 0x000007,
-	0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
-	0x020040, 0x004820, 0x025060, 0x40000A,
-	0x024060, 0x000040, 0x454944, 0x000007,
-	0x004020, 0x003AE5, 0x000040, 0x0028E5,
-	0x000042, 0x48000A, 0x004904, 0x39F886,
-	0x002C65, 0x000042, 0x40000A, 0x0000D5,
-	0x454104, 0x000007, 0x000655, 0x054504,
-	0x368286, 0x0001D5, 0x054504, 0x368086,
-	0x002B65, 0x000042, 0x003AE5, 0x50004A,
-	0x40000A, 0x45C3D4, 0x000007, 0x454504,
-	0x000007, 0x0000CD, 0x444944, 0x000007,
-	0x454504, 0x000007, 0x00014D, 0x554944,
-	0x000007, 0x045144, 0x367986, 0x002C65,
-	0x000042, 0x48000A, 0x4CD104, 0x000007,
-	0x04C144, 0x368386, 0x000007, 0x160007,
-	0x002CE5, 0x040042, 0x40000A, 0x004020,
-	0x000040, 0x002965, 0x000042, 0x40000A,
-	0x004104, 0x36F086, 0x000007, 0x002402,
-	0x383206, 0x005C02, 0x0025E5, 0x000042,
-	0x40000A, 0x004274, 0x002AE5, 0x000042,
-	0x40000A, 0x004274, 0x500112, 0x0029E5,
-	0x000042, 0x40000A, 0x004234, 0x454104,
-	0x000007, 0x004020, 0x000040, 0x003EE5,
-	0x000020, 0x000040, 0x002DE5, 0x400152,
-	0x50000A, 0x045144, 0x37DA86, 0x0000C5,
-	0x003EE5, 0x004020, 0x000040, 0x002BE5,
-	0x000042, 0x40000A, 0x404254, 0x000007,
-	0x002AE5, 0x004020, 0x000040, 0x500132,
-	0x040134, 0x005674, 0x0029E5, 0x020042,
-	0x42000A, 0x000042, 0x50000A, 0x05417C,
-	0x0028E5, 0x000042, 0x48000A, 0x0000C5,
-	0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
-	0x020042, 0x40004A, 0x50000A, 0x00423C,
-	0x00567C, 0x0028E5, 0x004820, 0x000040,
-	0x281D12, 0x282512, 0x001F72, 0x002965,
-	0x000042, 0x40000A, 0x004104, 0x393A86,
-	0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
-	0x000042, 0x40000A, 0x004104, 0x397886,
-	0x002D65, 0x000042, 0x28340A, 0x003465,
-	0x020042, 0x42004A, 0x004020, 0x4A004A,
-	0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
-	0x39E186, 0x000007, 0x000606, 0x080007,
-	0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
-	0x020045, 0x004020, 0x000060, 0x000365,
-	0x000040, 0x002E65, 0x001A20, 0x0A1A60,
-	0x000040, 0x003465, 0x020042, 0x42004A,
-	0x004020, 0x4A004A, 0x000606, 0x50004A,
-	0x0017FD, 0x018042, 0x08000A, 0x000904,
-	0x225A86, 0x000007, 0x00107D, 0x018042,
-	0x0011FD, 0x33804A, 0x19804A, 0x20000A,
-	0x000095, 0x2A1144, 0x01A144, 0x3B9086,
-	0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
-	0x018042, 0x0010FD, 0x09804A, 0x38000A,
-	0x000095, 0x010924, 0x003A64, 0x3B8186,
-	0x000007, 0x003904, 0x3B9286, 0x000007,
-	0x3B9A06, 0x00000D, 0x00008D, 0x000820,
-	0x00387D, 0x018040, 0x700002, 0x00117D,
-	0x018042, 0x00197D, 0x29804A, 0x30000A,
-	0x380002, 0x003124, 0x000424, 0x000424,
-	0x002A24, 0x280502, 0x00068D, 0x000810,
-	0x28143A, 0x00750D, 0x00B124, 0x002264,
-	0x3D0386, 0x284402, 0x000810, 0x280C3A,
-	0x0B800D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00758D, 0x00B124, 0x100102,
-	0x012144, 0x3E4986, 0x001810, 0x10003A,
-	0x00387D, 0x018042, 0x08000A, 0x000904,
-	0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
-	0x00008D, 0x023164, 0x000A64, 0x280D02,
-	0x0B808D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00387D, 0x018042, 0x08000A,
-	0x000904, 0x3E3286, 0x030000, 0x0002FD,
-	0x018042, 0x08000A, 0x000904, 0x3D8286,
-	0x000007, 0x002810, 0x28043A, 0x00750D,
-	0x030924, 0x002264, 0x280D02, 0x02316C,
-	0x28450A, 0x0B810D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x00008D, 0x000A24,
-	0x3E4A06, 0x100102, 0x001810, 0x10003A,
-	0x0000BD, 0x003810, 0x30043A, 0x00187D,
-	0x018042, 0x0018FD, 0x09804A, 0x20000A,
-	0x0000AD, 0x028924, 0x07212C, 0x001010,
-	0x300583, 0x300D8B, 0x3014BB, 0x301C83,
-	0x002083, 0x00137D, 0x038042, 0x33844A,
-	0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
-	0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
-	0x001E0D, 0x0005FD, 0x018042, 0x20000A,
-	0x020924, 0x00068D, 0x00A96C, 0x00009D,
-	0x0002FD, 0x018042, 0x08000A, 0x000904,
-	0x3F6A86, 0x000007, 0x280502, 0x280D0A,
-	0x284402, 0x001810, 0x28143A, 0x0C008D,
-	0x000820, 0x0002FD, 0x018040, 0x220007,
-	0x003904, 0x225886, 0x001E0D, 0x00057D,
-	0x018042, 0x20000A, 0x020924, 0x0000A5,
-	0x0002FD, 0x018042, 0x08000A, 0x000904,
-	0x402A86, 0x000007, 0x280502, 0x280C02,
-	0x002010, 0x28143A, 0x0C010D, 0x000820,
-	0x0002FD, 0x018040, 0x225A06, 0x220007,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000
-};
-
-#endif	//_HWMCODE_
diff --git a/sound/oss/yss225.c b/sound/oss/yss225.c
deleted file mode 100644
index e700400..0000000
--- a/sound/oss/yss225.c
+++ /dev/null
@@ -1,319 +0,0 @@
-#include <linux/init.h>
-
-unsigned char page_zero[] __initdata = {
-0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00,
-0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00,
-0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19,
-0x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01,
-0x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00,
-0x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02,
-0xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17,
-0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00,
-0x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02,
-0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40,
-0x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02,
-0x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-0x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00,
-0x1d, 0x02, 0xdf
-};    
-
-unsigned char page_one[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00,
-0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00,
-0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01,
-0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00,
-0x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7,
-0x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0,
-0x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00,
-0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0,
-0x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03,
-0xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00,
-0x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02,
-0x60, 0x00, 0x1b
-};
-
-unsigned char page_two[] __initdata = {
-0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4,
-0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07,
-0x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46,
-0x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46,
-0x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07,
-0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05,
-0x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05,
-0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44
-};
-
-unsigned char page_three[] __initdata = {
-0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
-0x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40,
-0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
-0x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00,
-0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40
-};
-
-unsigned char page_four[] __initdata = {
-0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
-0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00,
-0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60,
-0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00,
-0x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22,
-0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01
-};
-
-unsigned char page_six[] __initdata = {
-0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00,
-0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e,
-0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00,
-0x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00,
-0x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24,
-0x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00,
-0x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00,
-0x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a,
-0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00,
-0x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d,
-0x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50,
-0x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00,
-0x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17,
-0x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66,
-0x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c,
-0x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00,
-0x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c,
-0x80, 0x00, 0x7e, 0x80, 0x80
-};
-
-unsigned char page_seven[] __initdata = {
-0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f,
-0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff,
-0x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f,
-0xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38,
-0x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06,
-0x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b,
-0x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06,
-0xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55,
-0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14,
-0xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93,
-0x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x00
-};
-
-unsigned char page_zero_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_one_v2[] __initdata = {
-0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_two_v2[] __initdata = {
-0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-unsigned char page_three_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-unsigned char page_four_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_seven_v2[] __initdata = {
-0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-unsigned char mod_v2[] __initdata = {
-0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02,
-0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05,
-0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0,
-0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20,
-0xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3,
-0x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff,
-0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16,
-0xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff,
-0x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31,
-0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00,
-0x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44,
-0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00,
-0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57,
-0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00,
-0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72,
-0xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0,
-0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85,
-0x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00,
-0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0,
-0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00,
-0xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
-0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00,
-0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6,
-0x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00,
-0xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02,
-0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03,
-0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01,
-0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01
-};
-unsigned char coefficients[] __initdata = {
-0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03,
-0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49,
-0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01,
-0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00,
-0x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00,
-0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47,
-0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07,
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00,
-0x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01,
-0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43,
-0x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07,
-0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00,
-0x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02,
-0x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44,
-0x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07,
-0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40,
-0x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a,
-0x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56,
-0x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07,
-0x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda,
-0x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05,
-0x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79,
-0x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07,
-0x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52,
-0x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03,
-0x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a,
-0x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06,
-0x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3,
-0x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20,
-0x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c,
-0x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06,
-0x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48,
-0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02,
-0xba
-};
-unsigned char coefficients2[] __initdata = {
-0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f,
-0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d,
-0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07,
-0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00,
-0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00
-};
-unsigned char coefficients3[] __initdata = { 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00,
-0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc,
-0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01,
-0x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99,
-0x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02,
-0x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f,
-0x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03,
-0x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c,
-0x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03,
-0xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51,
-0x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04,
-0xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e,
-0x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05,
-0x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14,
-0x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06,
-0x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1,
-0x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07,
-0x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7,
-0x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08,
-0x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3,
-0x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09,
-0x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99,
-0x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a,
-0x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66,
-0x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a,
-0xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c,
-0x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b,
-0xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28,
-0x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c,
-0xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e,
-0x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d,
-0x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb,
-0x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e,
-0x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1,
-0x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f,
-0x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae,
-0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff
-};
-
diff --git a/sound/oss/yss225.h b/sound/oss/yss225.h
deleted file mode 100644
index 56d8b6b..0000000
--- a/sound/oss/yss225.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef __yss255_h__
-#define __yss255_h__
-
-extern unsigned char page_zero[256];
-extern unsigned char page_one[256];
-extern unsigned char page_two[128];
-extern unsigned char page_three[128];
-extern unsigned char page_four[128];
-extern unsigned char page_six[192];
-extern unsigned char page_seven[256];
-extern unsigned char page_zero_v2[96];
-extern unsigned char page_one_v2[96];
-extern unsigned char page_two_v2[48];
-extern unsigned char page_three_v2[48];
-extern unsigned char page_four_v2[48];
-extern unsigned char page_seven_v2[96];
-extern unsigned char mod_v2[304];
-extern unsigned char coefficients[364];
-extern unsigned char coefficients2[56];
-extern unsigned char coefficients3[404];
-
-
-#endif /* __ys225_h__ */
-
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 0b0a016..5322c50 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -366,25 +366,6 @@
 EXPORT_SYMBOL(register_sound_dsp);
 
 /**
- *	register_sound_synth - register a synth device
- *	@fops: File operations for the driver
- *	@dev: Unit number to allocate
- *
- *	Allocate a synth device. Unit is the number of the synth device requested.
- *	Pass -1 to request the next free synth unit. On success the allocated
- *	number is returned, on failure a negative error code is returned.
- */
-
-
-int register_sound_synth(const struct file_operations *fops, int dev)
-{
-	return sound_insert_unit(&chains[9], fops, dev, 9, 137,
-				 "synth", S_IRUSR | S_IWUSR, NULL);
-}
-
-EXPORT_SYMBOL(register_sound_synth);
-
-/**
  *	unregister_sound_special - unregister a special sound device
  *	@unit: unit number to allocate
  *
@@ -449,21 +430,6 @@
 
 EXPORT_SYMBOL(unregister_sound_dsp);
 
-/**
- *	unregister_sound_synth - unregister a synth device
- *	@unit: unit number to allocate
- *
- *	Release a sound device that was allocated with register_sound_synth().
- *	The unit passed is the return value from the register function.
- */
-
-void unregister_sound_synth(int unit)
-{
-	return sound_remove_unit(&chains[9], unit);
-}
-
-EXPORT_SYMBOL(unregister_sound_synth);
-
 /*
  *	Now our file operations
  */