Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (25 commits)
  [POWERPC] Add support for the mpc832x mds board
  [POWERPC] Add initial support for the e300c2 core
  [POWERPC] Add MPC8360EMDS default dts file
  [POWERPC] Add MPC8360EMDS board support
  [POWERPC] Add QUICC Engine (QE) infrastructure
  [POWERPC] Add QE device tree node definition
  [POWERPC] Don't try to just continue if xmon has no input device
  [POWERPC] Fix a printk in pseries_mpic_init_IRQ
  [POWERPC] Get default baud rate in udbg_scc
  [POWERPC] Fix zImage.coff on oldworld PowerMac
  [POWERPC] Fix xmon=off and cleanup xmon initialisation
  [POWERPC] Cleanup include/asm-powerpc/xmon.h
  [POWERPC] Update swim3 printk after blkdev.h change
  [POWERPC] Cell interrupt rework
  POWERPC: mpc82xx merge: board-specific/platform stuff(resend)
  POWERPC: 8272ads merge to powerpc: common stuff
  POWERPC: Added devicetree for mpc8272ads board
  [POWERPC] iSeries has no legacy I/O
  [POWERPC] implement BEGIN/END_FW_FTR_SECTION
  [POWERPC] iSeries does not need pcibios_fixup_resources
  ...
diff --git a/CREDITS b/CREDITS
index 6c06ded..5d75254 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
@@ -2009,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
@@ -2178,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
@@ -2234,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
@@ -2975,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.
@@ -3287,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/
@@ -3658,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 49c7457..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
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 9f08d73..0e3924e 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -468,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/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 2e410f5..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
@@ -184,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
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/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 c53b1c1..085eb15 100644
--- a/Documentation/input/ff.txt
+++ b/Documentation/input/ff.txt
@@ -38,7 +38,7 @@
 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()
 and write() on /dev/input/eventXX.
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/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/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 9ae9e40..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
@@ -175,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
@@ -214,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.
@@ -307,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.
@@ -330,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.
 
@@ -353,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,
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..badb7480 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 b57e7da..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.
 
 
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/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 1c6223d..8c35b3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -977,6 +977,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
@@ -1893,11 +1900,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
@@ -2434,6 +2436,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
@@ -2854,6 +2869,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
@@ -3377,12 +3397,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 dbe327d..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.
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/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/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/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-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index d781549..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
  *
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-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/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/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/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/i386/Kconfig b/arch/i386/Kconfig
index af219e5..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).
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 b2f24d5..d9f3e3c 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -669,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/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/smpboot.c b/arch/i386/kernel/smpboot.c
index 9d93ecf..4bb8b77 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -648,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/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/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 e5b1be5..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.
  *
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/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/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/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/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/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/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/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/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/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/kernel/entry.S b/arch/parisc/kernel/entry.S
index 95c1b8e..192357a 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -941,8 +941,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)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2587468..8b69104 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1013,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
@@ -1024,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.
 
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index c383d56..003520b 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -113,7 +113,7 @@
 endif
 
 quiet_cmd_wrap	= WRAP    $@
-      cmd_wrap	=$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux
+      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
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/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/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/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_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/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/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/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 d5d36c3..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
  *
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
index bf388ed..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
  *
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/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/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/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/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 bab7d3c..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
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/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/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/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/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-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/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/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/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/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/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 24747a4..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;
  */
 
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/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/x86_64/Kconfig b/arch/x86_64/Kconfig
index 0a5d8e6..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.   
 
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/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/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 d9285d4..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
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/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 8c75743..6d3e4c0 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -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/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/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/amiserial.c b/drivers/char/amiserial.c
index d0e92ed..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
 	 */
@@ -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 f85b4eb..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);
@@ -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 3baa2ab..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);
@@ -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/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/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/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/riscom8.c b/drivers/char/riscom8.c
index 214d8501..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);
@@ -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/serial167.c b/drivers/char/serial167.c
index b4ea126..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
      */
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index c91d9a6..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
  *
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c
index db477f7..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
  *
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/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/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/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/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/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/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/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index c62e00c..679bde3 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -177,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/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/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/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/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/md/md.c b/drivers/md/md.c
index 38a0a57..cb82816 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4438,8 +4438,7 @@
 {
  	mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
 
-	if (!mddev)
-		BUG();
+	BUG_ON(!mddev);
 	mddev_put(mddev);
 
 	return 0;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 37e4ff6..e14f457 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1105,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;
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/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 5c53fe6..afb734d 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -353,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/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/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/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 c1bf1fb..d65ece7 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -6,3 +6,5 @@
 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/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/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/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/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/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index 465961b..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"
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/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/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/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/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/parisc/power.c b/drivers/parisc/power.c
index 4a9f025..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>
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/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/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/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/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/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/Kconfig b/drivers/serial/Kconfig
index d926272..653098b 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.
@@ -667,7 +667,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_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.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
index a663300..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
  * 
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/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/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/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/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 a1c8923..daaa486 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -188,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.
 
@@ -403,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.
 
@@ -771,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
@@ -865,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
@@ -1062,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
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index b120896..a433cc7 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -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/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/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 1453d2d..674cfbb 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.
@@ -995,6 +995,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
@@ -1032,7 +1044,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.
@@ -1090,7 +1102,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/>).
@@ -1260,7 +1272,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
@@ -1365,7 +1377,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
@@ -1950,7 +1962,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 819b2a9..fd24d67 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -75,6 +75,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/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/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/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/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/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/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/lockd/clntlock.c b/fs/lockd/clntlock.c
index 87e1d03..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(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 0116729..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)
@@ -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 a816b92..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,8 +159,13 @@
 	 * 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))
+	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);
@@ -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 3cc369e..6341392 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -33,6 +33,7 @@
 #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
@@ -61,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.
@@ -395,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 }
 };
 
@@ -483,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 93c00ee..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);
 }
 
 /*
@@ -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/nfsd/export.c b/fs/nfsd/export.c
index cfe141e..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);
 }
 
@@ -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,30 +1152,21 @@
 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;
 }
 
@@ -1158,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;
@@ -1174,6 +1270,21 @@
 		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)
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/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 15ded7a..8333db1 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -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/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 5c6a477..39aed90 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -57,6 +57,7 @@
 	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
@@ -82,6 +83,7 @@
 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);
@@ -100,6 +102,7 @@
 	[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,
@@ -523,18 +526,20 @@
 		err = nfsd_create_serv();
 		if (!err) {
 			int proto = 0;
-			err = lockd_up(proto);
-			if (!err) {
-				err = svc_addsock(nfsd_serv, fd, buf, &proto);
-				if (err)
-					lockd_down();
+			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;
+		return err < 0 ? err : 0;
 	}
 	if (buf[0] == '-') {
 		char *toclose = kstrdup(buf+1, GFP_KERNEL);
@@ -545,12 +550,43 @@
 		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);
 
@@ -616,6 +652,7 @@
 		[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 1944305..6fa6340 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -198,9 +198,26 @@
 		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,
+	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)
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 443ebc5..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) {
@@ -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 b1317ad..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
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/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/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-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/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-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-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-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-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-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/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-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-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-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-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-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-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-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-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 65b9322..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.
  *
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/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-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/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/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/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-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-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-x86_64/cache.h b/include/asm-x86_64/cache.h
index ed8a9d25..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-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/linux/Kbuild b/include/linux/Kbuild
index f7a52e1..7d564b6 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -156,12 +156,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
@@ -333,6 +331,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/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/ipc.h b/include/linux/ipc.h
index d9e2b3f..636094c 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -2,7 +2,6 @@
 #define _LINUX_IPC_H
 
 #include <linux/types.h>
-#include <linux/kref.h>
 
 #define IPC_PRIVATE ((__kernel_key_t) 0)  
 
@@ -52,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 */
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/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/lockd/lockd.h b/include/linux/lockd/lockd.h
index 47b7dbd..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 */
 };
 
 /*
@@ -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/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/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/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 e1dbc86..d0d4aae 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -145,6 +145,7 @@
 void nfsd_reset_versions(void);
 int nfsd_create_serv(void);
 
+extern int nfsd_max_blksize;
 
 /* 
  * NFSv4 State
@@ -215,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)
@@ -291,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)
@@ -307,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/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/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/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/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_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/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/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/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/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/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 4ebcdf9..d6288e8 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -13,6 +13,7 @@
 #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>
@@ -95,8 +96,28 @@
  * 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.
@@ -170,7 +191,6 @@
 /*
  * 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 */
@@ -189,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 */
@@ -255,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;
@@ -347,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.
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 4c29615..98b21ad 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -54,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;
 };
 
 /*
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/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/utsname.h b/include/linux/utsname.h
index 02e4b69..a4555fe 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -1,11 +1,6 @@
 #ifndef _LINUX_UTSNAME_H
 #define _LINUX_UTSNAME_H
 
-#include <linux/sched.h>
-#include <linux/kref.h>
-#include <linux/nsproxy.h>
-#include <asm/atomic.h>
-
 #define __OLD_UTS_LEN 8
 
 struct oldold_utsname {
@@ -35,6 +30,13 @@
 	char domainname[65];
 };
 
+#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;
@@ -86,4 +88,7 @@
 }
 
 extern struct rw_semaphore uts_sem;
-#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_UTSNAME_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/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/ipc/mqueue.c b/ipc/mqueue.c
index c45ae86..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:
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/kernel/Makefile b/kernel/Makefile
index d948ca1..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 nsproxy.o
+	    hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
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..42f2f117 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/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/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/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/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 2314867..98489d8 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -153,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).
  */
 
 /**
@@ -401,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
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/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/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 ec4692359..f789500 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/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..d172a98 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.
 
@@ -526,7 +526,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 +556,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/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/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/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/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/svc.c b/net/sunrpc/svc.c
index a99e67b..c2c8bb2 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -417,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;
 }
 
@@ -438,14 +435,10 @@
 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]);
 }
 
 /*
@@ -651,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;
+			}
 		}
 	}
 
@@ -697,7 +699,7 @@
 	u32			dir, prog, vers, proc;
 	__be32			auth_stat, rpc_stat;
 	int			auth_res;
-	__be32			*accept_statp;
+	__be32			*reply_statp;
 
 	rpc_stat = rpc_success;
 
@@ -707,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;
@@ -738,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 */
 
@@ -886,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 */
@@ -926,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 40d41a2..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
 
@@ -375,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)
 {
@@ -384,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;
@@ -400,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 cba85d1..b39e7e2 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -313,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;
 
@@ -412,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;
@@ -437,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)
@@ -492,7 +494,12 @@
 	}
 	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);
@@ -703,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)
@@ -946,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",
@@ -1044,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);
@@ -1204,7 +1215,7 @@
 	struct svc_sock		*svsk =NULL;
 	struct svc_serv		*serv = rqstp->rq_server;
 	struct svc_pool		*pool = rqstp->rq_pool;
-	int			len;
+	int			len, i;
 	int 			pages;
 	struct xdr_buf		*arg;
 	DECLARE_WAITQUEUE(wait, current);
@@ -1221,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;
@@ -1604,6 +1610,8 @@
 			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);
@@ -1699,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;
 }
 
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/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/oss/Kconfig b/sound/oss/Kconfig
index f3b3530..cc2b9ab 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -643,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 8681179..2489bd6 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -15,71 +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_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)
@@ -87,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
@@ -118,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/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 3f32d467..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/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 858e1fe6..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
  */